--[[ Get information about a movie from IMDb Copyright © 2009-2010 VideoLAN and AUTHORS Authors: Jean-Philippe André (jpeg@videolan.org) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. --]] dlg = nil txt = nil function descriptor() return { title = "IMDb - The Internet Movie Database" ; version = "0.1" ; author = "Jean-Philippe André" ; url = 'http://www.imdb.org/'; shortdesc = "The Internet Movie Database"; description = "
The Internet Movie Database

" .. "Get information about movies from the Internet " .. "Movie Database (IMDb).
This Extension will show " .. "you the cast, a short plot summary and a link to " .. "the web page on imdb.org." ; capabilities = { "input-listener" } } end -- Update title text field. Removes file extensions. function update_title() local item = vlc.input.item() local title = item and item:name() if title ~= nil then title = string.gsub(title, "(.*)(%.%w+)$", "%1") end if title ~= nil then txt:set_text(title) end end function input_changed() update_title() end function create_dialog() dlg = vlc.dialog("IMDb Search") dlg:add_label("The Internet Movie Database", 1, 1, 4, 1) dlg:add_label("Movie Title", 1, 2, 1, 1) local item = vlc.input.item() txt = dlg:add_text_input(item and item:name() or "", 2, 2, 1, 1) dlg:add_button("Okay", click_okay, 3, 2, 1, 1) dlg:add_button("*", update_title, 4, 2, 1, 1) dlg:show() -- Show, if not already visible end function activate() create_dialog() end function deactivate() end -- Dialog closed function close() -- Deactivate this extension vlc.deactivate() end -- Some global variables: widgets list = nil button_open = nil titles = nil html = nil function click_okay() vlc.msg.dbg("Searching for " .. txt:get_text() .. " on IMDb") if html then dlg:del_widget(html) html = nil end if not list then list = dlg:add_list(1, 3, 4, 1) button_open = dlg:add_button("Open", click_open, 1, 4, 4, 1) end -- Clear previous results list:clear() -- Search IMDb local url = "http://www.imdb.com/find?s=all&q=" local title = string.gsub(txt:get_text(), " ", "+") local s, msg = vlc.stream(url .. title) if not s then vlc.msg.warn(msg) return end -- Fetch HTML data local data = s:read(65000) -- Find titles titles = {} local count = 0 idxEnd = 1 while idxEnd ~= nil do -- Find title types _, idxEnd, titleType = string.find(data, "([^<]*Titles[^<]*)", idxEnd) _, _, nextTitle = string.find(data, "([^<]*Titles[^<]*)", idxEnd) if not titleType then break else -- Find current scope if not nextTitle then _, _, table = string.find(data, "(.*)
", idxEnd) else nextTitle = string.gsub(nextTitle, "%(", "%%(") nextTitle = string.gsub(nextTitle, "%)", "%%)") _, _, table = string.find(data, "(.*)
.*"..nextTitle, idxEnd) end -- Find all titles in this scope if not table then break end pos = 0 while pos ~= nil do _, _, link = string.find(table, "]*>([^<]+)", pos) if not title then break end -- this would not be normal behavior... _, _, year = string.find(table, "\((%d+)\)", pos) -- Add this title to the list count = count + 1 _, _, imdbID = string.find(link, "/([^/]+)/$") title = replace_html_chars(title) titles[count] = { id = imdbID ; title = title ; year = year ; link = link } end end end for idx, title in ipairs(titles) do list:add_value("[" .. title.id .. "] " .. title.title .. " (" .. title.year .. ")", idx) end end function click_open() selection = list:get_selection() if not selection then return 1 end if not html then html = dlg:add_html("Loading IMDb page...", 1, 3, 4, 1) -- userLink = dlg:add_label("", 1, 4, 5, 1) end dlg:del_widget(list) dlg:del_widget(button_open) list = nil button_open = nil local sel = nil for idx, selectedItem in pairs(selection) do sel = idx break end imdbID = titles[sel].id url = "http://www.imdb.org/title/" .. imdbID .. "/" -- userLink:set_text("" .. url .. "") local s, msg = vlc.stream(url) if not s then vlc.msg.warn(msg) return end data = s:read(65000) text = "

" .. titles[sel].title .. " (" .. titles[sel].year .. ")

" text = text .. "

Overview

" -- Director local director = nil _, nextIdx, _ = string.find(data, "
]+>([%w%s]+)", nextIdx) end if not director then director = "(Unknown)" end text = text .. "
" -- Main genres local genres = "" local first = true for genre, _ in string.gmatch(data, "/Sections/Genres/(%w+)/\">") do if first then genres = genres .. "" else genres = genres .. "" end first = false end text = text .. genres -- List main actors local actors = "" first = true for nm, char in string.gmatch(data, "" first = false end text = text .. actors .. "
Director" .. director .. "
Genres" .. genre .. "
" .. genre .. "
Cast]+>([%w%s]+) ... ]+>([%w%s]+)") do if not first then actors = actors .. "
" end actors = actors .. "" .. nm .. "" .. char .. "
" text = text .. "

Plot Summary

" s, msg = vlc.stream(url .. "plotsummary") if not s then vlc.msg.warn(msg) return end data = s:read(65000) -- We read only the first summary _, _, summary = string.find(data, "

([^<]+)") if not summary then summary = "(Unknown)" end text = text .. "

" .. summary .. "

" text = text .. "

Source IMDb

" .. url .. "

" html:set_text(text) end -- Convert some HTML characters into UTF8 function replace_html_chars(txt) if not txt then return nil end -- return vlc.strings.resolve_xml_special_chars(txt) for num in string.gmatch(txt, "&#x(%x+);") do -- Convert to decimal (any better way?) dec = 0 for c in string.gmatch(num, "%x") do cc = string.byte(c) - string.byte("0") if (cc >= 10 or cc < 0) then cc = string.byte(string.lower(c)) - string.byte("a") + 10 end dec = dec * 16 + cc end txt = string.gsub(txt, "&#x" .. num .. ";", string.char(dec)) end return txt end