Quotes in sqlite

This commit is contained in:
mrhanky 2017-05-16 08:54:47 +02:00
parent cb8011aa67
commit c17df31655
No known key found for this signature in database
GPG Key ID: 67D772C481CB41B8
9 changed files with 94 additions and 97 deletions

View File

@ -1,5 +1,4 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import sqlite3
import json import json
import sys import sys
import os import os
@ -24,7 +23,7 @@ CFG_DEV = {
} }
# TODO: imdb, youtube, intensifies, pay, owe, rape (owe), ddg, regex, tell # TODO: imdb, youtube, pay, owe, rape (owe), ddg, regex, tell
def main(cfg_file): def main(cfg_file):
load_dotenv('.env') load_dotenv('.env')
with open(cfg_file, 'r') as fp: with open(cfg_file, 'r') as fp:

View File

@ -1,4 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from irc3.plugins.command import Commands
from irc3 import IrcBot from irc3 import IrcBot
MODULE = __name__ MODULE = __name__
@ -8,6 +9,7 @@ class BasePlugin(object):
def __init__(self, bot: IrcBot): def __init__(self, bot: IrcBot):
self.bot = bot self.bot = bot
self.log = bot.log self.log = bot.log
self.guard = bot.get_plugin(Commands).guard
class Plugin(BasePlugin): class Plugin(BasePlugin):

View File

@ -16,8 +16,7 @@ class Bitcoin(Plugin):
] ]
@command @command
async def btc(self, mask: IrcString, channel: IrcString, async def btc(self, mask: IrcString, channel: IrcString, args: DocOptDict):
args: DocOptDict) -> str:
"""Bitcoin command. """Bitcoin command.
%%btc %%btc
""" """

View File

@ -19,7 +19,7 @@ class CTCP(Plugin):
'irc3.plugins.command', 'irc3.plugins.command',
] ]
async def ctcp(self, ctcp: str, mask: IrcString, args: DocOptDict) -> str: async def ctcp(self, ctcp: str, mask: IrcString, args: DocOptDict):
nick = args.get('<nick>') or mask.nick nick = args.get('<nick>') or mask.nick
name = ctcp.upper() name = ctcp.upper()
ctcp = await self.bot.ctcp_async(nick, name, timeout=self.TIMEOUT) ctcp = await self.bot.ctcp_async(nick, name, timeout=self.TIMEOUT)
@ -36,7 +36,7 @@ class CTCP(Plugin):
@command @command
async def ping(self, mask: IrcString, channel: IrcString, async def ping(self, mask: IrcString, channel: IrcString,
args: DocOptDict) -> str: args: DocOptDict):
"""CTCP ping command. """CTCP ping command.
%%ping [<nick>] %%ping [<nick>]
""" """
@ -58,7 +58,7 @@ class CTCP(Plugin):
@command @command
async def finger(self, mask: IrcString, channel: IrcString, async def finger(self, mask: IrcString, channel: IrcString,
args: DocOptDict) -> str: args: DocOptDict):
"""CTCP finger command. """CTCP finger command.
%%finger [<nick>] %%finger [<nick>]
""" """
@ -66,15 +66,14 @@ class CTCP(Plugin):
@command @command
async def time(self, mask: IrcString, channel: IrcString, async def time(self, mask: IrcString, channel: IrcString,
args: DocOptDict) -> str: args: DocOptDict):
"""CTCP time command. """CTCP time command.
%%time [<nick>] %%time [<nick>]
""" """
return await self.ctcp('TIME', mask, args) return await self.ctcp('TIME', mask, args)
@command @command
async def ver(self, mask: IrcString, channel: IrcString, async def ver(self, mask: IrcString, channel: IrcString, args: DocOptDict):
args: DocOptDict) -> str:
"""CTCP version command. """CTCP version command.
%%ver [<nick>] %%ver [<nick>]
""" """

View File

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from docopt import Dict as DocOptDict from docopt import Dict as DocOptDict
from irc3.utils import IrcString from irc3.utils import IrcString
from irc3.plugins.command import command, Commands from irc3.plugins.command import command
from . import DatabasePlugin from . import DatabasePlugin
from ..utils import parse_int from ..utils import parse_int
@ -22,14 +22,13 @@ class McManiac(DatabasePlugin):
""" """
cmd = args.get('<cmd>') cmd = args.get('<cmd>')
item = args.get('<mcmaniac>') item = args.get('<mcmaniac>')
guard = self.bot.get_plugin(Commands).guard
if cmd and item: if cmd and item:
if guard.has_permission(mask, 'admin'): if self.guard.has_permission(mask, 'admin'):
if cmd == 'add': if cmd == 'add':
self.cur.execute('insert into mcmaniac (item) values (?)', self.cur.execute('insert into mcmaniac (item) values (?)',
[item]) [item])
if cmd == 'del': if cmd == 'del':
order, index, op = parse_int(item, select=False) index, order, op = parse_int(item, select=False)
if not index: if not index:
return return
self.cur.execute('''delete from mcmaniac where id = self.cur.execute('''delete from mcmaniac where id =
@ -45,7 +44,7 @@ class McManiac(DatabasePlugin):
index = parse_int(index) index = parse_int(index)
if not index: if not index:
return return
order, index, _ = index index, order, _ = index
order = 'id {order}'.format(order=order) order = 'id {order}'.format(order=order)
extra = 'offset ?' extra = 'offset ?'
binds = [index] binds = [index]
@ -58,6 +57,6 @@ class McManiac(DatabasePlugin):
(select count(id) from mcmaniac) as len (select count(id) from mcmaniac) as len
from mcmaniac a order by {order} limit 1 {extra} from mcmaniac a order by {order} limit 1 {extra}
'''.format(order=order, extra=extra), binds) '''.format(order=order, extra=extra), binds)
item = self.cur.fetchone() result = self.cur.fetchone()
if item: if result:
return '[{idx}/{len}] {item}'.format(**item) return '[{idx}/{len}] {item}'.format(**result)

View File

@ -2,7 +2,6 @@
from docopt import Dict as DocOptDict from docopt import Dict as DocOptDict
from irc3.utils import IrcString from irc3.utils import IrcString
from irc3.plugins.command import command from irc3.plugins.command import command
import random
import irc3 import irc3
import re import re
@ -20,42 +19,53 @@ class Quotes(DatabasePlugin):
# noinspection PyUnusedLocal # noinspection PyUnusedLocal
@command(options_first=True) @command(options_first=True)
def q(self, mask: IrcString, channel: IrcString, args: DocOptDict) -> str: def q(self, mask: IrcString, channel: IrcString, args: DocOptDict):
""" """
Manage quotes. Manage quotes.
%%q <cmd> <nick> <quote>... %%q <cmd> <nick> <quote>...
%%q <nick> [<quote>...] %%q <nick> [<index>]
""" """
cmd = args.get('<cmd>') cmd = args.get('<cmd>')
nick = args['<nick>'] nick = args['<nick>']
quote = args.get('<quote>') item = args.get('<quote>')
if cmd: print(cmd, nick, item)
if cmd == 'add': if cmd and item:
nick = self.REGEX.match(nick).group(1) if self.guard.has_permission(mask, 'admin'):
if nick not in self.db: if cmd == 'add':
self.db[nick] = [] nick = self.REGEX.match(nick).group(1)
quote = ' '.join(quote) self.cur.execute('insert into quotes (nick, item) '
if quote not in self.db[nick]: 'values (?, ?)', [nick, ' '.join(item)])
self.db[nick].append(quote) if cmd == 'del':
elif cmd == 'del': index, order, op = parse_int(''.join(item), select=False)
try: if not index:
self.db[nick].pop(parse_int(quote)) return
if not self.db[nick]: self.cur.execute('''delete from quotes where id =
del self.db[nick] (select id from quotes a where nick like ? and ? =
except (KeyError, IndexError, TypeError): (select count(id) from quotes b where a.id {op} b.id)
return '' order by id {order})
self._db.SIGINT() '''.format(op=op, order=order), [nick, index])
else: self.con.commit()
if quote:
try:
quote = self.db[nick][parse_int(quote)]
except (KeyError, IndexError, TypeError):
return ''
else: else:
quote = random.choice(self.db[nick]) self.bot.notice(mask.nick, 'Permission denied')
return '[{index}/{total}] <{nick}> {quote}'.format( else:
index=self.db[nick].index(quote) + 1, index = args.get('<index>')
total=len(self.db[nick]), binds = [nick]
nick=nick, if index:
quote=quote, index = parse_int(index)
) if not index:
return
index, order, _ = index
order = 'id {order}'.format(order=order)
extra = 'offset ?'
binds.append(index)
else:
order = 'random()'
extra = ''
self.cur.execute('''select nick, item,
(select count(id) from quotes b where a.id >= b.id) as idx,
(select count(id) from quotes) as len
from quotes a where nick like ? order by {order} limit 1 {extra}
'''.format(order=order, extra=extra), binds)
result = self.cur.fetchone()
if result:
return '[{idx}/{len}] <{nick}> {item}'.format(**result)

View File

@ -56,9 +56,10 @@ class Useless(Plugin):
self.bot.privmsg(channel, face) self.bot.privmsg(channel, face)
@command @command
def jn(self, mask: IrcString, channel: IrcString, args: DocOptDict) -> str: def jn(self, mask: IrcString, channel: IrcString, args: DocOptDict):
"""Yes or no command. """Yes or no command.
%%jn <question> %%jn <question>
%%jn
""" """
choice = random.choice(['{green}Ja', '{maroon}Nein']) choice = random.choice(['{green}Ja', '{maroon}Nein'])
return fmt('{nick}: {bold}{color}%s' % choice, nick=mask.nick) return fmt('{nick}: {bold}{color}%s' % choice, nick=mask.nick)
@ -82,8 +83,7 @@ class Useless(Plugin):
nick=args['<nick>']) nick=args['<nick>'])
@command @command
def hack(self, mask: IrcString, channel: IrcString, def hack(self, mask: IrcString, channel: IrcString, args: DocOptDict):
args: DocOptDict) -> str:
"""Hack command. """Hack command.
%%hack [<nick>] %%hack [<nick>]
""" """
@ -93,16 +93,14 @@ class Useless(Plugin):
return 'hacking{nick}...'.format(nick=nick) return 'hacking{nick}...'.format(nick=nick)
@command @command
def gay(self, mask: IrcString, channel: IrcString, def gay(self, mask: IrcString, channel: IrcString, args: DocOptDict):
args: DocOptDict) -> str:
"""Gay command (alias to rainbow). """Gay command (alias to rainbow).
%%gay <word>... %%gay <word>...
""" """
return self.rainbow(mask, channel, args) return self.rainbow(mask, channel, args)
@command @command
def rainbow(self, mask: IrcString, channel: IrcString, def rainbow(self, mask: IrcString, channel: IrcString, args: DocOptDict):
args: DocOptDict) -> str:
"""Rainbow command. """Rainbow command.
%%rainbow <word>... %%rainbow <word>...
""" """
@ -116,8 +114,7 @@ class Useless(Plugin):
return fmt(''.join(word)) return fmt(''.join(word))
@command @command
def wrainbow(self, mask: IrcString, channel: IrcString, def wrainbow(self, mask: IrcString, channel: IrcString, args: DocOptDict):
args: DocOptDict) -> str:
"""Word Rainbow command. """Word Rainbow command.
%%wrainbow <words>... %%wrainbow <words>...
""" """

View File

@ -1,5 +1,6 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from requests import request, Response from requests import request, Response
from datetime import timedelta
from pprint import pprint from pprint import pprint
import re import re
@ -30,27 +31,21 @@ FORMATTING = dict(
underline='\x1F', # underlined text underline='\x1F', # underlined text
swap='\x16', # swap bg and fg colors ("reverse video") swap='\x16', # swap bg and fg colors ("reverse video")
reset='\x0F', # reset all formatting reset='\x0F', # reset all formatting
# COLORS
# white='\x0300', # white
# black='\x0301', # black
# blue='\x0302', # blue (navy)
# green='\x0303', # green
# red='\x0304', # red
# maroon='\x0305', # brown (maroon)
# purple='\x0306', # purple
# orange='\x0307', # orange (olive)
# yellow='\x0308', # yellow
# ltgreen='\x0309', # light green (lime)
# teal='\x0310', # teal (a green/blue cyan)
# ltcyan='\x0311', # light cyan (cyan / aqua)
# ltblue='\x0312', # light blue (royal)
# pink='\x0313', # pink (light purple / fuchsia)
# grey='\x0314', # grey
# ltgrey='\x0315', # light grey (silver)
**COLORS **COLORS
) )
# @formatter:on # @formatter:on
TIME_REGEX = re.compile(r'(\d+)([smhdwy])')
TIME_DICT = {
's': ['seconds', 1],
'm': ['minutes', 60],
'h': ['hours', 3600],
'd': ['days', 86400],
'w': ['weeks', 604800],
'y': ['years', 31449600],
}
# Debug helper # Debug helper
pp = pprint pp = pprint
@ -65,22 +60,19 @@ async def req(method: str, url: str, **kwargs) -> Response:
def time_to_sec(text: str) -> int: def time_to_sec(text: str) -> int:
match = re.match(r'(\d+)([smhdwy])', text) match = TIME_REGEX.match(text)
if match: if match:
num, unit = match.groups() unit, num = match
num = int(num) return num * TIME_DICT[unit][1]
if unit == 's':
return num
elif unit == 'm': def time_delta(text: str) -> timedelta:
return num * 60 match = TIME_REGEX.match(text)
elif unit == 'h': if match:
return num * 3600 unit, num = match
elif unit == 'd': if unit == 'years':
return num * 86400 num *= 52
elif unit == 'w': return timedelta(**{TIME_DICT[unit][0]: num})
return num * 604800
elif unit == 'y':
return num * 52 * 604800
def parse_int(val: str, select: bool = True) -> tuple: def parse_int(val: str, select: bool = True) -> tuple:
@ -96,7 +88,7 @@ def parse_int(val: str, select: bool = True) -> tuple:
op = '>=' op = '>='
if select: if select:
val -= 1 val -= 1
return order, val, op return val, order, op
except ValueError: except ValueError:
pass pass

View File

@ -1,8 +1,8 @@
create table if not exists quotes ( create table if not exists quotes (
id integer primary key autoincrement, id integer primary key autoincrement,
nick text not null, nick text not null,
value text not null, item text not null,
unique (nick, value collate nocase) unique (nick, item collate nocase)
); );
create table if not exists mcmaniac ( create table if not exists mcmaniac (