--- /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(""", "\""):gsub("&", "&")
+ name = name:gsub("<", "<"):gsub(">", ">")
+ name = name:gsub("'", "'")
+
+ 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)