mcbot/cmds/tvcal.lua
author Mikael Berthe <mikael@lilotux.net>
Sun, 25 Nov 2012 19:29:32 +0100
changeset 65 2cefbe9f3ac6
parent 63 31f967ba9e1f
child 66 d9c00a9fe9d5
permissions -rw-r--r--
shortenurl: cosmetical change
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
39
237af42156a1 Add checks after shcmd() calls
Mikael Berthe <mikael@lilotux.net>
parents: 38
diff changeset
    31
    if not contents then
237af42156a1 Add checks after shcmd() calls
Mikael Berthe <mikael@lilotux.net>
parents: 38
diff changeset
    32
        return nil, "Could not fetch calendar, please try again later!"
237af42156a1 Add checks after shcmd() calls
Mikael Berthe <mikael@lilotux.net>
parents: 38
diff changeset
    33
    end
237af42156a1 Add checks after shcmd() calls
Mikael Berthe <mikael@lilotux.net>
parents: 38
diff changeset
    34
61
5d807892b439 tvcal: Work around buggy 0x0d at end of lines
Mikael Berthe <mikael@lilotux.net>
parents: 59
diff changeset
    35
    -- Work around frackin ugly end of line characters... :/
5d807892b439 tvcal: Work around buggy 0x0d at end of lines
Mikael Berthe <mikael@lilotux.net>
parents: 59
diff changeset
    36
    local eol = "[%s"..string.char(13).."]*"
5d807892b439 tvcal: Work around buggy 0x0d at end of lines
Mikael Berthe <mikael@lilotux.net>
parents: 59
diff changeset
    37
58
4c3028c21ccb Sync tvcal module (another website change...)
Mikael Berthe <mikael@lilotux.net>
parents: 57
diff changeset
    38
    -- Regex for each day
4c3028c21ccb Sync tvcal module (another website change...)
Mikael Berthe <mikael@lilotux.net>
parents: 57
diff changeset
    39
    local tabregex = '<td id="d_(%d+_%d+_%d%d%d%d)" class="t?o?day"%s*>'..
4c3028c21ccb Sync tvcal module (another website change...)
Mikael Berthe <mikael@lilotux.net>
parents: 57
diff changeset
    40
                     '%s*(.-)%s*</td>'
36
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    41
58
4c3028c21ccb Sync tvcal module (another website change...)
Mikael Berthe <mikael@lilotux.net>
parents: 57
diff changeset
    42
    -- Regex for parsing one day
59
0a39d217b80a Fix tvcal regex
Mikael Berthe <mikael@lilotux.net>
parents: 58
diff changeset
    43
    local epregex = '<p[^>]*>'..
61
5d807892b439 tvcal: Work around buggy 0x0d at end of lines
Mikael Berthe <mikael@lilotux.net>
parents: 59
diff changeset
    44
                      '<a href=[^>]+>([^<]+)</a>'..eol..        -- Name
5d807892b439 tvcal: Work around buggy 0x0d at end of lines
Mikael Berthe <mikael@lilotux.net>
parents: 59
diff changeset
    45
                      '<br /><a href=[^>]+>([^<]+)</a>'..eol..  -- Episode
58
4c3028c21ccb Sync tvcal module (another website change...)
Mikael Berthe <mikael@lilotux.net>
parents: 57
diff changeset
    46
                    '</p>'
4c3028c21ccb Sync tvcal module (another website change...)
Mikael Berthe <mikael@lilotux.net>
parents: 57
diff changeset
    47
4c3028c21ccb Sync tvcal module (another website change...)
Mikael Berthe <mikael@lilotux.net>
parents: 57
diff changeset
    48
    -- loop over all days
4c3028c21ccb Sync tvcal module (another website change...)
Mikael Berthe <mikael@lilotux.net>
parents: 57
diff changeset
    49
    for day, daytab in string.gmatch(contents, tabregex) do
36
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    50
        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
    51
        day = string.format("%04d-%02d-%02d", y, m, d)
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    52
58
4c3028c21ccb Sync tvcal module (another website change...)
Mikael Berthe <mikael@lilotux.net>
parents: 57
diff changeset
    53
        local shows = {}
36
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    54
58
4c3028c21ccb Sync tvcal module (another website change...)
Mikael Berthe <mikael@lilotux.net>
parents: 57
diff changeset
    55
        -- Loop over all episodes of a day
4c3028c21ccb Sync tvcal module (another website change...)
Mikael Berthe <mikael@lilotux.net>
parents: 57
diff changeset
    56
        for name, ep in string.gmatch(daytab, epregex) do
36
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    57
            name = name:gsub("&quot;", "\""):gsub("&amp;", "&")
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    58
            name = name:gsub("&lt;", "<"):gsub("&gt;", ">")
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    59
            name = name:gsub("&#39;", "'")
63
31f967ba9e1f tvcal: Remove newlines in episode names
Mikael Berthe <mikael@lilotux.net>
parents: 61
diff changeset
    60
            name = name:gsub("%s*\n%s*", "  ")
36
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    61
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    62
            local obj = {
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    63
                ["name"] = name,
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    64
                ["ep"] = ep
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
            table.insert(shows, obj)
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    67
        end
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    68
        tvcaldata[day] = shows
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    69
    end
58
4c3028c21ccb Sync tvcal module (another website change...)
Mikael Berthe <mikael@lilotux.net>
parents: 57
diff changeset
    70
36
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    71
    tvcaldata_timestamp = os.date("%F")
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    72
    return true
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    73
end
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    74
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    75
local function tvcal_by_date (d)
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    76
    if not tvcaldata[d] then
37
9d7f19e4e4fe Add support for tvcal +n
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
    77
        return "No episode found for this date ("..d..")"
36
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    78
    end
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    79
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    80
    local r = "Shows on " .. d .. ":\n"
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    81
    for i,j in ipairs(tvcaldata[d]) do
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    82
        r = r .. 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
    r = r:gsub("\n+$", "")
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    85
    return r
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    86
end
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    87
38
a51ddbce247b Add regex support to tvcal
Mikael Berthe <mikael@lilotux.net>
parents: 37
diff changeset
    88
local function tvcal_by_name (name, plain)
a51ddbce247b Add regex support to tvcal
Mikael Berthe <mikael@lilotux.net>
parents: 37
diff changeset
    89
    local action = plain and "contain" or "match"
36
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    90
    local r = ""
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    91
    name = name:lower()
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    92
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    93
    for day, obj in pairsByKeys(tvcaldata) do
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    94
        for i,j in ipairs(obj) do
38
a51ddbce247b Add regex support to tvcal
Mikael Berthe <mikael@lilotux.net>
parents: 37
diff changeset
    95
            if j.name:lower():find(name, 1, plain) then
36
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    96
                r = r .. day .. "\t" .. j.name .. " (" ..j.ep .. ")\n"
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    97
            end
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    98
        end
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
    99
    end
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   100
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   101
    if r == "" then
38
a51ddbce247b Add regex support to tvcal
Mikael Berthe <mikael@lilotux.net>
parents: 37
diff changeset
   102
        return "No episode found "..action.."ing this string"
36
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   103
    end
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   104
    r = r:gsub("\n+$", "")
38
a51ddbce247b Add regex support to tvcal
Mikael Berthe <mikael@lilotux.net>
parents: 37
diff changeset
   105
    return "Episodes "..action.."ing \""..name.."\":\n" .. r
36
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   106
end
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   107
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   108
function tvcal.cmd (arg)
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   109
    if not tvcaldata_timestamp or tvcaldata_timestamp ~= os.date("%F") then
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   110
        tvcaldata = {} -- Empty the previous list
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   111
        local r, err = parse_webpage("http://www.pogdesign.co.uk/cat/")
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   112
        if not r then return nil, err end
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   113
        -- Fetch next month as well...
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   114
        local m = tonumber(os.date("%m"))+1
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   115
        local y = os.date("%Y")
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   116
        if m > 12 then m = 1; y = y + 1; end
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   117
        parse_webpage("http://www.pogdesign.co.uk/cat/"..m.."-"..y)
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   118
    end
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   119
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   120
    if not arg or arg == "today" then
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   121
        arg = os.date("%F")
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   122
    elseif arg == "tomorrow" then
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   123
        arg = os.date("%F", os.date("%s")+86400)
37
9d7f19e4e4fe Add support for tvcal +n
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   124
    elseif arg:match("^%+%d+$") then
9d7f19e4e4fe Add support for tvcal +n
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   125
        local n = tonumber(arg:match("^%+(%d+)$"))
9d7f19e4e4fe Add support for tvcal +n
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   126
        if n < 60 then
9d7f19e4e4fe Add support for tvcal +n
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   127
            arg = os.date("%F", os.date("%s")+86400*n)
9d7f19e4e4fe Add support for tvcal +n
Mikael Berthe <mikael@lilotux.net>
parents: 36
diff changeset
   128
        end
36
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   129
    end
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   130
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   131
    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
   132
        return tvcal_by_date(arg)
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   133
    end
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   134
38
a51ddbce247b Add regex support to tvcal
Mikael Berthe <mikael@lilotux.net>
parents: 37
diff changeset
   135
    -- Is it a pattern? (string surrounded by quotes)
a51ddbce247b Add regex support to tvcal
Mikael Berthe <mikael@lilotux.net>
parents: 37
diff changeset
   136
    local plain = arg:match('^"(.*)"$')
a51ddbce247b Add regex support to tvcal
Mikael Berthe <mikael@lilotux.net>
parents: 37
diff changeset
   137
    if plain then
a51ddbce247b Add regex support to tvcal
Mikael Berthe <mikael@lilotux.net>
parents: 37
diff changeset
   138
        arg = plain
a51ddbce247b Add regex support to tvcal
Mikael Berthe <mikael@lilotux.net>
parents: 37
diff changeset
   139
        plain = false
a51ddbce247b Add regex support to tvcal
Mikael Berthe <mikael@lilotux.net>
parents: 37
diff changeset
   140
    else
a51ddbce247b Add regex support to tvcal
Mikael Berthe <mikael@lilotux.net>
parents: 37
diff changeset
   141
        plain = true
a51ddbce247b Add regex support to tvcal
Mikael Berthe <mikael@lilotux.net>
parents: 37
diff changeset
   142
    end
a51ddbce247b Add regex support to tvcal
Mikael Berthe <mikael@lilotux.net>
parents: 37
diff changeset
   143
    return tvcal_by_name(arg, plain)
36
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   144
end
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   145
2aedd0749666 Actually add tvcal file
Mikael Berthe <mikael@lilotux.net>
parents:
diff changeset
   146
mcbot_register_command("tvcal", tvcal)