#!/usr/bin/env python3 """ When was this user last seen. """ import time import threading from datetime import datetime from sqlite3 import OperationalError from tools.time import relativeTime from module import commands, example, hook, require_chanmsg def load_database(bot): """ Loads all entries from the 'seen' table in the bot's database and returns them. """ data = {} seens = bot.db.execute("SELECT * FROM seen").fetchall() for seen in seens: nick, timestamp, channel, message = seen seen = (timestamp, channel, message) data[nick] = seen return data def setup(bot): bot.memory["seen_lock"] = threading.Lock() bot.memory["seen"] = load_database(bot) bot.memory["seen_last_dump"] = time.time() con = bot.db.connect() cur = con.cursor() try: cur.execute("SELECT * FROM seen").fetchone() except OperationalError: cur.execute("CREATE TABLE seen(" "nick TEXT PRIMARY KEY," "timestamp INTEGER," "channel TEXT," "message TEXT)") con.commit() con.close() @commands('seen') @example(".seen Nigger -l", "Last heard from Nigger at [1997-03-12 16:30:00] "\ +"with \"Just going to the store for some smokes babe I'll be right back\"") @example(".seen Soma_QM", "I haven't seen Soma_QM") def seen(bot, trigger): """Reports when and where the user was last seen.""" nick = trigger.group(3) last = False if nick == "-l" or nick == "--last": last = True nick = trigger.group(4) if not nick: return bot.say("Seen who?") if nick == bot.nick: return bot.reply("I'm right here!") if nick in bot.memory["seen"]: timestamp, channel, message = bot.memory["seen"][nick] else: return bot.msg(f"I haven't seen \x0308{nick}") timestamp = datetime.fromtimestamp(timestamp) t_format = bot.config.core.default_time_format timestamp = datetime.strftime(timestamp, t_format) reltime = relativeTime(bot.config, datetime.now(), timestamp) msg = f"Last heard from \x0308{nick}\x03 at {timestamp} " \ + f"(\x0312{reltime} ago\x03) in \x0312{channel}" if last: msg += f'\x03 with "\x0308{message}\x03"' bot.say(msg) def dump_seen_db(bot): """ Dumps the seen database into the bot's database. """ bot.memory["seen_lock"].acquire() for nick, seen in bot.memory["seen"].items(): bot.db.execute("INSERT OR REPLACE INTO seen " "(nick, timestamp, channel, message) VALUES (?, ?, ?, ?)", (nick,) + seen) bot.memory["seen_lock"].release() @hook(True) @require_chanmsg def seen_hook(bot, trigger): seen = (time.time(), trigger.channel, trigger.group(0)) bot.memory["seen"][trigger.nick] = seen if time.time() - bot.memory["seen_last_dump"] > 60: # only dump once a minute at most dump_seen_db(bot) bot.memory["seen_last_dump"] = time.time()