mcbot/cmds/tvcal.lua
changeset 36 2aedd0749666
child 37 9d7f19e4e4fe
equal deleted inserted replaced
35:1fba2631c743 36:2aedd0749666
       
     1 #! /usr/bin/env lua
       
     2 
       
     3 -- Data extractor for http://www.pogdesign.co.uk/cat/
       
     4 -- Mikael BERTHE, 2010-04-18
       
     5 
       
     6 require "libs.shcmd"
       
     7 
       
     8 local tvcal = { ["desc"] = "Display TV calendar" }
       
     9 
       
    10 local tvcaldata = {}
       
    11 local tvcaldata_timestamp
       
    12 
       
    13 -- Function from PIL
       
    14 local function pairsByKeys (t, f)
       
    15     local a = {}
       
    16     for n in pairs(t) do table.insert(a, n) end
       
    17     table.sort(a, f)
       
    18     local i = 0      -- iterator variable
       
    19     local iter = function ()   -- iterator function
       
    20         i = i + 1
       
    21         if a[i] == nil then return nil
       
    22         else return a[i], t[a[i]]
       
    23         end
       
    24     end
       
    25     return iter
       
    26 end
       
    27 
       
    28 local function parse_webpage (url)
       
    29     local contents = shcmd("curl "..url)
       
    30 
       
    31     local tabregex = '<td id="d_(%d+_%d+_%d%d%d%d)" class="t?o?day"%s*>%s*\n%s*'..
       
    32                      '<table>(.-)</table>'
       
    33 
       
    34     for day, tab in string.gmatch(contents, tabregex) do
       
    35         local epregex
       
    36         local d, m, y = day:match("^(%d+)_(%d+)_(%d%d%d%d)$")
       
    37         day = string.format("%04d-%02d-%02d", y, m, d)
       
    38 
       
    39         epregex = '<td><a id="[^"]+" href="[^"]+" class="eplink%s*"%s*>([^<]+)</a>'
       
    40         epregex = epregex .. '<span class="seasep"%s*></span><br />'
       
    41         epregex = epregex .. '<span class="seasep"%s*>([^<]+)</span>[%s\n]*</td>'
       
    42 
       
    43         local shows = {}
       
    44         for name, ep in string.gmatch(tab, epregex) do
       
    45             name = name:gsub("&quot;", "\""):gsub("&amp;", "&")
       
    46             name = name:gsub("&lt;", "<"):gsub("&gt;", ">")
       
    47             name = name:gsub("&#39;", "'")
       
    48 
       
    49             local obj = {
       
    50                 ["name"] = name,
       
    51                 ["ep"] = ep
       
    52                 }
       
    53             table.insert(shows, obj)
       
    54         end
       
    55         tvcaldata[day] = shows
       
    56     end
       
    57     tvcaldata_timestamp = os.date("%F")
       
    58     return true
       
    59 end
       
    60 
       
    61 local function tvcal_by_date (d)
       
    62     if not tvcaldata[d] then
       
    63         return "No episode found for this date"
       
    64     end
       
    65 
       
    66     local r = "Shows on " .. d .. ":\n"
       
    67     for i,j in ipairs(tvcaldata[d]) do
       
    68         r = r .. j.name .. " (" ..j.ep .. ")\n"
       
    69     end
       
    70     r = r:gsub("\n+$", "")
       
    71     return r
       
    72 end
       
    73 
       
    74 local function tvcal_by_name (name)
       
    75     local r = ""
       
    76     name = name:lower()
       
    77 
       
    78     for day, obj in pairsByKeys(tvcaldata) do
       
    79         for i,j in ipairs(obj) do
       
    80             if j.name:lower():find(name, 1, true) then
       
    81                 r = r .. day .. "\t" .. j.name .. " (" ..j.ep .. ")\n"
       
    82             end
       
    83         end
       
    84     end
       
    85 
       
    86     if r == "" then
       
    87         return "No episode found containing this string"
       
    88     end
       
    89     r = r:gsub("\n+$", "")
       
    90     return "Episodes containing \""..name.."\":\n" .. r
       
    91 end
       
    92 
       
    93 function tvcal.cmd (arg)
       
    94     if not tvcaldata_timestamp or tvcaldata_timestamp ~= os.date("%F") then
       
    95         tvcaldata = {} -- Empty the previous list
       
    96         local r, err = parse_webpage("http://www.pogdesign.co.uk/cat/")
       
    97         if not r then return nil, err end
       
    98         -- Fetch next month as well...
       
    99         local m = tonumber(os.date("%m"))+1
       
   100         local y = os.date("%Y")
       
   101         if m > 12 then m = 1; y = y + 1; end
       
   102         parse_webpage("http://www.pogdesign.co.uk/cat/"..m.."-"..y)
       
   103     end
       
   104 
       
   105     if not arg or arg == "today" then
       
   106         arg = os.date("%F")
       
   107     elseif arg == "tomorrow" then
       
   108         arg = os.date("%F", os.date("%s")+86400)
       
   109     end
       
   110 
       
   111     if arg:match("^%d%d%d%d%-%d%d%-%d%d$") then
       
   112         return tvcal_by_date(arg)
       
   113     end
       
   114 
       
   115     return tvcal_by_name(arg)
       
   116 end
       
   117 
       
   118 mcbot_register_command("tvcal", tvcal)