mcbot/cmds/rfc.lua
changeset 31 71bf91612a33
child 32 96bce644394a
equal deleted inserted replaced
30:e5e20eed6c58 31:71bf91612a33
       
     1 #! /usr/bin/env lua
       
     2 
       
     3 -- RFC index parser
       
     4 -- Mikael BERTHE, 2010-04-17
       
     5 
       
     6 -- TXT index database, retrieved from
       
     7 -- <ftp://ftp.rfc-editor.org/in-notes/rfc-index.txt>
       
     8 local indexfname = "/home/mikael/.mcabber/lua/mcbot/rfc-index.txt"
       
     9 
       
    10 local rfc = { ["desc"] = "Search RFC database" }
       
    11 
       
    12 local rfcdb = {}
       
    13 
       
    14 local function parse_file (fname)
       
    15     local fh = io.open(fname)
       
    16 
       
    17     if not fh then
       
    18         print("Cannot open RFC database")
       
    19         return 255
       
    20     end
       
    21 
       
    22     -- Skip header
       
    23     local count = 0
       
    24     for line in fh:lines() do
       
    25         count = count + 1
       
    26         if line:match("^%s+RFC INDEX%s*$") and count > 30 then
       
    27             break
       
    28         end
       
    29     end
       
    30 
       
    31     -- Skip 2 more lines
       
    32     fh:read("*l")
       
    33     fh:read("*l")
       
    34 
       
    35     local contents = fh:read("*a")
       
    36     fh:close()
       
    37 
       
    38     for entry in contents:gfind("(%d%d%d%d .-)\n\n") do
       
    39         entry = entry:gsub("\n     ", " ")
       
    40         local n = entry:match("^(%d%d%d%d) ")
       
    41         entry = entry:gsub("^(%d%d%d%d) ", "")
       
    42 
       
    43         local data = {}
       
    44         data.title = entry:match("^(.-)%. ")
       
    45         entry = entry:gsub("^(.-)%. ", "")
       
    46 
       
    47         data.date = entry:match("%. (.-)%. %(Format:")
       
    48         data.obsoletes = entry:match("%(Obsoletes (.-)%)")
       
    49         data.obsoleted_by = entry:match("%(Obsoleted by (.-)%)")
       
    50         data.updates = entry:match("%(Updates (.-)%)")
       
    51         data.updated_by = entry:match("%(Updated by (.-)%)")
       
    52         data.also = entry:match("%(Also (.-)%)")
       
    53         data.status = entry:match("%(Status: (.-)%)")
       
    54 
       
    55         if data.title then
       
    56             rfcdb[n] = data
       
    57         end
       
    58     end
       
    59 end
       
    60 
       
    61 local function rfc_lookup_string (rfcstring)
       
    62     rfcstring = rfcstring:lower()
       
    63     local r = ""
       
    64     for id, data in pairs(rfcdb) do
       
    65         if data.title:lower():find(rfcstring) then
       
    66             r = r.."RFC"..id..": "..data.title.."\n"
       
    67         end
       
    68     end
       
    69     r = r:gsub("\n$", "")
       
    70     if r ~= "" then return r; end
       
    71     return nil, "Sorry, I couldn't find any relevant RFC"
       
    72 end
       
    73 
       
    74 local function rfc_lookup_number (rfcnum)
       
    75     rfcnum = tostring(rfcnum)
       
    76     rfcnum = string.rep("0", 4 - rfcnum:len()) .. rfcnum
       
    77 
       
    78     local data = rfcdb[rfcnum]
       
    79     if not data then return nil, "Sorry, RFC not found" end
       
    80 
       
    81     local r = "RFC"..rfcnum .. " is " .. data.title .. "\n"
       
    82     if data.status then
       
    83         r = r .. "Status:\t" .. data.status:lower() .. "\n"
       
    84     end
       
    85     if data.obsoletes then
       
    86         r = r .. "Obsoletes:\t" .. data.obsoletes .. "\n"
       
    87     end
       
    88     if data.obsoleted_by then
       
    89         r = r .. "Obsoleted by:\t" .. data.obsoleted_by .. "\n"
       
    90     end
       
    91     if data.updates then
       
    92         r = r .. "Updates:\t" .. data.updates .. "\n"
       
    93     end
       
    94     if data.updated_by then
       
    95         r = r .. "Updated by:\t" .. data.updated_by .. "\n"
       
    96     end
       
    97     if data.also then
       
    98         r = r .. "Also:\t" .. data.also .. "\n"
       
    99     end
       
   100     r = r:gsub("\n$", "")
       
   101     return r
       
   102 end
       
   103 
       
   104 function rfc.cmd (rfcnum)
       
   105     local empty = true
       
   106     for i,v in pairs(rfcdb) do empty = false; break end
       
   107     if empty then parse_file(indexfname) end
       
   108 
       
   109     if (rfcnum) then
       
   110         rfcnum = rfcnum:gsub("^RFC[%s%-]*", "")
       
   111         rfcnum = rfcnum:gsub("^rfc[%s%-]*", "")
       
   112         rfcnum = rfcnum:gsub("[!%?%s:]+$", "")
       
   113     end
       
   114 
       
   115     if not rfcnum or rfcnum == "" then
       
   116         return nil, "What RFC do you want?"
       
   117     end
       
   118 
       
   119     local n = tonumber(rfcnum)
       
   120     if not n then return rfc_lookup_string(rfcnum) end
       
   121 
       
   122     return rfc_lookup_number(n)
       
   123 end
       
   124 
       
   125 mcbot_register_command("rfc", rfc)