Initial commit
This commit is contained in:
commit
5a0b829369
1
.env-example
Normal file
1
.env-example
Normal file
|
@ -0,0 +1 @@
|
||||||
|
PASSWORD=password
|
4
.gitignore
vendored
Normal file
4
.gitignore
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
data/
|
||||||
|
.env
|
||||||
|
.idea/
|
||||||
|
__pycache__/
|
34
config.json
Normal file
34
config.json
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
{
|
||||||
|
"username": "nxy",
|
||||||
|
"host": "unterschicht.tv",
|
||||||
|
"port": 56791,
|
||||||
|
"ssl": true,
|
||||||
|
"raw": true,
|
||||||
|
"autojoins": ["#nxy-dev"],
|
||||||
|
"storage": "json://data/db.json",
|
||||||
|
"flood_burst": 1,
|
||||||
|
"flood_rate": 4,
|
||||||
|
"flood_rate_delay": 1,
|
||||||
|
"includes": [
|
||||||
|
"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.mcmaniac",
|
||||||
|
"nxy.plugins.quotes",
|
||||||
|
"nxy.plugins.reminder",
|
||||||
|
"nxy.plugins.useless"
|
||||||
|
],
|
||||||
|
"irc3.plugins.command": {
|
||||||
|
"cmd": ".",
|
||||||
|
"guard": "irc3.plugins.command.mask_based_policy"
|
||||||
|
},
|
||||||
|
"irc3.plugins.command.masks": {
|
||||||
|
"*!ceo@cocaine-import.agency": "all_permissions",
|
||||||
|
"*": "view"
|
||||||
|
}
|
||||||
|
}
|
46
nxy/bot.py
Normal file
46
nxy/bot.py
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
import sqlite3
|
||||||
|
import json
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
|
||||||
|
# noinspection PyPackageRequirements
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
from irc3 import IrcBot
|
||||||
|
|
||||||
|
CFG_DEV = {
|
||||||
|
'nick': 'nxy',
|
||||||
|
'autojoins': ['#dev'],
|
||||||
|
'host': 'localhost',
|
||||||
|
'port': 6667,
|
||||||
|
'ssl': False,
|
||||||
|
'raw': True,
|
||||||
|
'debug': True,
|
||||||
|
'verbose': True,
|
||||||
|
"irc3.plugins.command.masks": {
|
||||||
|
"*!admin@127.0.0.1": "all_permissions",
|
||||||
|
"*": "view"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# TODO: imdb, youtube, intensifies, pay, owe, rape (owe)
|
||||||
|
def main(cfg_file):
|
||||||
|
load_dotenv('.env')
|
||||||
|
with open(cfg_file, 'r') as fp:
|
||||||
|
cfg = json.load(fp)
|
||||||
|
if bool(os.environ.get('DEV')):
|
||||||
|
cfg.update(CFG_DEV)
|
||||||
|
elif 'PASSWORD' in os.environ:
|
||||||
|
cfg['password'] = os.environ['PASSWORD']
|
||||||
|
data = os.path.dirname(cfg['storage'].split('://', 1)[1])
|
||||||
|
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()
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
main(sys.argv[1])
|
32
nxy/plugins/__init__.py
Normal file
32
nxy/plugins/__init__.py
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from irc3 import IrcBot
|
||||||
|
|
||||||
|
MODULE = __name__
|
||||||
|
|
||||||
|
|
||||||
|
class BasePlugin(object):
|
||||||
|
def __init__(self, bot: IrcBot):
|
||||||
|
self.bot = bot
|
||||||
|
self.log = bot.log
|
||||||
|
|
||||||
|
|
||||||
|
class Plugin(BasePlugin):
|
||||||
|
@classmethod
|
||||||
|
def reload(cls, old: BasePlugin):
|
||||||
|
return cls(old.bot)
|
||||||
|
|
||||||
|
|
||||||
|
class DatabasePlugin(Plugin):
|
||||||
|
def __init__(self, bot: IrcBot):
|
||||||
|
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] = {}
|
22
nxy/plugins/admin.py
Normal file
22
nxy/plugins/admin.py
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from docopt import Dict as DocoptDict
|
||||||
|
from irc3 import IrcBot
|
||||||
|
from irc3.utils import IrcString
|
||||||
|
from irc3.plugins.command import command
|
||||||
|
|
||||||
|
from . import MODULE, Plugin
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
|
@command(permission='admin', show_in_help_list=False)
|
||||||
|
def reload(bot: IrcBot, mask: IrcString, channel: IrcString, args: DocoptDict):
|
||||||
|
"""Reload a plugin
|
||||||
|
%%reload <plugin>
|
||||||
|
"""
|
||||||
|
plugin = args['<plugin>']
|
||||||
|
bot.reload('{module}.{plugin}'.format(plugin=plugin, module=MODULE))
|
||||||
|
bot.notice(mask.nick, 'Reloaded plugin "{plugin}"'.format(plugin=plugin))
|
||||||
|
|
||||||
|
|
||||||
|
class Admin(Plugin):
|
||||||
|
pass
|
31
nxy/plugins/bitcoin.py
Normal file
31
nxy/plugins/bitcoin.py
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from docopt import Dict as DocOptDict
|
||||||
|
from irc3.plugins.command import command
|
||||||
|
from irc3.utils import IrcString
|
||||||
|
|
||||||
|
from . import Plugin
|
||||||
|
from ..utils import fmt, req
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
|
class Bitcoin(Plugin):
|
||||||
|
requires = [
|
||||||
|
'irc3.plugins.command',
|
||||||
|
]
|
||||||
|
|
||||||
|
@command
|
||||||
|
async def btc(self, mask: IrcString, channel: IrcString,
|
||||||
|
args: DocOptDict) -> str:
|
||||||
|
"""Bitcoin command.
|
||||||
|
%%btc
|
||||||
|
"""
|
||||||
|
data = (await req('get', 'https://www.bitstamp.net/api/ticker')).json()
|
||||||
|
return fmt('{bold}[BitStamp, 24h]{reset} '
|
||||||
|
'Current: {bold}{color}{orange}${last:,.2f}{reset} - '
|
||||||
|
'High: {bold}{color}{green}${high:,.2f}{reset} - '
|
||||||
|
'Low: {bold}{color}{maroon}${low:,.2f}{reset} - '
|
||||||
|
'Volume: {bold}฿{volume:,.2f}',
|
||||||
|
last=float(data['last']),
|
||||||
|
high=float(data['high']),
|
||||||
|
low=float(data['low']),
|
||||||
|
volume=float(data['volume']))
|
79
nxy/plugins/ctcp.py
Normal file
79
nxy/plugins/ctcp.py
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from docopt import Dict as DocOptDict
|
||||||
|
from irc3.plugins.command import command
|
||||||
|
from irc3.utils import IrcString
|
||||||
|
import time
|
||||||
|
|
||||||
|
from . import Plugin
|
||||||
|
from ..utils import fmt
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
|
class CTCP(Plugin):
|
||||||
|
TIMEOUT = 5
|
||||||
|
|
||||||
|
requires = [
|
||||||
|
'irc3.plugins.async',
|
||||||
|
'irc3.plugins.command',
|
||||||
|
]
|
||||||
|
|
||||||
|
async def ctcp(self, ctcp: str, mask: IrcString, args: DocOptDict) -> str:
|
||||||
|
nick = args.get('<nick>') or mask.nick
|
||||||
|
name = ctcp.upper()
|
||||||
|
ctcp = await self.bot.ctcp_async(nick, name, timeout=self.TIMEOUT)
|
||||||
|
if not ctcp or ctcp['timeout']:
|
||||||
|
reply = 'timeout'
|
||||||
|
elif not ctcp['success']:
|
||||||
|
reply = 'Error: {reply}'.format(reply=ctcp['reply'])
|
||||||
|
else:
|
||||||
|
reply = ctcp['reply']
|
||||||
|
return fmt('{bold}[{ctcp}]{reset} {nick}: {reply}',
|
||||||
|
ctcp=name,
|
||||||
|
nick=nick,
|
||||||
|
reply=reply)
|
||||||
|
|
||||||
|
@command
|
||||||
|
async def ping(self, mask: IrcString, channel: IrcString,
|
||||||
|
args: DocOptDict) -> str:
|
||||||
|
"""CTCP ping command.
|
||||||
|
%%ping [<nick>]
|
||||||
|
"""
|
||||||
|
nick = args.get('<nick>') or mask.nick
|
||||||
|
ctcp = await self.bot.ctcp_async(nick, 'PING {0}'.format(time.time()),
|
||||||
|
timeout=self.TIMEOUT)
|
||||||
|
if not ctcp or ctcp['timeout']:
|
||||||
|
reply = 'timeout'
|
||||||
|
elif not ctcp['success']:
|
||||||
|
reply = 'Error: {reply}'.format(reply=ctcp['reply'])
|
||||||
|
else:
|
||||||
|
delta = time.time() - float(ctcp['reply'])
|
||||||
|
reply = '{delta:.9f} {unit}'.format(
|
||||||
|
unit='ms' if delta < 0 else 's',
|
||||||
|
delta=delta)
|
||||||
|
return fmt('{bold}[PING]{reset} {nick}: {text}',
|
||||||
|
nick=nick,
|
||||||
|
text=reply)
|
||||||
|
|
||||||
|
@command
|
||||||
|
async def finger(self, mask: IrcString, channel: IrcString,
|
||||||
|
args: DocOptDict) -> str:
|
||||||
|
"""CTCP finger command.
|
||||||
|
%%finger [<nick>]
|
||||||
|
"""
|
||||||
|
return await self.ctcp('FINGER', mask, args)
|
||||||
|
|
||||||
|
@command
|
||||||
|
async def time(self, mask: IrcString, channel: IrcString,
|
||||||
|
args: DocOptDict) -> str:
|
||||||
|
"""CTCP time command.
|
||||||
|
%%time [<nick>]
|
||||||
|
"""
|
||||||
|
return await self.ctcp('TIME', mask, args)
|
||||||
|
|
||||||
|
@command
|
||||||
|
async def ver(self, mask: IrcString, channel: IrcString,
|
||||||
|
args: DocOptDict) -> str:
|
||||||
|
"""CTCP version command.
|
||||||
|
%%ver [<nick>]
|
||||||
|
"""
|
||||||
|
return await self.ctcp('VERSION', mask, args)
|
59
nxy/plugins/mcmaniac.py
Normal file
59
nxy/plugins/mcmaniac.py
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
# -*- 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 . import DatabasePlugin
|
||||||
|
from ..utils import parse_int
|
||||||
|
|
||||||
|
|
||||||
|
@irc3.plugin
|
||||||
|
class McManiac(DatabasePlugin):
|
||||||
|
requires = [
|
||||||
|
'irc3.plugins.command',
|
||||||
|
]
|
||||||
|
|
||||||
|
@property
|
||||||
|
def items(self):
|
||||||
|
return self.db['items']
|
||||||
|
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
|
@command(options_first=True)
|
||||||
|
def mcmaniac(self, mask: IrcString, channel: IrcString, args: DocOptDict):
|
||||||
|
"""Manage McManiacs
|
||||||
|
%%mcmaniac <cmd> <mcmaniac>
|
||||||
|
%%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
|
||||||
|
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()
|
62
nxy/plugins/quotes.py
Normal file
62
nxy/plugins/quotes.py
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from docopt import Dict as DocOptDict
|
||||||
|
from irc3.utils import IrcString
|
||||||
|
from irc3.plugins.command import command
|
||||||
|
import random
|
||||||
|
import irc3
|
||||||
|
import re
|
||||||
|
|
||||||
|
from . import DatabasePlugin
|
||||||
|
from ..utils import parse_int
|
||||||
|
|
||||||
|
|
||||||
|
@irc3.plugin
|
||||||
|
class Quotes(DatabasePlugin):
|
||||||
|
requires = [
|
||||||
|
'irc3.plugins.command',
|
||||||
|
]
|
||||||
|
|
||||||
|
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):
|
||||||
|
"""
|
||||||
|
Manage quotes.
|
||||||
|
%%q <cmd> <nick> <quote>...
|
||||||
|
%%q <nick> [<quote>...]
|
||||||
|
"""
|
||||||
|
cmd = args.get('<cmd>')
|
||||||
|
nick = args['<nick>']
|
||||||
|
quote = args.get('<quote>')
|
||||||
|
if cmd:
|
||||||
|
if cmd == 'add':
|
||||||
|
nick = self.REGEX.match(nick).group(1)
|
||||||
|
if nick not in self.db:
|
||||||
|
self.db[nick] = []
|
||||||
|
quote = ' '.join(quote)
|
||||||
|
if quote not in self.db[nick]:
|
||||||
|
self.db[nick].append(quote)
|
||||||
|
elif cmd == 'del':
|
||||||
|
try:
|
||||||
|
self.db[nick].pop(parse_int(quote))
|
||||||
|
if not self.db[nick]:
|
||||||
|
del self.db[nick]
|
||||||
|
except (KeyError, IndexError, TypeError):
|
||||||
|
return
|
||||||
|
self._db.SIGINT()
|
||||||
|
else:
|
||||||
|
if quote:
|
||||||
|
try:
|
||||||
|
quote = self.db[nick][parse_int(quote)]
|
||||||
|
except (KeyError, IndexError, TypeError):
|
||||||
|
return
|
||||||
|
else:
|
||||||
|
quote = random.choice(self.db[nick])
|
||||||
|
self.bot.privmsg(channel, self.RESPONSE.format(
|
||||||
|
index=self.db[nick].index(quote) + 1,
|
||||||
|
total=len(self.db[nick]),
|
||||||
|
nick=nick,
|
||||||
|
quote=quote,
|
||||||
|
))
|
41
nxy/plugins/reminder.py
Normal file
41
nxy/plugins/reminder.py
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
# -*- 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)
|
77
nxy/plugins/useless.py
Normal file
77
nxy/plugins/useless.py
Normal file
|
@ -0,0 +1,77 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from docopt import Dict as DocOptDict
|
||||||
|
from irc3.plugins.command import command
|
||||||
|
from irc3.utils import IrcString
|
||||||
|
import random
|
||||||
|
|
||||||
|
from . import Plugin
|
||||||
|
from ..utils import fmt
|
||||||
|
|
||||||
|
RAINBOW = ('maroon', 'red', 'orange', 'yellow', 'ltgreen', 'green', 'teal',
|
||||||
|
'ltblue', 'blue', 'purple', 'pink')
|
||||||
|
RAINBOW_LEN = len(RAINBOW)
|
||||||
|
|
||||||
|
|
||||||
|
# noinspection PyUnusedLocal
|
||||||
|
class Useless(Plugin):
|
||||||
|
requires = [
|
||||||
|
'irc3.plugins.command',
|
||||||
|
]
|
||||||
|
|
||||||
|
@command
|
||||||
|
def jn(self, mask: IrcString, channel: IrcString, args: DocOptDict) -> str:
|
||||||
|
"""Yes or no command.
|
||||||
|
%%jn <question>
|
||||||
|
"""
|
||||||
|
choice = random.choice(['{green}Ja', '{maroon}Nein'])
|
||||||
|
return fmt('{nick}: {bold}{color}%s' % choice, nick=mask.nick)
|
||||||
|
|
||||||
|
@command
|
||||||
|
def kiss(self, mask: IrcString, channel: IrcString, args: DocOptDict):
|
||||||
|
"""Kiss command.
|
||||||
|
%%kiss <nick>
|
||||||
|
"""
|
||||||
|
return fmt('(づ。◕‿‿◕。)づ{color}{red}。。・゜゜・。。・゜❤{reset} {nick} '
|
||||||
|
'{color}{red}❤',
|
||||||
|
nick=args['<nick>'])
|
||||||
|
|
||||||
|
@command
|
||||||
|
def hug(self, mask: IrcString, channel: IrcString,
|
||||||
|
args: DocOptDict) -> str:
|
||||||
|
"""Hug command.
|
||||||
|
%%hug <nick>
|
||||||
|
"""
|
||||||
|
return fmt('{color}{red}♥♡❤♡♥{reset} {nick} {color}{red}♥♡❤♡♥',
|
||||||
|
nick=args['<nick>'])
|
||||||
|
|
||||||
|
@command
|
||||||
|
def gay(self, mask: IrcString, channel: IrcString,
|
||||||
|
args: DocOptDict) -> str:
|
||||||
|
"""Gay command (alias to rainbow).
|
||||||
|
%%gay <word>...
|
||||||
|
"""
|
||||||
|
return self.rainbow(mask, channel, args)
|
||||||
|
|
||||||
|
@command
|
||||||
|
def rainbow(self, mask: IrcString, channel: IrcString,
|
||||||
|
args: DocOptDict) -> str:
|
||||||
|
"""Rainbow command.
|
||||||
|
%%rainbow <word>...
|
||||||
|
"""
|
||||||
|
last = 0
|
||||||
|
word = []
|
||||||
|
for i, char in enumerate(' '.join(args.get('<word>'))):
|
||||||
|
if char != ' ':
|
||||||
|
char = '{color}{%s}%s' % (RAINBOW[last % RAINBOW_LEN], char)
|
||||||
|
last += 1
|
||||||
|
word.append(char)
|
||||||
|
return fmt(''.join(word))
|
||||||
|
|
||||||
|
@command
|
||||||
|
def wrainbow(self, mask: IrcString, channel: IrcString,
|
||||||
|
args: DocOptDict) -> str:
|
||||||
|
"""Word Rainbow command.
|
||||||
|
%%wrainbow <words>...
|
||||||
|
"""
|
||||||
|
return fmt(' '.join(['{color}{%s}%s' % (RAINBOW[i % RAINBOW_LEN], word)
|
||||||
|
for i, word in enumerate(args['<words>'])]))
|
100
nxy/utils.py
Normal file
100
nxy/utils.py
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from requests import request, Response
|
||||||
|
from pprint import pprint
|
||||||
|
import re
|
||||||
|
|
||||||
|
# @formatter:off
|
||||||
|
COLORS = dict(
|
||||||
|
white='00', # white
|
||||||
|
black='01', # black
|
||||||
|
blue='02', # blue (navy)
|
||||||
|
green='03', # green
|
||||||
|
red='04', # red
|
||||||
|
maroon='05', # brown (maroon)
|
||||||
|
purple='06', # purple
|
||||||
|
orange='07', # orange (olive)
|
||||||
|
yellow='08', # yellow
|
||||||
|
ltgreen='09', # light green (lime)
|
||||||
|
teal='10', # teal (a green/blue cyan)
|
||||||
|
ltcyan='11', # light cyan (cyan / aqua)
|
||||||
|
ltblue='12', # light blue (royal)
|
||||||
|
pink='13', # pink (light purple / fuchsia)
|
||||||
|
grey='14', # grey
|
||||||
|
ltgrey='15', # light grey (silver)
|
||||||
|
)
|
||||||
|
|
||||||
|
FORMATTING = dict(
|
||||||
|
bold='\x02', # bold
|
||||||
|
color='\x03', # colored text
|
||||||
|
italic='\x1D', # italic text
|
||||||
|
underline='\x1F', # underlined text
|
||||||
|
swap='\x16', # swap bg and fg colors ("reverse video")
|
||||||
|
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
|
||||||
|
)
|
||||||
|
# @formatter:on
|
||||||
|
|
||||||
|
# Debug helper
|
||||||
|
pp = pprint
|
||||||
|
|
||||||
|
|
||||||
|
def fmt(__text: str, **kwargs) -> str:
|
||||||
|
"""Formats a str with `kwargs` and `FORMATTING`."""
|
||||||
|
return __text.format(**kwargs, **FORMATTING)
|
||||||
|
|
||||||
|
|
||||||
|
async def req(method: str, url: str, **kwargs) -> Response:
|
||||||
|
return request(method, url, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
def time_to_sec(text: str) -> int:
|
||||||
|
match = re.match(r'(\d+)([smhdwy])', text)
|
||||||
|
if match:
|
||||||
|
num, unit = match.groups()
|
||||||
|
num = int(num)
|
||||||
|
if unit == 's':
|
||||||
|
return num
|
||||||
|
elif unit == 'm':
|
||||||
|
return num * 60
|
||||||
|
elif unit == 'h':
|
||||||
|
return num * 3600
|
||||||
|
elif unit == 'd':
|
||||||
|
return num * 86400
|
||||||
|
elif unit == 'w':
|
||||||
|
return num * 604800
|
||||||
|
elif unit == 'y':
|
||||||
|
return num * 52 * 604800
|
||||||
|
|
||||||
|
|
||||||
|
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
|
4
requirements.txt
Normal file
4
requirements.txt
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
irc3==1.0.0
|
||||||
|
aiocron==0.6
|
||||||
|
requests==2.14.2
|
||||||
|
python_dotenv==0.6.4
|
Loading…
Reference in New Issue
Block a user