sopel/modules/tell.py

175 lines
4.3 KiB
Python
Raw Normal View History

2017-11-22 19:26:40 -05:00
#! /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