#! /usr/bin/env lua
-- This module is part of the McBot / mcabbot project
-- RFC index parser
--
-- Copyright (C) 2010-2012 Mikael Berthe <mikael@lilotux.net>
--
-- This program is free software; you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation; either version 2 of the License, or (at
-- your option) any later version.
--
-- Please check the license in the COPYING file at the root of the tree.
--
-- TXT index database, retrieved from
-- <ftp://ftp.rfc-editor.org/in-notes/rfc-index.txt>
local indexfname = "/home/mikael/.mcabber/lua/mcbot/rfc-index.txt"
local urlbase = "http://tools.ietf.org/html/rfc"
local rfc = { ["desc"] = "Search RFC database" }
local rfcdb = {}
local function parse_file (fname)
local fh = io.open(fname)
if not fh then return nil, "Cannot open RFC database" end
-- Skip header
local count = 0
for line in fh:lines() do
count = count + 1
if line:match("^%s+RFC INDEX%s*$") and count > 30 then
break
end
end
-- Skip 2 more lines
fh:read("*l")
fh:read("*l")
local contents = fh:read("*a")
fh:close()
for entry in contents:gfind("(%d%d%d%d .-)\n\n") do
entry = entry:gsub("\n ", " ")
local n = entry:match("^(%d%d%d%d) ")
entry = entry:gsub("^(%d%d%d%d) ", "")
local data = {}
data.title = entry:match("^(.-)%. ")
entry = entry:gsub("^(.-)%. ", "")
data.date = entry:match("%. (.-)%. %(Format:")
data.obsoletes = entry:match("%(Obsoletes (.-)%)")
data.obsoleted_by = entry:match("%(Obsoleted by (.-)%)")
data.updates = entry:match("%(Updates (.-)%)")
data.updated_by = entry:match("%(Updated by (.-)%)")
data.also = entry:match("%(Also (.-)%)")
data.status = entry:match("%(Status: (.-)%)")
if data.title then
rfcdb[n] = data
end
end
return true
end
local function rfc_lookup_string (rfcstring)
rfcstring = rfcstring:lower()
local r = ""
for id, data in pairs(rfcdb) do
if data.title:lower():find(rfcstring) then
r = r.."RFC"..id..": "..data.title.."\n"
end
end
r = r:gsub("\n$", "")
if r ~= "" then return r; end
return nil, "Sorry, I couldn't find any relevant RFC"
end
local function rfc_lookup_number (rfcnum)
rfcnum = tostring(rfcnum)
rfcnum = string.rep("0", 4 - rfcnum:len()) .. rfcnum
local data = rfcdb[rfcnum]
if not data then return nil, "Sorry, RFC not found" end
local r = "RFC"..rfcnum .. " is " .. data.title .. "\n"
if data.status then
r = r .. "Status:\t" .. data.status:lower() .. "\n"
end
if data.obsoletes then
r = r .. "Obsoletes:\t" .. data.obsoletes .. "\n"
end
if data.obsoleted_by then
r = r .. "Obsoleted by:\t" .. data.obsoleted_by .. "\n"
end
if data.updates then
r = r .. "Updates:\t" .. data.updates .. "\n"
end
if data.updated_by then
r = r .. "Updated by:\t" .. data.updated_by .. "\n"
end
if data.also then
r = r .. "Also:\t" .. data.also .. "\n"
end
r = r .. "URL:\t" .. urlbase..rfcnum
return r
end
function rfc.cmd (rfcnum)
local empty = true
for i,v in pairs(rfcdb) do empty = false; break end
if empty then
local r, err = parse_file(indexfname)
if not r then return nil, err end
end
if (rfcnum) then
rfcnum = rfcnum:gsub("^RFC[%s%-]*", "")
rfcnum = rfcnum:gsub("^rfc[%s%-]*", "")
rfcnum = rfcnum:gsub("[!%?%s:]+$", "")
end
if not rfcnum or rfcnum == "" then
return nil, "What RFC do you want?"
end
local n = tonumber(rfcnum)
if not n then return rfc_lookup_string(rfcnum) end
return rfc_lookup_number(n)
end
mcbot_register_command("rfc", rfc)