plugins/xkcd.lua

changeset 89
5a573f1d7592
parent 78
00ad6fe8975e
child 97
a532667d596e
equal deleted inserted replaced
88:b7f628541981 89:5a573f1d7592
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

mercurial