Lots of stuff

This commit is contained in:
mrhanky 2017-05-16 07:45:10 +02:00
parent 5d46afa2da
commit cb8011aa67
No known key found for this signature in database
GPG Key ID: 67D772C481CB41B8
12 changed files with 113 additions and 64 deletions

View File

@ -5,7 +5,7 @@
"ssl": true,
"raw": true,
"autojoins": ["#nxy-dev"],
"storage": "json://data/db.json",
"storage": "sqlite://data/nxy.db",
"flood_burst": 1,
"flood_rate": 4,
"flood_rate_delay": 1,
@ -13,11 +13,11 @@
"irc3.plugins.async",
"irc3.plugins.cron",
"irc3.plugins.command",
"irc3.plugins.storage",
"irc3.plugins.uptime",
"nxy.plugins.admin",
"nxy.plugins.bitcoin",
"nxy.plugins.ctcp",
"nxy.plugins.database",
"nxy.plugins.mcmaniac",
"nxy.plugins.quotes",
"nxy.plugins.reminder",
@ -28,8 +28,9 @@
"guard": "irc3.plugins.command.mask_based_policy"
},
"irc3.plugins.command.masks": {
"*!ceo@cocaine-import.agency": "all_permissions",
"*!ceo@unterschicht.tv": "all_permissions",
"mrhanky!mrhanky@cocaine-import.agency": "all_permissions",
"jkhsjdhjs!jkhsjdhjs@smoke.weed.everyday": "admin",
"sirx!sirx@n0xy.net": "admin",
"*": "view"
}
}

View File

@ -37,8 +37,6 @@ def main(cfg_file):
if not os.path.exists(data):
os.makedirs(data)
bot = IrcBot.from_config(cfg)
if bool(os.environ.get('DEV')):
bot.con = sqlite3.connect('nxy.db')
bot.run()

View File

@ -17,16 +17,7 @@ class Plugin(BasePlugin):
class DatabasePlugin(Plugin):
def __init__(self, bot: IrcBot):
def __init__(self, bot):
super().__init__(bot)
# noinspection PyUnresolvedReferences
self._db = bot.db
self.prepare_db()
@property
def db(self):
return self._db[self]
def prepare_db(self):
if self not in self._db:
self._db[self] = {}
self.con = bot.con.db
self.cur = self.con.cursor()

View File

@ -3,6 +3,7 @@ from docopt import Dict as DocoptDict
from irc3 import IrcBot
from irc3.utils import IrcString
from irc3.plugins.command import command
import irc3
from . import MODULE, Plugin
@ -18,5 +19,6 @@ def reload(bot: IrcBot, mask: IrcString, channel: IrcString, args: DocoptDict):
bot.notice(mask.nick, 'Reloaded plugin "{plugin}"'.format(plugin=plugin))
@irc3.plugin
class Admin(Plugin):
pass

View File

@ -2,12 +2,14 @@
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
# noinspection PyUnusedLocal
@irc3.plugin
class Bitcoin(Plugin):
requires = [
'irc3.plugins.command',

View File

@ -3,12 +3,14 @@ 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
# noinspection PyUnusedLocal
@irc3.plugin
class CTCP(Plugin):
TIMEOUT = 5

18
nxy/plugins/database.py Normal file
View File

@ -0,0 +1,18 @@
# -*- coding: utf-8 -*-
import sqlite3
import irc3
from . import Plugin
@irc3.plugin
class Database(Plugin):
def __init__(self, bot):
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)
self.db.row_factory = sqlite3.Row
self.bot = bot
self.bot.con = self

View File

@ -1,24 +1,18 @@
# -*- coding: utf-8 -*-
from docopt import Dict as DocOptDict
from irc3.utils import IrcString
from irc3.plugins.command import command
import random
import irc3
from irc3.plugins.command import command, Commands
from . import DatabasePlugin
from ..utils import parse_int
@irc3.plugin
class McManiac(DatabasePlugin):
requires = [
'irc3.plugins.command',
'nxy.plugins.database',
]
@property
def items(self):
return self.db['items']
# noinspection PyUnusedLocal
@command(options_first=True)
def mcmaniac(self, mask: IrcString, channel: IrcString, args: DocOptDict):
@ -27,33 +21,43 @@ class McManiac(DatabasePlugin):
%%mcmaniac [<index>]
"""
cmd = args.get('<cmd>')
mcmaniac = args.get('<mcmaniac>')
index = args.get('<index>')
if cmd and mcmaniac:
if cmd == 'add':
if mcmaniac not in self.items:
self.items.append(mcmaniac)
if cmd == 'del':
try:
self.items.pop(parse_int(mcmaniac))
except (IndexError, TypeError):
return
self._db.SIGINT()
elif self.items:
if index:
try:
mcmaniac = self.items[parse_int(index)]
except (IndexError, TypeError):
return
item = args.get('<mcmaniac>')
guard = self.bot.get_plugin(Commands).guard
if cmd and item:
if guard.has_permission(mask, 'admin'):
if cmd == 'add':
self.cur.execute('insert into mcmaniac (item) values (?)',
[item])
if cmd == 'del':
order, index, 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})
'''.format(op=op, order=order), [index])
self.con.commit()
else:
mcmaniac = random.choice(self.items)
return '[{index}/{total}] {item}'.format(
index=self.items.index(mcmaniac) + 1,
total=len(self.items),
item=mcmaniac
)
def prepare_db(self):
super().prepare_db()
self._db.setdefault(self, items=[])
self._db.SIGINT()
self.bot.notice(mask.nick, 'Permission denied')
else:
index = args.get('<index>')
if index:
index = parse_int(index)
if not index:
return
order, index, _ = index
order = 'id {order}'.format(order=order)
extra = 'offset ?'
binds = [index]
else:
order = 'random()'
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}
'''.format(order=order, extra=extra), binds)
item = self.cur.fetchone()
if item:
return '[{idx}/{len}] {item}'.format(**item)

View File

@ -17,11 +17,10 @@ class Quotes(DatabasePlugin):
]
REGEX = re.compile(r'<?[~&@%+]?([a-zA-Z0-9_\-^`|\\\[\]{}]+)>?')
RESPONSE = '[{index}/{total}] <{nick}> {quote}'
# noinspection PyUnusedLocal
@command(options_first=True)
def q(self, mask: IrcString, channel: IrcString, args: DocOptDict):
def q(self, mask: IrcString, channel: IrcString, args: DocOptDict) -> str:
"""
Manage quotes.
%%q <cmd> <nick> <quote>...
@ -44,19 +43,19 @@ class Quotes(DatabasePlugin):
if not self.db[nick]:
del self.db[nick]
except (KeyError, IndexError, TypeError):
return
return ''
self._db.SIGINT()
else:
if quote:
try:
quote = self.db[nick][parse_int(quote)]
except (KeyError, IndexError, TypeError):
return
return ''
else:
quote = random.choice(self.db[nick])
self.bot.privmsg(channel, self.RESPONSE.format(
return '[{index}/{total}] <{nick}> {quote}'.format(
index=self.db[nick].index(quote) + 1,
total=len(self.db[nick]),
nick=nick,
quote=quote,
))
)

View File

@ -4,6 +4,7 @@ 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
@ -16,11 +17,12 @@ GNU_LINUX = """I'd Just Like To Interject For A Moment. What you're referring
to as Linux, is in fact, GNU/Linux, or as I've recently taken to calling it,
GNU plus Linux. Linux is not an operating system unto itself, but rather
another free component of a fully functioning GNU system made useful by the
GNU corelibs, shell utilities and vital system components comprising a full OS
as defined by POSIX."""
GNU corelibs, shell utilities and vital system components comprising a full
OS as defined by POSIX."""
# noinspection PyUnusedLocal
@irc3.plugin
class Useless(Plugin):
requires = [
'irc3.plugins.command',

View File

@ -83,7 +83,25 @@ def time_to_sec(text: str) -> int:
return num * 52 * 604800
def parse_int(val: list) -> int:
def parse_int(val: str, select: bool = True) -> tuple:
try:
val = int(val)
if val is not 0:
if val < 1:
order = 'desc'
val *= -1
op = '<='
else:
order = 'asc'
op = '>='
if select:
val -= 1
return order, val, 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.

12
schema.sql Normal file
View File

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