This commit is contained in:
mrhanky 2017-05-16 12:06:29 +02:00
parent ad90fefd5e
commit 3845b28e0a
No known key found for this signature in database
GPG Key ID: 67D772C481CB41B8
13 changed files with 122 additions and 91 deletions

View File

@ -18,9 +18,9 @@
"nxy.plugins.bitcoin",
"nxy.plugins.ctcp",
"nxy.plugins.database",
"nxy.plugins.futures",
"nxy.plugins.mcmaniac",
"nxy.plugins.quotes",
"nxy.plugins.reminder",
"nxy.plugins.useless"
],
"irc3.plugins.command": {

View File

@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
from irc3.plugins.command import Commands
from irc3 import IrcBot
from irc3.plugins.command import Commands
MODULE = __name__

View File

@ -1,9 +1,10 @@
# -*- coding: utf-8 -*-
import irc3
from docopt import Dict as DocoptDict
from irc3 import IrcBot
from irc3.utils import IrcString
from irc3.plugins.command import command
import irc3
from irc3.utils import IrcString
from . import MODULE, Plugin

View File

@ -1,8 +1,9 @@
# -*- coding: utf-8 -*-
import irc3
from docopt import Dict as DocOptDict
from irc3.plugins.command import command
from irc3.utils import IrcString
import irc3
from . import Plugin
from ..utils import fmt, req

View File

@ -1,9 +1,10 @@
# -*- coding: utf-8 -*-
import irc3
import time
from docopt import Dict as DocOptDict
from irc3.plugins.command import command
from irc3.utils import IrcString
import time
import irc3
from . import Plugin
from ..utils import fmt

View File

@ -2,17 +2,22 @@
import sqlite3
import irc3
from irc3 import IrcBot
from . import Plugin
@irc3.plugin
class Database(Plugin):
def __init__(self, bot):
def __init__(self, bot: IrcBot):
super().__init__(bot)
file = bot.config.storage.split('sqlite://', 1)[1]
if not file:
raise ValueError('Invalid database: {}'.format(bot.config.storage))
self.db = sqlite3.connect(file)
# @formatter:off
self.db = sqlite3.connect(file, detect_types=sqlite3.PARSE_DECLTYPES
| sqlite3.PARSE_COLNAMES)
# @formatter:on
self.db.row_factory = sqlite3.Row
self.bot = bot
self.bot.con = self

69
nxy/plugins/futures.py Normal file
View File

@ -0,0 +1,69 @@
# -*- 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
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.restore()
def restore(self):
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))
@command
def timer(self, mask: IrcString, channel: IrcString, args: DocOptDict):
"""Timer command.
%%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))
else:
self.bot.notice(mask.nick, 'Invalid delay "{delay}" for "timer"'
.format(delay=args['<delay>']))
async def _timer(self, mask: IrcString, channel: IrcString,
delta: timedelta, message: str, delay: str, row_id: int):
"""
Actually the reminder function. Sleeps `delay` seconds and then sends
message to `channel` after that.
"""
seconds = delta.total_seconds()
if seconds > 0:
await asyncio.sleep(seconds)
text = fmt('{bold}[Reminder]{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()

View File

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
from docopt import Dict as DocOptDict
from irc3.utils import IrcString
from irc3.plugins.command import command
from irc3.utils import IrcString
from . import DatabasePlugin
from ..utils import parse_int
@ -25,15 +25,15 @@ class McManiac(DatabasePlugin):
if cmd and item:
if self.guard.has_permission(mask, 'admin'):
if cmd == 'add':
self.cur.execute('insert into mcmaniac (item) values (?)',
self.cur.execute('insert into mcmaniacs (item) values (?)',
[item])
if cmd == 'del':
index, order, op = parse_int(item, select=False)
if not index:
return
self.cur.execute('''delete from mcmaniac where id =
(select id from mcmaniac a where ? = (select count(id)
from mcmaniac b where a.id {op} b.id) order by id {order})
self.cur.execute('''delete from mcmaniacs where id =
(select id from mcmaniacs a where ? = (select count(id)
from mcmaniacs b where a.id {op} b.id) order by id {order})
'''.format(op=op, order=order), [index])
self.con.commit()
else:
@ -53,9 +53,9 @@ class McManiac(DatabasePlugin):
extra = ''
binds = []
self.cur.execute('''select item,
(select count(id) from mcmaniac b where a.id >= b.id) as idx,
(select count(id) from mcmaniac) as len
from mcmaniac a order by {order} limit 1 {extra}
(select count(id) from mcmaniacs b where a.id >= b.id) as idx,
(select count(id) from mcmaniasc) as len
from mcmaniacs a order by {order} limit 1 {extra}
'''.format(order=order, extra=extra), binds)
result = self.cur.fetchone()
if result:

View File

@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-
from docopt import Dict as DocOptDict
from irc3.utils import IrcString
from irc3.plugins.command import command
import irc3
import re
from docopt import Dict as DocOptDict
from irc3.plugins.command import command
from irc3.utils import IrcString
from . import DatabasePlugin
from ..utils import parse_int

View File

@ -1,41 +0,0 @@
# -*- coding: utf-8 -*-
from docopt import Dict as DocOptDict
from irc3.plugins.command import command
from irc3.utils import IrcString
import asyncio
import irc3
from . import Plugin
from ..utils import fmt, time_to_sec
@irc3.plugin
class Reminder(Plugin):
requires = [
'irc3.plugins.command',
]
@command
def remind(self, mask: IrcString, channel: IrcString, args: DocOptDict):
"""Remind command.
%%remind <delay> <message>...
"""
delay = time_to_sec(args['<delay>'])
if delay:
asyncio.ensure_future(self.timer(delay, mask, channel, args))
else:
self.bot.notice(mask.nick, 'Invalid delay "{delay}" for "remind"'
.format(delay=args['<delay>']))
async def timer(self, delay, mask: IrcString, channel: IrcString,
args: DocOptDict):
"""
Actually the reminder function. Sleeps `delay` seconds and then sends
message to `channel` after that.
"""
await asyncio.sleep(delay)
text = fmt('{bold}[Reminder]{reset} {nick}: {message} ({delay})',
message=' '.join(args['<message>']),
delay=args['<delay>'],
nick=mask.nick)
self.bot.privmsg(channel, text)

View File

@ -1,10 +1,11 @@
# -*- coding: utf-8 -*-
import irc3
import random
from docopt import Dict as DocOptDict
from irc3.dec import event
from irc3.plugins.command import command
from irc3.utils import IrcString
from irc3.dec import event
import random
import irc3
from . import Plugin
from ..utils import fmt

View File

@ -1,8 +1,9 @@
# -*- coding: utf-8 -*-
from requests import request, Response
import re
from datetime import timedelta
from pprint import pprint
import re
from requests import request, Response
# @formatter:off
COLORS = dict(
@ -62,14 +63,15 @@ async def req(method: str, url: str, **kwargs) -> Response:
def time_to_sec(text: str) -> int:
match = TIME_REGEX.match(text)
if match:
unit, num = match
return num * TIME_DICT[unit][1]
num, unit = match.groups()
return int(num) * TIME_DICT[unit][1]
def time_delta(text: str) -> timedelta:
match = TIME_REGEX.match(text)
if match:
unit, num = match
num, unit = match.groups()
num = int(num)
if unit == 'years':
num *= 52
return timedelta(**{TIME_DICT[unit][0]: num})
@ -80,31 +82,12 @@ def parse_int(val: str, select: bool = True) -> tuple:
val = int(val)
if val is not 0:
if val < 1:
order = 'desc'
order, op = 'desc', '<='
val *= -1
op = '<='
else:
order = 'asc'
op = '>='
order, op = 'asc', '>='
if select:
val -= 1
return val, order, op
except ValueError:
pass
def _parse_int(val: list) -> int:
"""
Parses an int from list, decremts by -1 if positiv.
Only returns if value from list is not 0.
"""
try:
val = int(''.join(val))
# Ignore val == 0
if val is not 0:
# Decrement to match list index
if val > 0:
val -= 1
return val
except ValueError:
pass

View File

@ -5,8 +5,18 @@ create table if not exists quotes (
unique (nick, item collate nocase)
);
create table if not exists mcmaniac (
create table if not exists mcmaniacs (
id integer primary key autoincrement,
item text not null,
unique (item collate nocase) on conflict replace
);
create table if not exists timers (
id integer primary key autoincrement,
mask text not null,
channel text not null,
message text not null,
delay text not null,
until timestamp not null,
created timestamp not null default current_timestamp
);