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