77 lines
		
	
	
		
			2.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			77 lines
		
	
	
		
			2.8 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
 | |
| import irc3
 | |
| 
 | |
| from . import DatabasePlugin
 | |
| from ..utils import time_delta
 | |
| 
 | |
| 
 | |
| @irc3.plugin
 | |
| class Timer(DatabasePlugin):
 | |
|     requires = ['irc3.plugins.command',
 | |
|                 'nxy.plugins.database']
 | |
| 
 | |
|     def __init__(self, bot: irc3.IrcBot):
 | |
|         super().__init__(bot)
 | |
|         # Restore timers from database
 | |
|         self.cur.execute('select id, nick, channel, message, delay, ends_at '
 | |
|                          'from timers')
 | |
|         for res in self.cur.fetchall():
 | |
|             delta = res['ends_at'] - datetime.now()
 | |
|             args = (IrcString(res['nick']), res['channel'], delta,
 | |
|                     res['message'], res['delay'], res['id'])
 | |
|             asyncio.ensure_future(self._timer(*args))
 | |
| 
 | |
|     @command
 | |
|     def timer(self, mask: IrcString, target: 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:
 | |
|             message = ' '.join(args['<message>'])
 | |
|             # Insert into database
 | |
|             self.cur.execute('insert into timers (nick, channel, message, '
 | |
|                              'delay, ends_at) values (%s, %s, %s, %s, %s)',
 | |
|                              [mask.nick, target.lower(), message, delay,
 | |
|                               datetime.now() + delta])
 | |
|             self.con.commit()
 | |
| 
 | |
|             # Get id from inserted and start timer
 | |
|             self.cur.execute('select lastval()')
 | |
|             lastid = self.cur.fetchone()['lastval']
 | |
|             asyncio.ensure_future(self._timer(mask, target, delta, message,
 | |
|                                               delay, lastid))
 | |
| 
 | |
|             # Send notice to user
 | |
|             self.bot.notice(mask.nick, 'Timer in {delay} set: {message}'
 | |
|                             .format(delay=delay, message=message))
 | |
|         else:
 | |
|             self.bot.privmsg(target, 'Invalid timer delay')
 | |
| 
 | |
|     async def _timer(self, mask: IrcString, target: IrcString, delta: timedelta,
 | |
|                      message: str, delay: str, row_id: int):
 | |
|         """Async function, sleeps for `delay` seconds and sends notification"""
 | |
|         seconds = delta.total_seconds()
 | |
| 
 | |
|         # Sleep if necessary until timed
 | |
|         if seconds > 0:
 | |
|             await asyncio.sleep(seconds)
 | |
| 
 | |
|         # Send reminder
 | |
|         self.bot.privmsg(target, '\x02[Timer]\x0F {nick}: {message} ({delay})'
 | |
|                          .format(message=message,
 | |
|                                  nick=mask.nick,
 | |
|                                  delay=delay))
 | |
| 
 | |
|         # Delete timer from database
 | |
|         self.cur.execute('delete from timers where id = %s', [row_id])
 | |
|         self.con.commit()
 |