Sub.luac

173 views

Published on

Published in: Career
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
173
On SlideShare
0
From Embeds
0
Number of Embeds
2
Actions
Shares
0
Downloads
2
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Sub.luac

  1. 1. --[[ Subtitles Copyright © 2009-2011 VideoLAN and AUTHORS Authors: ale5000 (Based on the script made by Jean-Philippe André) 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.--]]--[[ Notes - Because of internal changes in VLC, the minimum version of VLC requiredis now: 1.1.0 git - 2010-03-21 - VLC support only uncompressed .rar files Know issues - The search fail if you click the button two times consecutively Changelog 1.04 - Updated for the latest GIT build (now almost all lua bugs are fixed) - Bumped the minimum version required - Minor changes 1.03 - Fixed the duplicated names that were appearing in the search - Fixed the empty names that were appearing in the search - Now there is a message when it doesnt find anything - Minor optimizations - Minor fixes 1.02 - Fix for the latest GIT build 1.01 - Changed version schema - Now there isnt any dialog showed by default, you can still open themfrom the menu - Now it is more clear when the script is working - Added some dlg:flush() that were missing (this fix the elements in thedialog that werent updated) - Now it catch the fail of vlc.stream - Minor fixes 0.1.8 - Now you can open a new dialog while the previous is still open - Fixed getting title in the new version of VLC - Now using dlg:flush() where appropriate - Workarounded some bugs in VLC
  2. 2. IMPORTANT: Now it no longer work on old versions of VLC 0.1.7 - Removed the button "+"; it is useless since the title is updatedautomatically - The download dialog can now be hidden/showed - Added the "Load from url..." dialog - The code of parse_archive() is now a separate function called by both"Load from url..." and the normal subtitles download dialog. - Minor changes 0.1.6 - Some variables made local - Minor fixes - Added .rar archive support ("stream_filter_rar" is incomplete and canonly use one file in the archive, need a fix in VLC) Note: VLC support only uncompressed .rar files]]-- Global variablesdlg = nildialog_is_opened = falsedialog_is_hidden = falseupdate_title_needed = false-- -Commonwebsite = nillanguage = nilmain_text_input = nilsearch_button = nilload_button = nil-- -Dialog "Download subtitles"subtitles_list = nilsubtitles_result = nil-- -Dialog "Load subtitles from url..."type_text_input = nilfunction descriptor() return { title = "Subtitles"; version = "1.04"; author = "ale5000"; url =http://ale5000.altervista.org/vlc/extensions/subtitles-mod.lua; description = "<center><b>Subtitles</b></center>" .. "Get the subtitles of movies from theinternet, currently only from OpenSubtitles.org<br /><br />" .. "<imgsrc=http://static.opensubtitles.org/favicon.ico /> Subtitles service allowedby <a href=http://www.opensubtitles.org/>www.OpenSubtitles.org</a><br />" .. "<br /><b>(Based on the script made byJean-Philippe André)</b>"; shortdesc = "Get the subtitles of movies from theinternet, currently only from OpenSubtitles.org"; capabilities = { "menu"; "input-listener"--[[; "meta-listener"]] } }endfunction menu() if not dialog_is_hidden then return { "Download", "Upload", "Load from url...", "About" } else return { "Show" }
  3. 3. endend-- Function triggered when the extension is activatedfunction activate() vlc.msg.dbg(_VERSION) vlc.msg.dbg("[Subtitles] Activating") trigger_menu(1) return trueend-- Function triggered when the extension is deactivatedfunction deactivate() if dialog_is_opened then close() else reset_variables() dlg = nil end vlc.msg.dbg("[Subtitles] Deactivated") return trueendfunction reset_variables() update_title_needed = false -- Common website = nil language = nil main_text_input = nil search_button = nil load_button = nil -- Dialog "Download subtitles" subtitles_list = nil subtitles_result = nil -- Dialog "Load subtitles from url..." type_text_input = nilend-- Function triggered when the dialog is closedfunction close() dialog_is_opened = false dialog_is_hidden = false vlc.msg.dbg("[Subtitles] Closing dialog") reset_variables() if dlg ~= nil then dlg:delete() end dlg = nil return trueend-- Current input changedfunction input_changed() vlc.msg.dbg("[Subtitles] Input is changed") update_title()end-- Current input item meta changed--[[function meta_changed()end]]function update_title() if dialog_is_hidden or not update_title_needed then return true end
  4. 4. vlc.msg.dbg("[Subtitles] Updating title") local item = vlc.input.item() if item == nil then return false end local title = item:name() -- It return the internal title or thefilename if the first is missing if title ~= nil then title = string.gsub(title, "(.*)%.%w+$", "%1") -- Removes fileextension if title ~= "" then main_text_input:set_text(title) dlg:update() return true end end return falseendfunction show_dialog_download() -- column, row, colspan, rowspan dlg:add_label("<right><b>Database: </b></right>", 1, 1, 1, 1) website = dlg:add_dropdown(2, 1, 3, 1) dlg:add_label("<right><b>Language: </b></right>", 1, 2, 1, 1) language = dlg:add_dropdown(2, 2, 3, 1) dlg:add_label("<right><b>Search: </b></right>", 1, 3, 1, 1) main_text_input = dlg:add_text_input("", 2, 3, 1, 1) search_button = dlg:add_button("Search", click_search, 3, 3, 1, 1) dlg:add_button("Hide", hide_dialog, 4, 3, 1, 1) for idx, ws in ipairs(websites) do website:add_value(ws.title, idx) end for idx, ws in ipairs(languages) do language:add_value(ws.title, idx) end update_title_needed = true update_title() dlg:update() return trueendfunction show_dialog_upload() -- column, row, colspan, rowspan dlg:add_label("<right><b>Database: </b></right>", 1, 1, 1, 1) website = dlg:add_dropdown(2, 1, 4, 1)-- FIXME: Link is NOT yet working dlg:add_label("<center><ahref=http://www.opensubtitles.org/upload>Upload toOpenSubtitles.org</a></center>", 1, 2, 2, 1) for idx, ws in ipairs(websites) do website:add_value(ws.title, idx) end dlg:update() return trueend
  5. 5. function show_dialog_load_url() -- column, row, colspan, rowspan dlg:add_label("<right><b>URL: </b></right>", 1, 1, 1, 1) main_text_input = dlg:add_text_input("", 2, 1, 3, 1) dlg:add_label("<right><b>Type: </b></right>", 1, 2, 1, 1) type_text_input = dlg:add_text_input("", 2, 2, 1, 1) dlg:add_label("&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;", 3, 2, 1,1) -- Spacer load_button = dlg:add_button("Load", click_load_from_url_button, 4, 2, 1,1) dlg:update() return trueendfunction show_dialog_about() local data = descriptor() -- column, row, colspan, rowspan dlg:add_label("<center><b>" .. data.title .. " " .. data.version .."</b></center>", 1, 1, 1, 1) dlg:add_html(data.description, 1, 2, 1, 1) dlg:update() return trueendfunction sleep(sec) local t = vlc.misc.mdate() vlc.misc.mwait(t + sec*1000*1000)endfunction new_dialog(title) dlg = vlc.dialog(title)endfunction hide_dialog() dialog_is_hidden = true dlg:hide()end-- Function triggered when a element from the menu is selectedfunction trigger_menu(id) if dialog_is_hidden then if dlg == nil then vlc.msg.err("[Subtitles] Dialog pointer lost") close() return false; end dialog_is_hidden = false dlg:show() return true end if(dialog_is_opened) then close() end dialog_is_opened = true if id == 1 then new_dialog("Download subtitles") return show_dialog_download() elseif id == 2 then new_dialog("Upload subtitles") return show_dialog_upload()
  6. 6. elseif id == 3 then new_dialog("Load subtitles from url...") return show_dialog_load_url() elseif id == 4 then new_dialog("About") return show_dialog_about() end vlc.msg.err("[Subtitles] Invalid menu id: "..id) return falseendfunction click_search() vlc.msg.dbg("[Subtitles] Clicked search button from "Download subtitles"dialog") local search_term = main_text_input:get_text() if(search_term == "") then return false end local old_button_name = search_button:get_text() search_button:set_text("Wait...") if subtitles_list ~= nil then subtitles_list:clear() end dlg:update() subtitles_result = nil local idx = website:get_value() local idx2 = language:get_value() if idx < 1 or idx2 < 1 then vlc.msg.err("[Subtitles] Invalid index indropdown") search_button:set_text(old_button_name) return false end local ws = websites[idx] local lang = languages[idx2] local url = ws.urlfunc(search_term) -- vlc.msg.info("[Subtitles] Url: " .. url .. "") local stream = vlc.stream(url) if stream == nil then vlc.msg.err("[Subtitles] The site of subtitles isntreachable") search_button:set_text(old_button_name) return false end local reading = "blah" local xmlpage = "" while(reading ~= nil and reading ~= "") do reading = stream:read(65653) if(reading) then xmlpage = xmlpage .. reading end end if xmlpage == "" then search_button:set_text(old_button_name) return falseend subtitles_result = ws.parsefunc(xmlpage) if subtitles_list == nil then subtitles_list = dlg:add_list(1, 4, 4, 1) load_button = dlg:add_button("Load selected subtitles",click_load_from_search_button, 1, 5, 4, 1) end if not subtitles_result then subtitles_result = {} subtitles_result[1]= { url = "-1" } subtitles_list:add_value("Nothing found", 1) search_button:set_text(old_button_name) dlg:update()
  7. 7. return false end for idx, res in ipairs(subtitles_result) do if(not res.language or lang.tag == "all" or lang.tag ==res.language) then subtitles_list:add_value("["..res.language.."] "..res.name,idx) end end search_button:set_text(old_button_name) dlg:update() return trueendfunction load_unknown_subtitles(url, language) vlc.msg.dbg("[Subtitles] Loading "..language.." subtitle: "..url) vlc.input.add_subtitle(url)endfunction load_subtitles_in_the_archive(dataBuffer, language) local buffer_length = dataBuffer:len() local files_found_in_the_compressed_file = 0 local subtitles_found_in_the_compressed_file = 0 local endIdx = 1 local srturl, extension -- Find subtitles while(endIdx < buffer_length) do _, endIdx, srturl, extension = dataBuffer:find("<location>([^<]+)%.(%a%a%a?)</location>", endIdx) if(srturl == nil ) then break end --vlc.msg.dbg("[Subtitles] File found in the archive: " .. srturl ..extension) files_found_in_the_compressed_file =files_found_in_the_compressed_file + 1 srturl = string.gsub(srturl, "^(%a%a%a)://", "%1://http://") if(extension == "ass" or extension == "ssa" or extension == "srt" orextension == "smi" or extension == "sub" or extension == "rt" or extension =="txt" or extension == "mpl") then subtitles_found_in_the_compressed_file =subtitles_found_in_the_compressed_file + 1 vlc.msg.dbg("[Subtitles] Loading "..language.." subtitle:"..srturl) vlc.input.add_subtitle(srturl.."."..extension) end end vlc.msg.info("[Subtitles] Files found in the compressed file:"..files_found_in_the_compressed_file) vlc.msg.info("[Subtitles] Subtitles found in the compressed file:"..subtitles_found_in_the_compressed_file) if(subtitles_found_in_the_compressed_file > 0) then return true end vlc.msg.warn("[Subtitles] No subtitles found in the compressed file") return falseendfunction parse_archive(url, language) if url == "-1" then vlc.msg.dbg("[Subtitles] Dummy result") return trueend
  8. 8. local stream = vlc.stream(url) if stream == nil then vlc.msg.err("[Subtitles] The site of subtitles isntreachable") return false end stream:addfilter("zip,stream_filter_rar") local data = stream:read(2048) if(data == nil or data:find("<?xml version", 1, true) ~= 1) then vlc.msg.info("[Subtitles] Type: RAR or unknown file") load_unknown_subtitles(url, language) else vlc.msg.info("[Subtitles] Type: ZIP file") local dataBuffer = "" while(data ~= nil and data ~= "") do vlc.msg.dbg("Buffering...") dataBuffer = dataBuffer..data data = stream:read(8192) end load_subtitles_in_the_archive(dataBuffer, language) end --vlc.msg.dbg("[Subtitles] Subtitle data: "..dataBuffer) return trueendfunction click_load_from_search_button() vlc.msg.dbg("[Subtitles] Clicked load button from "Download subtitles"dialog") if(not vlc.input.is_playing()) then vlc.msg.warn("[Subtitles] You cannot load subtitles if you arentplaying any file") return true end local old_button_name = load_button:get_text() load_button:set_text("Wait...") dlg:update() local selection = subtitles_list:get_selection() local index, name for index, name in pairs(selection) do vlc.msg.dbg("[Subtitles] Selected the item "..index.." with thename: "..name) vlc.msg.dbg("[Subtitles] URL: "..subtitles_result[index].url) parse_archive(subtitles_result[index].url,subtitles_result[index].language) -- ZIP, RAR or unknown file end load_button:set_text(old_button_name) dlg:update() return trueendfunction click_load_from_url_button() vlc.msg.dbg("[Subtitles] Clicked load button in "Load subtitles fromurl..." dialog") if(not vlc.input.is_playing()) then vlc.msg.warn("[Subtitles] You cannot load subtitles if you arentplaying any file") return true end local old_button_name = load_button:get_text() load_button:set_text("Wait...")
  9. 9. type_text_input:set_text("") dlg:update() local url_to_load = main_text_input:get_text() if(url_to_load == "") then return false end vlc.msg.dbg("[Subtitles] URL: "..url_to_load) local _, ext_pos, extension = url_to_load:find("%.(%a%a%a?)", -4) if(ext_pos == url_to_load:len()) then type_text_input:set_text(extension) if(extension == "ass" or extension == "ssa" or extension == "srt" orextension == "smi" or extension == "sub" or extension == "rt" or extension =="txt" or extension == "mpl") then load_button:set_text(old_button_name) dlg:update() return vlc.input.add_subtitle(url_to_load) end end local result = parse_archive(url_to_load, "") if not result then vlc.msg.info("[Subtitles] Waiting 5 seconds before retry...") sleep(5) result = parse_archive(url_to_load, "") end load_button:set_text(old_button_name) dlg:update() return resultend-- XML Parsingfunction parseargs(s) local arg = {} string.gsub(s, "(%w+)=(["])(.-)%2", function (w, _, a) arg[w] = a end) return argendfunction collect(s) local stack = {} local top = {} table.insert(stack, top) local ni,c,label,xarg, empty local i, j = 1, 1 while true do ni,j,c,label,xarg, empty = string.find(s, "<(%/?)([%w:]+)(.-)(%/?)>", i) if not ni then break end local text = string.sub(s, i, ni-1) if not string.find(text, "^%s*$") then table.insert(top, text) end if empty == "/" then -- empty element tag table.insert(top, {label=label, xarg=parseargs(xarg),empty=1}) elseif c == "" then -- start tag top = {label=label, xarg=parseargs(xarg)} table.insert(stack, top) -- new level else -- end tag
  10. 10. local toclose = table.remove(stack) -- remove top top = stack[#stack] if #stack < 1 then error("nothing to close with "..label) end if toclose.label ~= label then error("trying to close "..toclose.label.." with"..label) end table.insert(top, toclose) end i = j+1 end local text = string.sub(s, i) if not string.find(text, "^%s*$") then table.insert(stack[#stack], text) end if #stack > 1 then error("unclosed "..stack[stack.n].label) end return stack[1]end--[[ Websites configurations]]---- OpenSubtitles.org-- This function uses first version of OS API. It will probably fail in-- the future. Well need a XML-RPC key btwfunction urlOpenSub(search_term) -- base = "http://api.opensubtitles.org/xml-rpc" -- lang = "eng" base = "http://api.opensubtitles.org/en/search/" -- if(lang) then base = base .. "sublanguageid-" .. lang .. "/" search_term = string.gsub(search_term, "%%", "%%37") search_term = string.gsub(search_term, " ", "%%20") return base .. "moviename-" .. search_term .. "/simplexml" -- http://api.opensubtitles.org/en/search/moviename- .. search_term ../simplexmlendfunction parseOpenSub(xmltext) vlc.msg.dbg("[Subtitles] Parsing XML data...") local xmltext = string.gsub(xmltext, "<%?xml version="1%.0"encoding="utf-8"%?>", "") local xmldata = collect(xmltext) for a,b in pairs(xmldata) do if type(b) == "table" then if b.label == "search" then xmldata = b break end end end if xmldata == nil then return nil end -- Subtitles information data local subname = {} local sub_movie = {} local suburl = {}
  11. 11. local sublang = {} local sub_language = {} local subformat = {} local subfilenum = {} local subnum = 1 local baseurl = "" -- Lets browse iteratively the xmldata tree -- OK, the variables names arent explicit enough, but just remember acouple -- a,b contains the index (a) and the data (b) of the table, which mightalso be a table for a,b in pairs(xmldata) do if type(b) == "table" then if b.label == "results" then for c,d in pairs(b) do if type(d) == "table" then if d.label == "subtitle" then for e,f in pairs(d) do if type(f) == "table" then if f.label == "releasename"then if f[1] ~= nil thensubname[subnum] = f[1] else subname[subnum]= "" end elseif f.label == "movie"then if f[1] ~= nil thensub_movie[subnum] = f[1] elsesub_movie[subnum] = "" end elseif f.label =="download" then if f[1] ~= nil thensuburl[subnum] = f[1] else suburl[subnum] ="" end elseif f.label == "iso639"then -- language if f[1] ~= nil thensublang[subnum] = f[1] else sublang[subnum]= "" end elseif f.label =="language" then -- language -- not use yet if f[1] ~= nil thensub_language[subnum] = f[1] elsesub_language[subnum] = "" end elseif f.label == "format"then if f[1] ~= nil thensubformat[subnum] = f[1] elsesubformat[subnum] = "" end end end end subnum = subnum + 1 end end end elseif b.label == "base" then
  12. 12. baseurl = b[1] end end end if subnum <= 1 then return nil end ret = {} for i = 1,(subnum - 1) do fullURL = baseurl .. "/" .. suburl[i] realName = string.gsub( subname[i], "<..CDATA.", "" ) realName = string.gsub( realName, "..>", "" ) if realName == "" then realName = string.gsub( sub_movie[i], "<..CDATA.", "" ) realName = string.gsub( realName, "..>", "" ) end ret[i] = { name = realName, url = fullURL, language = sublang[i], extension = ".zip" } vlc.msg.dbg("[Subtitles] Found subtitle " .. i .. ": ") vlc.msg.dbg(realName) vlc.msg.dbg(fullURL) end return retend-- These tables must be after all function definitionswebsites = { { title = "OpenSubtitles.org", urlfunc = urlOpenSub, parsefunc = parseOpenSub } --[[; { title = "Fake (OS)", urlfunc = url2, parsefunc = parse2 }]]}languages = { { title = "All", tag = "all" }, { title = "English", tag = "en" }, { title = "Chinese", tag = "zh" }, { title = "Finnish", tag = "fi" }, { title = "French", tag = "fr" }, { title = "German", tag = "de" }, { title = "Italian", tag = "it" }, { title = "Japanese", tag = "ja" }, { title = "Polish", tag = "pl" }, { title = "Portuguese", tag = "pt" }, { title = "Russian", tag = "ru" }, { title = "Spanish", tag = "es" }}

×