|
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 |