appletrailers.lua: Fix script for website changes
[vlc.git] / share / lua / playlist / appletrailers.lua
1 --[[
2    Translate trailers.apple.com video webpages URLs to the corresponding
3    movie URL
4
5  $Id$
6  Copyright © 2007-2010 the VideoLAN team
7
8  This program is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 2 of the License, or
11  (at your option) any later version.
12
13  This program is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  GNU General Public License for more details.
17
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 --]]
22
23 -- Probe function
24 function probe()
25     return (vlc.access == "http" or vlc.access == "https")
26         and string.match( vlc.path, "^trailers%.apple%.com/trailers/.+/.+" )
27 end
28
29 function find( haystack, needle )
30     local _,_,r = string.find( haystack, needle )
31     return r
32 end
33
34 function parse_json(url)
35     vlc.msg.dbg("Trying to parse JSON from " .. url)
36     local json = require ("dkjson")
37
38     -- Use vlc.stream to grab a remote json file, place it in a string,
39     -- decode it and return the decoded data.
40     local stream = vlc.stream(url)
41     local string = ""
42     local line   = ""
43
44     if not stream then return false end
45
46     while true do
47         line = stream:readline()
48         if not line then break end
49
50         string = string .. line
51     end
52
53     return json.decode(string)
54 end
55
56 -- Parse function.
57 function parse()
58     local video_id = nil
59     local playlist = {}
60
61     while true do
62         line = vlc.readline()
63         if not line then break end
64
65         if string.match(line, "FilmId%s+=%s+'%d+'") then
66             video_id = find(line, "FilmId%s+=%s+'(%d+)'")
67             vlc.msg.dbg("Found FilmId " .. video_id)
68             break
69         end
70     end
71
72     -- Found a video id
73     if video_id ~= nil then
74         -- Lookup info from the json endpoint
75         local info = filmid_info(video_id)
76
77         -- Parse data
78         if info["clips"] == nil then
79             vlc.msg.err("Unexpected JSON response from Apple trailers")
80             return playlist
81         end
82
83         local movietitle = lookup_keys(info, "details/locale/en/movie_title")
84         local desc       = lookup_keys(info, "details/locale/en/synopsis")
85
86         for _, clip in ipairs(info["clips"]) do
87             local item          = {}
88
89             if clip["title"] == nil then
90                 item["name"] = movietitle
91             else
92                 item["name"] = movietitle .. " (" .. clip["title"] .. ")"
93             end
94             item["path"]        = get_preferred_src(clip)
95             item["artist"]      = clip["artist"]
96             item["arturl"]      = clip["thumb"]
97             item["description"] = desc
98             item["url"]         = vlc.path
99
100             table.insert(playlist, item)
101         end
102     else
103         vlc.msg.err("Couldn't extract trailer video URL")
104     end
105
106     return playlist
107 end
108
109 -- Request, parse and return the info for a FilmID
110 function filmid_info(id)
111     local film_url = "https://trailers.apple.com/trailers/feeds/data/" .. id .. ".json"
112     vlc.msg.dbg("Fetching FilmID info from " .. film_url)
113
114     return parse_json(film_url)
115 end
116
117 -- Get the user-preferred quality src
118 function get_preferred_src(clip)
119     local resolution = vlc.var.inherit(nil, "preferred-resolution")
120     if resolution == -1 then
121         return lookup_keys(clip, "versions/enus/sizes/hd1080/srcAlt")
122     end
123     if resolution >= 1080 then
124         return lookup_keys(clip, "versions/enus/sizes/hd1080/srcAlt")
125     end
126     if resolution >= 720 then
127         return lookup_keys(clip, "versions/enus/sizes/hd720/srcAlt")
128     end
129     return lookup_keys(clip, "versions/enus/sizes/sd/srcAlt")
130 end
131
132 -- Resolve a "path" in a table or return nil if any of
133 -- the keys are not found
134 function lookup_keys(table, path)
135     local value = table
136     for token in path:gmatch( "[^/]+" ) do
137         value = value[token]
138         if value == nil then
139             break
140         end
141     end
142     return value
143 end