From: Jean-Philippe André Date: Sun, 24 Jan 2010 15:26:15 +0000 (+0100) Subject: Extensions: an example Lua script: IMDb X-Git-Tag: 1.1.0-ff~963 X-Git-Url: https://git.sesse.net/?a=commitdiff_plain;h=92ea10da4e5694e98f4e5a92656d366c2e9e7f26;p=vlc Extensions: an example Lua script: IMDb This Lua Extension will get some meta data on the current movie (or any movie) from the Internet Movie Database and shows it in a simple dialog box. Please consider this script more as an example than as a final version of the IMDb extension. --- diff --git a/share/lua/extensions/imdb.lua b/share/lua/extensions/imdb.lua new file mode 100644 index 0000000000..7cfb6230e4 --- /dev/null +++ b/share/lua/extensions/imdb.lua @@ -0,0 +1,234 @@ +--[[ + 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" ; capabilities = {} } +end + +-- Update title text field. Removes file extensions. +function update_title() + local title = vlc.input.get_title() + if (title ~= nil) then + title = string.gsub(title, "(.*)(%.%w+)$", "%1") + end + if (title ~= nil) then + txt:set_text(title) + end +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) + txt = dlg:add_text_input(vlc.input.get_title(), 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 = vlc.stream(url .. title) + + -- 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 = vlc.stream(url) + 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 = vlc.stream(url .. "plotsummary") + 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 +