#! /usr/bin/env python3 # -*- coding: utf-8 -*- """ Leave a message for someone. """ import os from datetime import datetime import threading import sys from tools import Identifier, iterkeys from tools.time import get_timezone, format_time, relativeTime from module import commands, nickname_commands, rule, priority, example maximum = 40 def loadReminders(fname, lock): lock.acquire() try: result = {} f = open(fname) for line in f: line = line.strip() if sys.version_info.major < 3: line = line.decode('utf-8') if line: try: tellee, teller, timenow, msg = line.split('\t', 4) except ValueError: continue # @@ hmm result.setdefault(tellee, []).append((teller, timenow, msg)) f.close() finally: lock.release() return result def dumpReminders(fname, data, lock): lock.acquire() try: f = open(fname, 'w') for tellee in iterkeys(data): for remindon in data[tellee]: line = '\t'.join((tellee,) + remindon) try: to_write = line + '\n' if sys.version_info.major < 3: to_write = to_write.encode('utf-8') f.write(to_write) except IOError: break try: f.close() except IOError: pass finally: lock.release() return True def setup(bot): fname = bot.nick + '-' + bot.config.core.host + '.tell.db' bot.tell_filename = os.path.join(bot.config.core.homedir, fname) if not os.path.exists(bot.tell_filename): try: f = open(bot.tell_filename, 'w') except OSError: pass else: f.write('') f.close() bot.memory['tell_lock'] = threading.Lock() bot.memory['reminders'] = loadReminders(bot.tell_filename, bot.memory['tell_lock']) @commands('tell') @example('.tell Embolalia you broke something again.') def f_remind(bot, trigger): """Give someone a message the next time they're seen""" teller = trigger.nick if not trigger.group(3): bot.reply("Tell whom?") return tellee = trigger.group(3).rstrip('.,:;') msg = trigger.group(2).lstrip(tellee).lstrip() if not msg: bot.reply("Tell %s what?" % tellee) return tellee = Identifier(tellee) if not os.path.exists(bot.tell_filename): return if len(tellee) > 20: return bot.reply('That nickname is too long.') if tellee == bot.nick: return bot.reply("I'm here now, you can tell me whatever you want!") if not tellee in (Identifier(teller), bot.nick, 'me'): tz = get_timezone(bot.db, bot.config, None, tellee) timenow = format_time(bot.db, bot.config, tz, tellee) bot.memory['tell_lock'].acquire() try: if not tellee in bot.memory['reminders']: bot.memory['reminders'][tellee] = [(teller, timenow, msg)] else: bot.memory['reminders'][tellee].append((teller, timenow, msg)) finally: bot.memory['tell_lock'].release() response = "I'll pass that on when %s is around." % tellee bot.reply(response) elif Identifier(teller) == tellee: bot.say('You can tell yourself that.') else: bot.say("Hey, I'm not as stupid as Monty you know!") dumpReminders(bot.tell_filename, bot.memory['reminders'], bot.memory['tell_lock']) # @@ tell def getReminders(bot, channel, key, tellee): lines = [] template = "%s: \x0310%s\x03 (\x0308%s\x03) %s [\x0312%s\x03]" bot.memory['tell_lock'].acquire() try: for (teller, telldate, msg) in bot.memory['reminders'][key]: lines.append(template % (tellee, msg, teller, telldate, relativeTime(bot, tellee, telldate))) try: del bot.memory['reminders'][key] except KeyError: bot.msg(channel, 'Er...') finally: bot.memory['tell_lock'].release() return lines @rule('(.*)') @priority('low') def message(bot, trigger): tellee = trigger.nick channel = trigger.sender if not os.path.exists(bot.tell_filename): return reminders = [] remkeys = list(reversed(sorted(bot.memory['reminders'].keys()))) for remkey in remkeys: if not remkey.endswith('*') or remkey.endswith(':'): if tellee == remkey: reminders.extend(getReminders(bot, channel, remkey, tellee)) elif tellee.startswith(remkey.rstrip('*:')): reminders.extend(getReminders(bot, channel, remkey, tellee)) for line in reminders[:maximum]: bot.say(line) if reminders[maximum:]: bot.say('Further messages sent privately') for line in reminders[maximum:]: bot.msg(tellee, line) if len(bot.memory['reminders'].keys()) != remkeys: dumpReminders(bot.tell_filename, bot.memory['reminders'], bot.memory['tell_lock']) # @@ tell