nxy/bot/plugins/timer.py

107 lines
3.4 KiB
Python
Raw Normal View History

2017-05-16 10:06:29 +00:00
# -*- coding: utf-8 -*-
import asyncio
2017-06-30 12:09:46 +00:00
from datetime import datetime, timedelta
2017-05-16 10:06:29 +00:00
2017-06-30 12:09:46 +00:00
import irc3
2017-05-16 10:06:29 +00:00
from docopt import Dict as DocOptDict
from irc3.plugins.command import command
from irc3.utils import IrcString
from psycopg2 import Error
2017-05-16 10:06:29 +00:00
from . import DatabasePlugin
2017-05-29 16:44:26 +00:00
from ..utils import time_delta
2017-05-16 10:06:29 +00:00
@irc3.plugin
class Timer(DatabasePlugin):
requires = ['irc3.plugins.command',
2017-07-07 00:11:20 +00:00
'bot.plugins.storage']
2017-05-16 10:06:29 +00:00
def __init__(self, bot: irc3.IrcBot):
2017-05-16 10:06:29 +00:00
super().__init__(bot)
2017-06-30 12:04:50 +00:00
# Fetch timers from database
self.cur.execute('''
select
id, mask, target, message, delay, ends_at
from
timers
''')
# Recreate timers
2017-05-16 10:06:29 +00:00
for res in self.cur.fetchall():
2017-06-30 12:04:50 +00:00
self.start_timer(IrcString(res['mask']),
res['target'],
res['message'],
res['delay'],
res['ends_at'] - datetime.now(),
res['id'])
2017-05-16 16:58:27 +00:00
2017-05-16 10:06:29 +00:00
@command
2017-06-29 21:26:07 +00:00
def timer(self, mask: IrcString, target: IrcString, args: DocOptDict):
2017-08-16 12:39:44 +00:00
"""Sets a timer, delay can be: s, m, h, d, w, mon, y
2017-05-16 11:44:39 +00:00
2017-05-16 10:06:29 +00:00
%%timer <delay> <message>...
"""
delay = args['<delay>']
delta = time_delta(delay)
2017-06-30 12:04:50 +00:00
if not delta:
self.bot.privmsg(target, 'Invalid timer delay')
else:
2017-05-16 10:06:29 +00:00
message = ' '.join(args['<message>'])
2017-06-30 12:04:50 +00:00
values = [mask, target, message, delay]
try:
# Insert into database (add now + delta)
self.cur.execute('''
insert into
timers (mask, target, message, delay, ends_at)
values
(%s, %s, %s, %s, %s)
returning id
''', values + [datetime.now() + delta])
self.con.commit()
# Add delta and id from inserted and start timer
values.extend([delta, self.cur.fetchone()['id']])
self.start_timer(*values)
# Send notice to user that timer has been set
self.bot.notice(mask.nick, 'Timer in {delay} set: {message}'
.format(delay=delay, message=message))
except Error:
# Rollback transaction on error
self.con.rollback()
2017-05-16 10:06:29 +00:00
2017-06-30 12:04:50 +00:00
def start_timer(self, mask: IrcString, target: IrcString, message: str,
delay: str, delta: timedelta, row_id: int):
2017-05-16 12:27:34 +00:00
"""Async function, sleeps for `delay` seconds and sends notification"""
2017-06-29 21:26:07 +00:00
2017-06-30 12:04:50 +00:00
async def callback():
# Sleep if necessary until timed
seconds = delta.total_seconds()
if seconds > 0:
await asyncio.sleep(seconds)
2017-06-29 21:26:07 +00:00
2017-06-30 12:04:50 +00:00
# Send reminder
self.bot.privmsg(target, '\x02[Timer]\x0F {nick}: {message} '
'({delay})'.format(message=message,
nick=mask.nick,
delay=delay))
try:
# Delete timer from database
self.cur.execute('''
delete from
timers
where
id = %s
''', [row_id])
self.con.commit()
except Error:
# Rollback transaction on error
self.con.rollback()
2017-06-29 21:26:07 +00:00
2017-06-30 12:04:50 +00:00
asyncio.ensure_future(callback())