plugins/xkcd.lua

Mon, 11 Feb 2013 18:28:28 +0100

author
Kim Alvefur <zash@zash.se>
date
Mon, 11 Feb 2013 18:28:28 +0100
changeset 97
a532667d596e
parent 78
00ad6fe8975e
child 98
1f365028aae1
permissions
-rw-r--r--

plugins.xkcd: If no argument is given, return the latest strip

57
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
1 local parse_xkcd_list;
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
2 local xkcd_list_updated_at = 0;
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
3 local xkcd_list = { };
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
4
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
5 function riddim.plugins.xkcd(bot)
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
6 require "net.httpclient_listener";
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
7 local http = require("net.http");
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
8 bot:hook("commands/xkcd", function(command)
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
9 if os.difftime(os.time(), xkcd_list_updated_at) > (3 * 60 * 60) then -- Not refreshed within 3 hours
77
7e50244d8e42 plugins.xkcd: Microsoft apparently hates %T (crashes on Windows)
God of Dice@mf-nb
parents: 66
diff changeset
10 --COMPAT We could have saved 6 bytes here, but Microsoft apparently hates %T, so you got this gigantic comment instead.
7e50244d8e42 plugins.xkcd: Microsoft apparently hates %T (crashes on Windows)
God of Dice@mf-nb
parents: 66
diff changeset
11 -- http.request('http://xkcd.com/archive/', { headers = { ["If-Modified-Since"] = os.date("!%a, %d %b %Y %T %Z", xkcd_list_updated_at or 0) } }, function (data, code)
7e50244d8e42 plugins.xkcd: Microsoft apparently hates %T (crashes on Windows)
God of Dice@mf-nb
parents: 66
diff changeset
12 http.request('http://xkcd.com/archive/', { headers = { ["If-Modified-Since"] = os.date("!%a, %d %b %Y %H:%M:%S %Z", xkcd_list_updated_at or 0) } }, function (data, code)
57
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
13 if code == 200 then
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
14 xkcd_list_updated_at = os.time();
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
15 print("debug", "got "..(#data or 0).." bytes of data");
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
16 parse_xkcd_list(data);
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
17 elseif code == 304 then
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
18 xkcd_list_updated_at = os.time();
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
19 else
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
20 if code > 0 then
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
21 command:reply("Received HTTP "..code.." error trying to fetch the XKCD archive");
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
22 else
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
23 command:reply("Unable to fetch the XKCD archive from xkcd.com: "..data:gsub("%-", " "));
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
24 end
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
25 return;
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
26 end
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
27 command:reply(handle_xkcd_command(command));
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
28 end);
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
29 else
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
30 return handle_xkcd_command(command);
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
31 end
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
32 end);
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
33 end
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
34
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
35 function handle_xkcd_command(command)
78
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
36 local xkcdnum = command.param;
97
a532667d596e plugins.xkcd: If no argument is given, return the latest strip
Kim Alvefur <zash@zash.se>
parents: 78
diff changeset
37 if not xkcdnum then
a532667d596e plugins.xkcd: If no argument is given, return the latest strip
Kim Alvefur <zash@zash.se>
parents: 78
diff changeset
38 xkcdnum = #xkcd_list;
a532667d596e plugins.xkcd: If no argument is given, return the latest strip
Kim Alvefur <zash@zash.se>
parents: 78
diff changeset
39 end
78
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
40 if not tonumber(xkcdnum) then -- Search for an xkcd
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
41 xkcdnum = xkcdnum:lower()
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
42 local xkcdpat = xkcdnum:gsub("[()]", function(s) return "%" .. s end)
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
43 :gsub("[%[]",function(s) return "%" .. s end)
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
44 :gsub("%%(%b[])",function(s) return (#s > 2 and "" or "%") .. s end);
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
45 local results = {};
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
46 for x, xkcd in pairs(xkcd_list) do
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
47 name = xkcd:lower()
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
48 if name == xkcdnum then -- exact match
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
49 return xkcd..", http://xkcd.org/"..x.."/";
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
50 elseif name:match(xkcdpat) then
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
51 table.insert(results, x);
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
52 --return commands.xkcd(msg, x);
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
53 end
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
54 end
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
55 if #results == 0 then
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
56 return "Sorry, I couldn't find a match";
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
57 elseif #results == 1 then
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
58 command.param = results[1];
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
59 return handle_xkcd_command(command);
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
60 else
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
61 -- We have more than one match
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
62 local ret = "Multiple matches:";
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
63 for _, x in ipairs(results) do
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
64 local xkcdnum = tostring(tonumber(x));
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
65 local xkcd = xkcd_list[tostring(x)];
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
66 ret = string.format("%s %s%s", ret, xkcd, ((_ < #results) and ",") or "");
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
67 if _ > 5 then ret = ret .. " " .. (#results - 5) .. " more"; break; end
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
68 end
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
69 return ret;
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
70 end
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
71 end
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
72 -- Check that xkcdnum is a valid number
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
73 xkcdnum = tostring(tonumber(xkcdnum));
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
74 if not xkcdnum then return "What XKCD strip number? Or enter a search string."; end
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
75 xkcd = xkcd_list[xkcdnum];
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
76 if not xkcd then return "Sorry, I don't think there is a XKCD #"..xkcdnum; end
00ad6fe8975e plugins.xkcd: reformat code
God of Dice@mf-nb
parents: 77
diff changeset
77 return xkcd..", http://xkcd.org/"..xkcdnum.."/";
57
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
78 end
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
79
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
80 function parse_xkcd_list(t)
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
81 if not t then return nil; end
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
82 for number, name in string.gmatch(t,"<a [^>]*href=\"/(%d+)/\"[^>]*>([^<]+)") do
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
83 xkcd_list[number] = name;
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
84 end
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
85 return true;
766f4225110b plugins.xkcd: New plugin, guess what it does ;)
Kim Alvefur <zash@zash.se>
parents:
diff changeset
86 end

mercurial