109 lines
4.1 KiB
Python
109 lines
4.1 KiB
Python
# -*- coding: utf-8 -*-
|
|
from datetime import datetime, timedelta
|
|
import asyncio
|
|
|
|
from docopt import Dict as DocOptDict
|
|
from irc3.plugins.command import command
|
|
from irc3.utils import IrcString
|
|
from irc3 import IrcBot, event
|
|
import irc3
|
|
|
|
from . import DatabasePlugin
|
|
from ..utils import fmt, time_delta
|
|
|
|
|
|
@irc3.plugin
|
|
class Futures(DatabasePlugin):
|
|
requires = [
|
|
'irc3.plugins.command',
|
|
'nxy.plugins.database',
|
|
]
|
|
|
|
def __init__(self, bot: IrcBot):
|
|
super().__init__(bot)
|
|
self.tell_queue = {}
|
|
# Restore timers from database
|
|
self.cur.execute('select * from timers')
|
|
for res in self.cur.fetchall():
|
|
delta = res['until'] - datetime.utcnow()
|
|
args = (IrcString(res['mask']), res['channel'], delta,
|
|
res['message'], res['delay'], res['id'])
|
|
asyncio.ensure_future(self._timer(*args))
|
|
# Restore tells from database
|
|
self.cur.execute('select * from tells')
|
|
for res in self.cur.fetchall():
|
|
user = res['user']
|
|
if user not in self.tell_queue:
|
|
self.tell_queue[user] = []
|
|
self.tell_queue[user].append(res)
|
|
|
|
@command
|
|
def timer(self, mask: IrcString, channel: IrcString, args: DocOptDict):
|
|
"""Sets a timer, delay can be: s, m, h, w, mon, y(
|
|
|
|
%%timer <delay> <message>...
|
|
"""
|
|
delay = args['<delay>']
|
|
delta = time_delta(delay)
|
|
if delta:
|
|
date = datetime.utcnow() + delta
|
|
message = ' '.join(args['<message>'])
|
|
self.cur.execute('''insert into timers (mask, channel, message,
|
|
delay, until) values (?, ?, ?, ?, ?)''', [mask.nick, channel,
|
|
message, delay, date])
|
|
self.con.commit()
|
|
asyncio.ensure_future(self._timer(mask, channel, delta, message,
|
|
delay, self.cur.lastrowid))
|
|
self.bot.notice(mask.nick, 'Timer in {delay} set: {message}'
|
|
.format(delay=delay, message=message))
|
|
else:
|
|
self.bot.privmsg(channel, 'Invalid timer delay')
|
|
|
|
# noinspection PyUnusedLocal
|
|
@command
|
|
def tell(self, mask: IrcString, channel: IrcString, args: DocOptDict):
|
|
"""Saves a message for nick to forward on activity
|
|
|
|
%%tell <nick> <message>...
|
|
"""
|
|
nick = args['<nick>']
|
|
message = ' '.join(args['<message>'])
|
|
if nick not in self.tell_queue:
|
|
self.tell_queue[nick] = []
|
|
self.cur.execute('insert into tells (mask, user, message) values '
|
|
'(?, ?, ?)', [mask, nick, message])
|
|
self.con.commit()
|
|
self.tell_queue[nick].append({
|
|
'id': self.cur.lastrowid,
|
|
'mask': mask,
|
|
'user': nick,
|
|
'message': message,
|
|
})
|
|
|
|
async def _timer(self, mask: IrcString, channel: IrcString,
|
|
delta: timedelta, message: str, delay: str, row_id: int):
|
|
"""Async function, sleeps for `delay` seconds and sends notification"""
|
|
seconds = delta.total_seconds()
|
|
if seconds > 0:
|
|
await asyncio.sleep(seconds)
|
|
text = fmt('{bold}[Timer]{reset} {nick}: {message} ({delay})',
|
|
message=message, delay=delay, nick=mask.nick)
|
|
self.bot.privmsg(channel, text)
|
|
self.cur.execute('delete from timers where id = ?', [row_id])
|
|
self.con.commit()
|
|
|
|
@event(r'(?i)^:(?P<mask>.*) PRIVMSG .* :.*')
|
|
def tell_check(self, mask: str):
|
|
nick = IrcString(mask).nick
|
|
if nick in self.tell_queue:
|
|
ids = []
|
|
for tell in self.tell_queue[nick]:
|
|
ids.append(tell['id'])
|
|
self.bot.privmsg(nick, '[Tell] Message from {nick}: {message}'
|
|
.format(nick=IrcString(tell['mask']).nick,
|
|
message=tell['message']))
|
|
del self.tell_queue[nick]
|
|
self.cur.execute('delete from tells where id in ({})'
|
|
.format(', '.join('?' * len(ids))), ids)
|
|
self.con.commit()
|