|
1 --local bugs = {}; |
|
2 local s_match = string.match; |
|
3 local t_insert = table.insert; |
|
4 local to_json = require "json".encode; |
|
5 |
|
6 function riddim.plugins.trac(bot) |
|
7 local trac = bot.config.trac; |
|
8 if not trac then return end |
|
9 |
|
10 --require "net.httpclient_listener"; |
|
11 local http = --require("net.http"); |
|
12 { request = function(url, iduno, callback) |
|
13 local data = io.popen("curl -s " .. url):read("*a"); |
|
14 return callback(data, 200); |
|
15 end; } |
|
16 |
|
17 bot:hook("commands/ticket", function(command) |
|
18 if not command.param then return end |
|
19 local bug_id = s_match(command.param, "%d+"); |
|
20 if not bug_id then return end |
|
21 local format = s_match(command.param, "%w+$"); |
|
22 local url = trac .. '/ticket/' .. bug_id; |
|
23 http.request(url .. '?format=csv', nil, function (data, code) |
|
24 if code ~= 200 then return end |
|
25 if data:sub(1,3) ~= "id," then return end |
|
26 local ticket = map_table(parse_csv(data)); |
|
27 command:reply( |
|
28 format == "raw" and to_json(ticket) or |
|
29 ticket[format] or |
|
30 ( ticket.component .. " / " |
|
31 .. ticket.summary .. ": " |
|
32 .. (ticket.status == "closed" |
|
33 and ticket.resolution |
|
34 or ticket.status == "assigned" and "" |
|
35 or ticket.status) .. " " |
|
36 .. ticket.priority .. " " |
|
37 .. ticket.type .. |
|
38 ( ticket.status == "assigned" |
|
39 and " assigned till ".. ticket.owner or "") |
|
40 .. " - <" .. url .. ">" |
|
41 )); |
|
42 end); |
|
43 end); |
|
44 end |
|
45 |
|
46 function parse_csv(s) |
|
47 s = s -- ending comma |
|
48 local t, l = {{}}, 1 -- table to collect fields |
|
49 local fieldstart = 1 |
|
50 repeat |
|
51 -- next field is quoted? (start with `"'?) |
|
52 if string.find(s, '^"', fieldstart) then |
|
53 local a, c |
|
54 local i = fieldstart |
|
55 repeat |
|
56 -- find closing quote |
|
57 a, i, c = string.find(s, '"("?)', i+1) |
|
58 until c ~= '"' -- quote not followed by quote? |
|
59 if not i then error('unmatched "') end |
|
60 local f = string.sub(s, fieldstart+1, i-1) |
|
61 if not t[l] then t[l] = {} end |
|
62 table.insert(t[l], (string.gsub(f, '""', '"'))) |
|
63 fieldstart = string.find(s, ',', i) + 1 |
|
64 else -- unquoted; find next comma |
|
65 local nexti = math.min(string.find(s, ',', fieldstart) or #s, string.find(s, "\r\n", fieldstart) or #s) |
|
66 if not t[l] then t[l] = {} end |
|
67 table.insert(t[l], string.sub(s, fieldstart, nexti-1)) |
|
68 if string.sub(s, nexti, nexti +1) == "\r\n" then l = l + 1; nexti = nexti +1 end |
|
69 fieldstart = nexti + 1 |
|
70 end |
|
71 until fieldstart > string.len(s) |
|
72 return t |
|
73 end |
|
74 |
|
75 function map_table(t) |
|
76 local ret = {}; |
|
77 if not t[1] then return nil end |
|
78 if not t[2] then return nil end |
|
79 |
|
80 for i,v in ipairs(t[1]) do |
|
81 ret[t[1][i]] = t[2][i] or ""; |
|
82 end |
|
83 return ret |
|
84 end |
|
85 |