Actually add tvcal file
authorMikael Berthe <mikael@lilotux.net>
Sun, 18 Apr 2010 23:51:22 +0200
changeset 36 2aedd0749666
parent 35 1fba2631c743
child 37 9d7f19e4e4fe
Actually add tvcal file Also, fetch data for next month
mcbot/cmds/tvcal.lua
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mcbot/cmds/tvcal.lua	Sun Apr 18 23:51:22 2010 +0200
@@ -0,0 +1,118 @@
+#! /usr/bin/env lua
+
+-- Data extractor for http://www.pogdesign.co.uk/cat/
+-- Mikael BERTHE, 2010-04-18
+
+require "libs.shcmd"
+
+local tvcal = { ["desc"] = "Display TV calendar" }
+
+local tvcaldata = {}
+local tvcaldata_timestamp
+
+-- Function from PIL
+local function pairsByKeys (t, f)
+    local a = {}
+    for n in pairs(t) do table.insert(a, n) end
+    table.sort(a, f)
+    local i = 0      -- iterator variable
+    local iter = function ()   -- iterator function
+        i = i + 1
+        if a[i] == nil then return nil
+        else return a[i], t[a[i]]
+        end
+    end
+    return iter
+end
+
+local function parse_webpage (url)
+    local contents = shcmd("curl "..url)
+
+    local tabregex = '<td id="d_(%d+_%d+_%d%d%d%d)" class="t?o?day"%s*>%s*\n%s*'..
+                     '<table>(.-)</table>'
+
+    for day, tab in string.gmatch(contents, tabregex) do
+        local epregex
+        local d, m, y = day:match("^(%d+)_(%d+)_(%d%d%d%d)$")
+        day = string.format("%04d-%02d-%02d", y, m, d)
+
+        epregex = '<td><a id="[^"]+" href="[^"]+" class="eplink%s*"%s*>([^<]+)</a>'
+        epregex = epregex .. '<span class="seasep"%s*></span><br />'
+        epregex = epregex .. '<span class="seasep"%s*>([^<]+)</span>[%s\n]*</td>'
+
+        local shows = {}
+        for name, ep in string.gmatch(tab, epregex) do
+            name = name:gsub("&quot;", "\""):gsub("&amp;", "&")
+            name = name:gsub("&lt;", "<"):gsub("&gt;", ">")
+            name = name:gsub("&#39;", "'")
+
+            local obj = {
+                ["name"] = name,
+                ["ep"] = ep
+                }
+            table.insert(shows, obj)
+        end
+        tvcaldata[day] = shows
+    end
+    tvcaldata_timestamp = os.date("%F")
+    return true
+end
+
+local function tvcal_by_date (d)
+    if not tvcaldata[d] then
+        return "No episode found for this date"
+    end
+
+    local r = "Shows on " .. d .. ":\n"
+    for i,j in ipairs(tvcaldata[d]) do
+        r = r .. j.name .. " (" ..j.ep .. ")\n"
+    end
+    r = r:gsub("\n+$", "")
+    return r
+end
+
+local function tvcal_by_name (name)
+    local r = ""
+    name = name:lower()
+
+    for day, obj in pairsByKeys(tvcaldata) do
+        for i,j in ipairs(obj) do
+            if j.name:lower():find(name, 1, true) then
+                r = r .. day .. "\t" .. j.name .. " (" ..j.ep .. ")\n"
+            end
+        end
+    end
+
+    if r == "" then
+        return "No episode found containing this string"
+    end
+    r = r:gsub("\n+$", "")
+    return "Episodes containing \""..name.."\":\n" .. r
+end
+
+function tvcal.cmd (arg)
+    if not tvcaldata_timestamp or tvcaldata_timestamp ~= os.date("%F") then
+        tvcaldata = {} -- Empty the previous list
+        local r, err = parse_webpage("http://www.pogdesign.co.uk/cat/")
+        if not r then return nil, err end
+        -- Fetch next month as well...
+        local m = tonumber(os.date("%m"))+1
+        local y = os.date("%Y")
+        if m > 12 then m = 1; y = y + 1; end
+        parse_webpage("http://www.pogdesign.co.uk/cat/"..m.."-"..y)
+    end
+
+    if not arg or arg == "today" then
+        arg = os.date("%F")
+    elseif arg == "tomorrow" then
+        arg = os.date("%F", os.date("%s")+86400)
+    end
+
+    if arg:match("^%d%d%d%d%-%d%d%-%d%d$") then
+        return tvcal_by_date(arg)
+    end
+
+    return tvcal_by_name(arg)
+end
+
+mcbot_register_command("tvcal", tvcal)