5 function riddim.plugins.xkcd(bot) |
5 function riddim.plugins.xkcd(bot) |
6 require "net.httpclient_listener"; |
6 require "net.httpclient_listener"; |
7 local http = require("net.http"); |
7 local http = require("net.http"); |
8 bot:hook("commands/xkcd", function(command) |
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 |
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/', { |
10 --COMPAT We could have saved 6 bytes here, but Microsoft apparently hates %T, so you got this gigantic comment instead. |
11 headers = { ["If-Modified-Since"] = os.date("!%a, %d %b %Y %T %Z", xkcd_list_updated_at or 0) } |
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) |
12 }, function (data, code) |
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) |
13 if code == 200 then |
13 if code == 200 then |
14 xkcd_list_updated_at = os.time(); |
14 xkcd_list_updated_at = os.time(); |
15 print("debug", "got "..(#data or 0).." bytes of data"); |
15 print("debug", "got "..(#data or 0).." bytes of data"); |
16 parse_xkcd_list(data); |
16 parse_xkcd_list(data); |
17 elseif code == 304 then |
17 elseif code == 304 then |
31 end |
31 end |
32 end); |
32 end); |
33 end |
33 end |
34 |
34 |
35 function handle_xkcd_command(command) |
35 function handle_xkcd_command(command) |
36 local xkcdnum = command.param; |
36 local xkcdnum = command.param; |
37 if not xkcdnum then return "Please supply an XKCD number or a search string :)"; end |
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 |
38 if not tonumber(xkcdnum) then -- Search for an xkcd |
39 xkcdnum = xkcdnum:lower() |
39 xkcdnum = xkcdnum:lower() |
40 local xkcdpat = xkcdnum:gsub("[()]", function(s) return "%" .. s end) |
40 local xkcdpat = xkcdnum:gsub("[()]", function(s) return "%" .. s end) |
41 :gsub("[%[]",function(s) return "%" .. s end) |
41 :gsub("[%[]",function(s) return "%" .. s end) |
42 :gsub("%%(%b[])",function(s) return (#s > 2 and "" or "%") .. s end); |
42 :gsub("%%(%b[])",function(s) return (#s > 2 and "" or "%") .. s end); |
43 local results = {}; |
43 local results = {}; |
44 for x, xkcd in pairs(xkcd_list) do |
44 for x, xkcd in pairs(xkcd_list) do |
45 name = xkcd:lower() |
45 name = xkcd:lower() |
46 if name == xkcdnum then -- exact match |
46 if name == xkcdnum then -- exact match |
47 return xkcd..", http://xkcd.org/"..x.."/"; |
47 return xkcd..", http://xkcd.org/"..x.."/"; |
48 elseif name:match(xkcdpat) then |
48 elseif name:match(xkcdpat) then |
49 table.insert(results, x); |
49 table.insert(results, x); |
50 --return commands.xkcd(msg, x); |
50 --return commands.xkcd(msg, x); |
51 end |
51 end |
52 end |
52 end |
53 if #results == 0 then |
53 if #results == 0 then |
54 return "Sorry, I couldn't find a match"; |
54 return "Sorry, I couldn't find a match"; |
55 elseif #results == 1 then |
55 elseif #results == 1 then |
56 command.param = results[1]; |
56 command.param = results[1]; |
57 return handle_xkcd_command(command); |
57 return handle_xkcd_command(command); |
58 else |
58 else |
59 -- We have more than one match |
59 -- We have more than one match |
60 local ret = "Multiple matches:"; |
60 local ret = "Multiple matches:"; |
61 for _, x in ipairs(results) do |
61 for _, x in ipairs(results) do |
62 local xkcdnum = tostring(tonumber(x)); |
62 local xkcdnum = tostring(tonumber(x)); |
63 local xkcd = xkcd_list[tostring(x)]; |
63 local xkcd = xkcd_list[tostring(x)]; |
64 ret = string.format("%s %s%s", ret, xkcd, ((_ < #results) and ",") or ""); |
64 ret = string.format("%s %s%s", ret, xkcd, ((_ < #results) and ",") or ""); |
65 if _ > 5 then ret = ret .. " " .. (#results - 5) .. " more"; break; end |
65 if _ > 5 then ret = ret .. " " .. (#results - 5) .. " more"; break; end |
66 end |
66 end |
67 return ret; |
67 return ret; |
68 end |
68 end |
69 end |
69 end |
70 -- Check that xkcdnum is a valid number |
70 -- Check that xkcdnum is a valid number |
71 xkcdnum = tostring(tonumber(xkcdnum)); |
71 xkcdnum = tostring(tonumber(xkcdnum)); |
72 if not xkcdnum then return "What XKCD strip number? Or enter a search string."; end |
72 if not xkcdnum then return "What XKCD strip number? Or enter a search string."; end |
73 xkcd = xkcd_list[xkcdnum]; |
73 xkcd = xkcd_list[xkcdnum]; |
74 if not xkcd then return "Sorry, I don't think there is a XKCD #"..xkcdnum; end |
74 if not xkcd then return "Sorry, I don't think there is a XKCD #"..xkcdnum; end |
75 return xkcd..", http://xkcd.org/"..xkcdnum.."/"; |
75 return xkcd..", http://xkcd.org/"..xkcdnum.."/"; |
76 end |
76 end |
77 |
77 |
78 function parse_xkcd_list(t) |
78 function parse_xkcd_list(t) |
79 if not t then return nil; end |
79 if not t then return nil; end |
80 for number, name in string.gmatch(t,"<a [^>]*href=\"/(%d+)/\"[^>]*>([^<]+)") do |
80 for number, name in string.gmatch(t,"<a [^>]*href=\"/(%d+)/\"[^>]*>([^<]+)") do |