aboutsummaryrefslogtreecommitdiff
path: root/plugins/zyklonb/seen
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/zyklonb/seen')
-rwxr-xr-xplugins/zyklonb/seen160
1 files changed, 0 insertions, 160 deletions
diff --git a/plugins/zyklonb/seen b/plugins/zyklonb/seen
deleted file mode 100755
index 8fc9c82..0000000
--- a/plugins/zyklonb/seen
+++ /dev/null
@@ -1,160 +0,0 @@
-#!/usr/bin/env lua
---
--- ZyklonB seen plugin
---
--- Copyright 2016 Přemysl Eric Janouch <p@janouch.name>
--- See the file LICENSE for licensing information.
---
-
-function parse (line)
- local msg = { params = {} }
- line = line:match ("[^\r]*")
- for start, word in line:gmatch ("()([^ ]+)") do
- local colon = word:match ("^:(.*)")
- if start == 1 and colon then
- msg.prefix = colon
- elseif not msg.command then
- msg.command = word
- elseif colon then
- table.insert (msg.params, line:sub (start + 1))
- break
- elseif start ~= #line then
- table.insert (msg.params, word)
- end
- end
- return msg
-end
-
-function get_config (name)
- io.write ("ZYKLONB get_config :", name, "\r\n")
- return parse (io.read ()).params[1]
-end
-
--- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-io.output ():setvbuf ('line')
-local prefix = get_config ('prefix')
-io.write ("ZYKLONB register\r\n")
-
-local db = {}
-local db_filename = "seen.db"
-local db_garbage = 0
-
-function remember (who, where, when, what)
- if not db[who] then db[who] = {} end
- if db[who][where] then db_garbage = db_garbage + 1 end
- db[who][where] = { tonumber (when), what }
-end
-
--- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-local db_file, e = io.open (db_filename, "a+")
-if not db_file then error ("cannot open database: " .. e, 0) end
-
-function db_store (who, where, when, what)
- db_file:write (string.format
- (":%s %s %s %s :%s\n", who, "PRIVMSG", where, when, what))
-end
-
-function db_compact ()
- db_file:close ()
-
- -- Unfortunately, default Lua doesn't have anything like mkstemp()
- local db_tmpname = db_filename .. "." .. os.time ()
- db_file, e = io.open (db_tmpname, "a+")
- if not db_file then error ("cannot save database: " .. e, 0) end
-
- for who, places in pairs (db) do
- for where, data in pairs (places) do
- db_store (who, where, data[1], data[2])
- end
- end
- db_file:flush ()
-
- local ok, e = os.rename (db_tmpname, db_filename)
- if not ok then error ("cannot save database: " .. e, 0) end
- db_garbage = 0
-end
-
-for line in db_file:lines () do
- local msg = parse (line)
- remember (msg.prefix, table.unpack (msg.params))
-end
-
--- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-
-function seen (who, where, args)
- local respond = function (...)
- local privmsg = function (target, ...)
- io.write ("PRIVMSG ", target, " :", table.concat { ... }, "\r\n")
- end
- if where:match ("^[#&!+]") then
- privmsg (where, who, ": ", ...)
- else
- privmsg (who, ...)
- end
- end
-
- local whom, e, garbage = args:match ("^(%S+)()%s*(.*)")
- if not whom or #garbage ~= 0 then
- return respond ("usage: <name>")
- elseif who:lower () == whom:lower () then
- return respond ("I can see you right now.")
- end
-
- local top = {}
- -- That is, * acts like a wildcard, otherwise everything is escaped
- local pattern = "^" .. whom:gsub ("[%^%$%(%)%%%.%[%]%+%-%?]", "%%%0")
- :gsub ("%*", ".*"):lower () .. "$"
- for name, places in pairs (db) do
- if places[where] and name:lower ():match (pattern) then
- local when, what = table.unpack (places[where])
- table.insert (top, { name = name, when = when, what = what })
- end
- end
- if #top == 0 then
- return respond ("I have not seen \x02" .. whom .. "\x02 here.")
- end
-
- -- Get all matching nicknames ordered from the most recently active
- -- and make the list case insensitive (remove older duplicates)
- table.sort (top, function (a, b) return a.when > b.when end)
- for i = #top, 2, -1 do
- if top[i - 1].name:lower () == top[i].name:lower () then
- table.remove (top, i)
- end
- end
-
- -- Hopefully the formatting mess will disrupt highlights in clients
- for i = 1, math.min (#top, 3) do
- local name = top[i].name:gsub ("^.", "%0\x02\x02")
- respond (string.format ("\x02%s\x02 -> %s -> %s",
- name, os.date ("%c", top[i].when), top[i].what))
- end
-end
-
-function handle (msg)
- local who = msg.prefix:match ("^[^!@]*")
- local where, what = table.unpack (msg.params)
- local when = os.time ()
-
- local what_log = what:gsub ("^\x01ACTION", "*"):gsub ("\x01$", "")
- remember (who, where, when, what_log)
- db_store (who, where, when, what_log)
-
- -- Comment out to reduce both disk load and reliability
- db_file:flush ()
-
- if db_garbage > 5000 then db_compact () end
-
- if what:sub (1, #prefix) == prefix then
- local command = what:sub (#prefix + 1)
- local name, e = command:match ("^(%S+)%s*()")
- if name == 'seen' then seen (who, where, command:sub (e)) end
- end
-end
-
-for line in io.lines () do
- local msg = parse (line)
- if msg.command == "PRIVMSG" then handle (msg) end
-end