plugins/xkcd.lua

changeset 57
766f4225110b
child 62
0785a911fce9
equal deleted inserted replaced
56:cb7656ee4dd8 57:766f4225110b
1 local parse_xkcd_list;
2 local xkcd_list_updated_at = 0;
3 local xkcd_list = { };
4
5 function riddim.plugins.xkcd(bot)
6 require "net.httpclient_listener";
7 local http = require("net.http");
8 bot:hook("commands/xkcd", function(command)
9 if os.difftime(os.time(), xkcd_list_updated_at) > (3 * 60 * 60) then -- Not refreshed within 3 hours
10 http.request('http://xkcd.com/archive/', {
11 headers = { ["If-Modified-Since"] = os.date("!%a, %d %b %Y %T %Z", xkcd_list_updated_at or 0) }
12 }, function (data, code)
13 if code == 200 then
14 xkcd_list_updated_at = os.time();
15 print("debug", "got "..(#data or 0).." bytes of data");
16 parse_xkcd_list(data);
17 elseif code == 304 then
18 xkcd_list_updated_at = os.time();
19 else
20 if code > 0 then
21 command:reply("Received HTTP "..code.." error trying to fetch the XKCD archive");
22 else
23 command:reply("Unable to fetch the XKCD archive from xkcd.com: "..data:gsub("%-", " "));
24 end
25 return;
26 end
27 command:reply(handle_xkcd_command(command));
28 end);
29 else
30 return handle_xkcd_command(command);
31 end
32 end);
33 end
34
35 function handle_xkcd_command(command)
36 local xkcdnum = command.param;
37 if not xkcdnum then return "Please supply an XKCD number or a search string :)"; end
38 if not tonumber(xkcdnum) then -- Search for an xkcd
39 local results = {};
40 for x, xkcd in pairs(xkcd_list) do
41 name = " "..xkcd:lower().." ";
42 if name:match(xkcdnum:lower():gsub("%-", "%%-")) then
43 table.insert(results, x);
44 --return commands.xkcd(msg, x);
45 end
46 end
47 if #results == 0 then
48 return "Sorry, I couldn't find a match";
49 elseif #results == 1 then
50 command.param = results[1];
51 return handle_xkcd_command(command);
52 else
53 -- We have more than one match
54 local ret = "Multiple matches:";
55 for _, x in ipairs(results) do
56 local xkcdnum = tostring(tonumber(x));
57 local xkcd = xkcd_list[tostring(x)];
58 ret = string.format("%s %s%s", ret, xkcd, ((_ < #results) and ",") or "");
59 if _ > 5 then ret = ret .. " " .. (#results - 5) .. " more"; break; end
60 end
61 return ret;
62 end
63 end
64 -- Check that xkcdnum is a valid number
65 xkcdnum = tostring(tonumber(xkcdnum));
66 if not xkcdnum then return "What XKCD strip number? Or enter a search string."; end
67 xkcd = xkcd_list[xkcdnum];
68 if not xkcd then return "Sorry, I don't think there is a XKCD #"..xkcdnum; end
69 return xkcd..", http://xkcd.org/"..xkcdnum.."/";
70 end
71
72 function parse_xkcd_list(t)
73 if not t then return nil; end
74 for number, name in string.gmatch(t,"<a [^>]*href=\"/(%d+)/\"[^>]*>([^<]+)") do
75 xkcd_list[number] = name;
76 end
77 return true;
78 end

mercurial