Massive refactoring/-structuring
This commit is contained in:
parent
a82175a44b
commit
59b67d9570
7
.gitignore
vendored
7
.gitignore
vendored
|
@ -1,4 +1,5 @@
|
|||
.env
|
||||
config.json
|
||||
.idea/
|
||||
__pycache__/
|
||||
.idea/
|
||||
|
||||
/.env
|
||||
/config.json
|
||||
|
|
25
FORMATTING.md
Normal file
25
FORMATTING.md
Normal file
|
@ -0,0 +1,25 @@
|
|||
# Formatting
|
||||
- bold: \x02
|
||||
- color: \x03{color code}
|
||||
- italic: \x1D
|
||||
- underline: \x1F
|
||||
- swap: \x16
|
||||
- reset: \x0F
|
||||
|
||||
# Color codes
|
||||
- white: 0
|
||||
- black: 1
|
||||
- blue: 2
|
||||
- green: 3
|
||||
- red: 4
|
||||
- maroon: 5
|
||||
- purple: 6
|
||||
- orange: 7
|
||||
- yellow: 8
|
||||
- ltgreen: 9
|
||||
- teal: 10
|
||||
- ltcyan: 11
|
||||
- ltblue: 12
|
||||
- pink: 13
|
||||
- grey: 14
|
||||
- ltgrey: 15
|
16
README.md
16
README.md
|
@ -10,19 +10,19 @@
|
|||
* Create virtualenv and install dependencies
|
||||
- ```mkvirtualenv -a $PWD -r $PWD/requirements.txt nxy```
|
||||
* Create needed tables in the database:
|
||||
- ```psql -U <your db user> < schema.sql```
|
||||
* Copy ```.env-example``` and insert values in ```.env``` (replace everything wrapped in < and >)
|
||||
- ```cp .env-example .env```
|
||||
- ```psql -U <your db user> < files/schema.sql```
|
||||
* Copy ```files/.env``` and insert values in ```.env``` (replace everything wrapped in < and >)
|
||||
- ```cp files/.env .env```
|
||||
- ```vim .env```
|
||||
* Copy ```config.json``` and modify it (setup ZNC etc.)
|
||||
- ```cp config.json-example config.json```
|
||||
* Copy ```files/config.json``` and modify it (setup ZNC etc.)
|
||||
- ```cp files/config.json config.json```
|
||||
- ```vim config.json```
|
||||
* If database is empty, run the migrate script to populate the database with old nxy data:
|
||||
- ```python bot/migrate.py```
|
||||
* If database is empty, import your database dump:
|
||||
- ```psql -U nxy -d nxy < /path/to/dump.sql```
|
||||
* Leave (auto) activated virtualenv and exit the bot's shell
|
||||
- ```deactivate && exit```
|
||||
* Copy systemd unit and enable it (would recommend the ```/usr/local``` prefix). Don't forget to modify the systemd unit if your user and home directory are different!
|
||||
- ```sudo mkdir -p /usr/local/lib/systemd/system```
|
||||
- ```sudo cp /home/nxy/nxy/nxy-bot.service /usr/local/lib/systemd/system```
|
||||
- ```sudo ln -fs /home/nxy/bot/files/nxy-bot.service /usr/local/lib/systemd/system```
|
||||
- ```sudo systemctl daemon-reload```
|
||||
- ```sudo systemctl enable --now nxy-bot.service```
|
||||
|
|
|
@ -46,4 +46,8 @@ def main(cfg_file):
|
|||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(sys.argv[1])
|
||||
if len(sys.argv) > 1:
|
||||
config = sys.argv[1]
|
||||
else:
|
||||
config = 'config.json'
|
||||
main(config)
|
|
@ -20,7 +20,7 @@ class Plugin(BasePlugin):
|
|||
|
||||
|
||||
# Import the PgSQL storage plugin
|
||||
from .storage import Storage
|
||||
from .storage import Storage # noqa: E402
|
||||
|
||||
|
||||
class DatabasePlugin(Plugin):
|
|
@ -12,8 +12,7 @@ from . import Plugin
|
|||
class Coins(Plugin):
|
||||
requires = ['irc3.plugins.command']
|
||||
|
||||
CRYPTOWAT = 'https://api.cryptowat.ch/markets/{market}/{crypto}{currency}' \
|
||||
'/summary'
|
||||
API_URL = 'https://api.cryptowat.ch/markets/coinbase/{crypto}{currency}/summary'
|
||||
CURRENCIES = {
|
||||
'usd': '$',
|
||||
'eur': '€',
|
||||
|
@ -37,19 +36,16 @@ class Coins(Plugin):
|
|||
"""
|
||||
return self._cryptowat_summary('eth', args.get('<currency>') or 'usd')
|
||||
|
||||
def _cryptowat_summary(self, crypto: str, currency: str = 'usd',
|
||||
market: str = 'coinbase'):
|
||||
def _cryptowat_summary(self, crypto: str, currency: str = 'usd'):
|
||||
# Check if valid currency + crypto2currency
|
||||
if currency not in self.CURRENCIES or crypto == currency:
|
||||
return
|
||||
|
||||
# Send request to api
|
||||
data = requests.get(self.CRYPTOWAT.format(market=market,
|
||||
crypto=crypto,
|
||||
currency=currency))
|
||||
data = requests.get(self.API_URL.format(crypto=crypto, currency=currency))
|
||||
if data:
|
||||
result = data.json()['result']
|
||||
return '\x02[{crypto}]\x02 ' \
|
||||
return '\x02[{crypto}]\x0F ' \
|
||||
'Current: \x02\x0307{currency}{last:,.2f}\x0F - ' \
|
||||
'High: \x02\x0303{currency}{high:,.2f}\x0F - ' \
|
||||
'Low: \x02\x0304{currency}{low:,.2f}\x0F - ' \
|
|
@ -14,13 +14,9 @@ class CTCP(Plugin):
|
|||
requires = ['irc3.plugins.async',
|
||||
'irc3.plugins.command']
|
||||
|
||||
@staticmethod
|
||||
def _ctcp(name: str, nick: str, reply: str):
|
||||
return '\x02[{name}]\x02 {nick}: {reply}'.format(
|
||||
name=name.upper(),
|
||||
nick=nick,
|
||||
reply=reply,
|
||||
)
|
||||
# noinspection PyMethodMayBeStatic
|
||||
def _ctcp(self, name: str, nick: str, reply: str):
|
||||
return '\x02[{}]\x0F {}: {}'.format(name.upper(), nick, reply)
|
||||
|
||||
async def ctcp(self, name: str, mask: IrcString, args: DocOptDict):
|
||||
nick = args.get('<nick>') or mask.nick
|
||||
|
@ -30,7 +26,7 @@ class CTCP(Plugin):
|
|||
if not data or data['timeout']:
|
||||
reply = 'timeout'
|
||||
elif not data['success']:
|
||||
reply = 'Error: {reply}'.format(reply=data['reply'])
|
||||
reply = 'Error: {}'.format(data['reply'])
|
||||
else:
|
||||
reply = data['reply']
|
||||
|
||||
|
@ -44,12 +40,12 @@ class CTCP(Plugin):
|
|||
%%ping [<nick>]
|
||||
"""
|
||||
nick = args.get('<nick>') or mask.nick
|
||||
data = await self.bot.ctcp_async(nick, 'PING {0}'.format(time.time()))
|
||||
data = await self.bot.ctcp_async(nick, 'PING {}'.format(time.time()))
|
||||
|
||||
if not data or data['timeout']:
|
||||
reply = 'timeout'
|
||||
elif not data['success']:
|
||||
reply = 'Error: {reply}'.format(reply=data['reply'])
|
||||
reply = 'Error: {}'.format(data['reply'])
|
||||
else:
|
||||
delta = time.time() - float(data['reply'])
|
||||
if delta < 1.0:
|
||||
|
@ -57,7 +53,7 @@ class CTCP(Plugin):
|
|||
unit = 'ms'
|
||||
else:
|
||||
unit = 's'
|
||||
reply = '{delta:.3f} {unit}'.format(unit=unit, delta=delta)
|
||||
reply = '{0:.3f} {1}'.format(delta, unit)
|
||||
|
||||
return self._ctcp('PING', nick, reply)
|
||||
|
|
@ -13,7 +13,7 @@ from . import DatabasePlugin
|
|||
@irc3.plugin
|
||||
class Useless(DatabasePlugin):
|
||||
requires = ['irc3.plugins.command',
|
||||
'nxy.plugins.storage']
|
||||
'bot.plugins.storage']
|
||||
|
||||
@command
|
||||
def isup(self, mask: IrcString, target: IrcString, args: DocOptDict):
|
||||
|
@ -31,6 +31,4 @@ class Useless(DatabasePlugin):
|
|||
state = 'up'
|
||||
except requests.ConnectionError:
|
||||
state = 'down'
|
||||
return '{scheme}://{address} seems to be {state}'.format(scheme=parsed.scheme,
|
||||
address=parsed.netloc,
|
||||
state=state)
|
||||
return '{}://{} seems to be {}'.format(parsed.scheme, parsed.netloc, state)
|
|
@ -8,6 +8,7 @@ from irc3.plugins.command import command
|
|||
from irc3.utils import IrcString
|
||||
|
||||
from . import Plugin
|
||||
from ..utils import re_generator
|
||||
|
||||
|
||||
GNU_LINUX = """I'd Just Like To Interject For A Moment. What you're referring
|
||||
|
@ -21,16 +22,13 @@ GNU_LINUX = """I'd Just Like To Interject For A Moment. What you're referring
|
|||
class Linux(Plugin):
|
||||
KERNEL_FEED = 'https://www.kernel.org/feeds/kdist.xml'
|
||||
|
||||
@irc3.event(r'(?i)^:\S+ PRIVMSG (?P<target>\S+) :'
|
||||
r'.*(debian|ubuntu|apt|dpkg).*')
|
||||
@irc3.event(r'(?i)^:\S+ PRIVMSG (?P<target>\S+) :.*(debian|ubuntu|apt|dpkg).*')
|
||||
def debillian(self, target: str):
|
||||
"""Annoying RE trigger for debian with variable count of E."""
|
||||
if random.randint(0, 3) is 0:
|
||||
self.bot.privmsg(target, 'R{}'.format(''.join(
|
||||
'E' for _ in range(random.randint(5, 20)))))
|
||||
self.bot.privmsg(target, re_generator())
|
||||
|
||||
@irc3.event(r'(?i)^:\S+ PRIVMSG (?P<target>\S+) :'
|
||||
r'.*(?<!gnu[/+])linux(?! kernel).*')
|
||||
@irc3.event(r'(?i)^:\S+ PRIVMSG (?P<target>\S+) :.*(?<!gnu[/+])linux(?! kernel).*')
|
||||
def linux(self, target: str):
|
||||
"""Super annoying, useless 'Stallman is mad' trigger."""
|
||||
if random.randint(0, 12) is 0:
|
||||
|
@ -46,7 +44,7 @@ class Linux(Plugin):
|
|||
|
||||
# Cancel if no feed or entries
|
||||
if not feed or not feed.get('entries'):
|
||||
self.log.error('Error fetching kernel.org releases feed.')
|
||||
self.log.error('Error fetching kernel.org releases feed')
|
||||
return
|
||||
|
||||
# Make list of releases
|
||||
|
@ -55,12 +53,8 @@ class Linux(Plugin):
|
|||
version, branch = e['title'].split(': ')
|
||||
|
||||
if '(EOL)' in e['description']:
|
||||
branch = '{branch}, \x1DEOL\x0F'.format(branch=branch)
|
||||
branch = '{}, \x1DEOL\x0F'.format(branch)
|
||||
|
||||
releases.append('\x02{version}\x0F ({branch})'.format(
|
||||
version=version,
|
||||
branch=branch,
|
||||
))
|
||||
releases.append('\x02{}\x0F ({})'.format(version, branch))
|
||||
|
||||
return '\x02[Kernel]\x0F {releases}'.format(
|
||||
releases=', '.join(releases))
|
||||
return '\x02[Kernel]\x0F {}'.format(', '.join(releases))
|
|
@ -13,7 +13,7 @@ from ..utils import parse_int
|
|||
@irc3.plugin
|
||||
class McManiac(DatabasePlugin):
|
||||
requires = ['irc3.plugins.command',
|
||||
'nxy.plugins.storage']
|
||||
'bot.plugins.storage']
|
||||
|
||||
@command(options_first=True)
|
||||
def mcmaniac(self, mask: IrcString, target: IrcString, args: DocOptDict):
|
||||
|
@ -27,7 +27,7 @@ class McManiac(DatabasePlugin):
|
|||
index = parse_int(index)
|
||||
if not index:
|
||||
return
|
||||
index, order, _ = index
|
||||
index, order = index
|
||||
order = 'id {order}'.format(order=order)
|
||||
offset = 'offset %s'
|
||||
else:
|
|
@ -1,23 +1,24 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import irc3
|
||||
import re
|
||||
|
||||
import irc3
|
||||
from docopt import Dict as DocOptDict
|
||||
from irc3.plugins.command import command
|
||||
from irc3.utils import IrcString
|
||||
from psycopg2 import Error
|
||||
|
||||
from . import DatabasePlugin
|
||||
from ..utils import NICK_REGEX, parse_int
|
||||
from ..utils import parse_int
|
||||
|
||||
|
||||
@irc3.plugin
|
||||
class Quotes(DatabasePlugin):
|
||||
requires = ['irc3.plugins.command',
|
||||
'nxy.plugins.storage']
|
||||
'bot.plugins.storage']
|
||||
|
||||
def add_quote(self, mask, nick, quote, channel):
|
||||
# Parse nick from "<@foobar>" like strings
|
||||
nick = NICK_REGEX.match(nick).group(1)
|
||||
nick = re.match(r'<?[~&@%+]?([a-zA-Z0-9_\-^`|\\\[\]{}]+)>?', nick).group(1)
|
||||
|
||||
if not nick:
|
||||
self.bot.notice(mask.nick, '[Quotes] Error parsing nick')
|
||||
|
@ -31,7 +32,7 @@ class Quotes(DatabasePlugin):
|
|||
''', [nick, quote, channel, mask.nick])
|
||||
|
||||
def delete_quote(self, nick, quote):
|
||||
index, order, _ = parse_int(quote, select=False)
|
||||
index, order = parse_int(quote, select=False)
|
||||
|
||||
if index:
|
||||
# Delete from database
|
||||
|
@ -91,7 +92,7 @@ class Quotes(DatabasePlugin):
|
|||
index = parse_int(index)
|
||||
if not index:
|
||||
return
|
||||
index, order, _ = index
|
||||
index, order = index
|
||||
order = 'rank {order}'.format(order=order)
|
||||
offset = 'offset %s'
|
||||
values.append(index)
|
|
@ -13,7 +13,7 @@ from . import DatabasePlugin
|
|||
@irc3.plugin
|
||||
class Rape(DatabasePlugin):
|
||||
requires = ['irc3.plugins.command',
|
||||
'nxy.plugins.storage']
|
||||
'bot.plugins.storage']
|
||||
|
||||
@command
|
||||
def owe(self, mask: IrcString, target: IrcString, args: DocOptDict):
|
|
@ -10,7 +10,7 @@ from . import DatabasePlugin
|
|||
@irc3.plugin
|
||||
class Useless(DatabasePlugin):
|
||||
requires = ['irc3.plugins.command',
|
||||
'nxy.plugins.storage']
|
||||
'bot.plugins.storage']
|
||||
|
||||
@irc3.event(r'^:(?P<mask>\S+) PRIVMSG (?P<target>#\S+) :s/'
|
||||
r'(?P<search>(?:[^/\\]|\\.)*)/'
|
|
@ -14,7 +14,7 @@ from . import DatabasePlugin
|
|||
@irc3.plugin
|
||||
class Seen(DatabasePlugin):
|
||||
requires = ['irc3.plugins.command',
|
||||
'nxy.plugins.storage']
|
||||
'bot.plugins.storage']
|
||||
|
||||
@command
|
||||
def seen(self, mask: IrcString, target: IrcString, args: DocOptDict):
|
||||
|
@ -62,10 +62,10 @@ class Seen(DatabasePlugin):
|
|||
seens (nick, host, channel, message, seen_at)
|
||||
values
|
||||
(%s, %s, %s, %s, %s)
|
||||
on conflict (nick) do update set
|
||||
on conflict (nick) do update set
|
||||
host = excluded.host,
|
||||
channel = excluded.channel,
|
||||
seen_at = excluded.seen_at,
|
||||
seen_at = excluded.seen_at,
|
||||
message = excluded.message
|
||||
''', [mask.nick, mask.host, target, msg, datetime.now()])
|
||||
self.con.commit()
|
|
@ -13,7 +13,7 @@ from . import DatabasePlugin
|
|||
@irc3.plugin
|
||||
class Tell(DatabasePlugin):
|
||||
requires = ['irc3.plugins.command',
|
||||
'nxy.plugins.storage']
|
||||
'bot.plugins.storage']
|
||||
|
||||
def __init__(self, bot: irc3.IrcBot):
|
||||
super().__init__(bot)
|
|
@ -15,7 +15,7 @@ from ..utils import time_delta
|
|||
@irc3.plugin
|
||||
class Timer(DatabasePlugin):
|
||||
requires = ['irc3.plugins.command',
|
||||
'nxy.plugins.storage']
|
||||
'bot.plugins.storage']
|
||||
|
||||
def __init__(self, bot: irc3.IrcBot):
|
||||
super().__init__(bot)
|
|
@ -9,6 +9,7 @@ from irc3.utils import IrcString
|
|||
from psycopg2 import Error
|
||||
|
||||
from . import DatabasePlugin
|
||||
from ..utils import re_generator
|
||||
|
||||
RAINBOW = (5, 7, 8, 9, 3, 10, 12, 2, 6, 13)
|
||||
RAINBOW_LEN = len(RAINBOW)
|
||||
|
@ -17,7 +18,7 @@ RAINBOW_LEN = len(RAINBOW)
|
|||
@irc3.plugin
|
||||
class Useless(DatabasePlugin):
|
||||
requires = ['irc3.plugins.command',
|
||||
'nxy.plugins.storage']
|
||||
'bot.plugins.storage']
|
||||
WOAH = (
|
||||
'woah',
|
||||
'woah indeed',
|
||||
|
@ -28,7 +29,7 @@ class Useless(DatabasePlugin):
|
|||
@irc3.event(r'(?i)^:(?P<mask>\S+) JOIN :(?P<target>#\S+)$')
|
||||
def tehkuh(self, mask, target):
|
||||
if re.search(r'(?i).*(tehkuh).*@.*(telefonica|vodafone|kabel|unity-media).*', mask):
|
||||
self.bot.privmsg(target, '{}: Bouncer'.format(nick))
|
||||
self.bot.privmsg(target, '{}: Bouncer'.format(IrcString(mask).nick))
|
||||
|
||||
@irc3.event(r'(?i)^:\S+ PRIVMSG (?P<target>\S+) :.*(woah|whoa).*$')
|
||||
def woah(self, target: str):
|
||||
|
@ -41,10 +42,10 @@ class Useless(DatabasePlugin):
|
|||
"""Returns a huehuehue when someone writes it."""
|
||||
self.bot.privmsg(target, msg)
|
||||
|
||||
@irc3.event(r'(?i)^:\S+ PRIVMSG (?P<target>\S+) :reeeeee$')
|
||||
@irc3.event(r'(?i)^:\S+ PRIVMSG (?P<target>\S+) :re+$')
|
||||
def reeeeee(self, target: str):
|
||||
"""Returns a REEEE."""
|
||||
self.bot.privmsg(target, 'REEEEEEEEEEEEEEEEEEEEEEEEEEEE')
|
||||
self.bot.privmsg(target, re_generator())
|
||||
|
||||
@irc3.event(r'(?i)^:\S+ PRIVMSG (?P<target>\S+) :same$')
|
||||
def same(self, target: str):
|
||||
|
@ -54,8 +55,7 @@ class Useless(DatabasePlugin):
|
|||
@irc3.event(r'(?i)^:\S+ PRIVMSG (?P<target>\S+) :\[(?P<msg>.*)\]$')
|
||||
def intensifies(self, target: str, msg: str):
|
||||
"""String with brackets around will be returned with INTENSIFIES."""
|
||||
self.bot.privmsg(target, '\x02[{msg} INTENSIFIES]'.format(
|
||||
msg=msg.upper()))
|
||||
self.bot.privmsg(target, '\x02[{} INTENSIFIES]'.format(msg.upper()))
|
||||
|
||||
@command
|
||||
def kill(self, mask: IrcString, target: IrcString, args: DocOptDict):
|
||||
|
@ -73,8 +73,8 @@ class Useless(DatabasePlugin):
|
|||
limit
|
||||
1
|
||||
''')
|
||||
self.bot.action(target, self.cur.fetchone()['item']
|
||||
.format(nick=args.get('<nick>') or mask.nick))
|
||||
nick = args.get('<nick>') or mask.nick
|
||||
self.bot.action(target, self.cur.fetchone()['item'].format(nick))
|
||||
|
||||
@command
|
||||
def yiff(self, mask: IrcString, target: IrcString, args: DocOptDict):
|
||||
|
@ -92,8 +92,8 @@ class Useless(DatabasePlugin):
|
|||
limit
|
||||
1
|
||||
''')
|
||||
self.bot.action(target, self.cur.fetchone()['item']
|
||||
.format(nick=args.get('<nick>') or mask.nick))
|
||||
nick = args.get('<nick>') or mask.nick
|
||||
self.bot.action(target, self.cur.fetchone()['item'].format(nick))
|
||||
|
||||
@command
|
||||
def waifu(self, mask: IrcString, target: IrcString, args: DocOptDict):
|
||||
|
@ -116,8 +116,7 @@ class Useless(DatabasePlugin):
|
|||
waifu = excluded.waifu
|
||||
''', [mask.nick, waifu])
|
||||
|
||||
self.bot.notice(mask.nick, 'Waifu set to: {waifu}'
|
||||
.format(waifu=waifu))
|
||||
self.bot.notice(mask.nick, 'Waifu set to: {}'.format(waifu))
|
||||
except Error as ex:
|
||||
print(ex)
|
||||
self.con.rollback()
|
||||
|
@ -133,9 +132,7 @@ class Useless(DatabasePlugin):
|
|||
result = self.cur.fetchone()
|
||||
|
||||
if result and result['waifu']:
|
||||
return '\x02[Waifu]\x0F {nick}: {waifu}'.format(
|
||||
nick=nick,
|
||||
waifu=result['waifu'])
|
||||
return '\x02[Waifu]\x0F {}: {}'.format(nick, result['waifu'])
|
||||
|
||||
@command
|
||||
def husbando(self, mask: IrcString, target: IrcString, args: DocOptDict):
|
||||
|
@ -158,9 +155,8 @@ class Useless(DatabasePlugin):
|
|||
husbando = excluded.husbando
|
||||
''', [mask.nick, nick])
|
||||
|
||||
self.bot.notice(mask.nick, 'Husbando set to: {husbando}'
|
||||
.format(husbando=nick))
|
||||
except Error:
|
||||
self.bot.notice(mask.nick, 'Husbando set to: {}'.format(nick))
|
||||
except Error as ex:
|
||||
print(ex)
|
||||
self.con.rollback()
|
||||
else:
|
||||
|
@ -175,9 +171,7 @@ class Useless(DatabasePlugin):
|
|||
result = self.cur.fetchone()
|
||||
|
||||
if result and result['husbando']:
|
||||
return '\x02[Husbando]\x0F {nick}: {husbando}'.format(
|
||||
nick=nick,
|
||||
husbando=result['husbando'])
|
||||
return '\x02[Husbando]\x0F {}: {}'.format(nick, result['husbando'])
|
||||
|
||||
@command
|
||||
def storyofpomfface(self, mask: IrcString, target: IrcString,
|
||||
|
@ -196,8 +190,7 @@ class Useless(DatabasePlugin):
|
|||
%%choose <items>...
|
||||
"""
|
||||
choice = random.choice(' '.join(args['<items>']).split(','))
|
||||
return '{nick}: {choice}'.format(nick=mask.nick,
|
||||
choice=choice.strip())
|
||||
return '{}: {}'.format(mask.nick, choice.strip())
|
||||
|
||||
@command
|
||||
def jn(self, mask: IrcString, target: IrcString, args: DocOptDict):
|
||||
|
@ -207,8 +200,7 @@ class Useless(DatabasePlugin):
|
|||
%%jn
|
||||
"""
|
||||
choice = random.choice(['3Ja', '4Nein'])
|
||||
return '{nick}: \x02\x03{choice}\x0F'.format(nick=mask.nick,
|
||||
choice=choice)
|
||||
return '{}: \x02\x030{}'.format(mask.nick, choice)
|
||||
|
||||
@command
|
||||
def kiss(self, mask: IrcString, target: IrcString, args: DocOptDict):
|
||||
|
@ -216,8 +208,7 @@ class Useless(DatabasePlugin):
|
|||
|
||||
%%kiss <nick>
|
||||
"""
|
||||
return '(づ。◕‿‿◕。)\x034。。・゜゜・。。・゜❤\x0F {nick} \x034❤'.format(
|
||||
nick=args['<nick>'])
|
||||
return '(づ。◕‿‿◕。)\x0304。。・゜゜・。。・゜❤\x0F {} \x0304❤'.format(args['<nick>'])
|
||||
|
||||
@command
|
||||
def hug(self, mask: IrcString, target: IrcString, args: DocOptDict):
|
||||
|
@ -225,7 +216,7 @@ class Useless(DatabasePlugin):
|
|||
|
||||
%%hug <nick>
|
||||
"""
|
||||
return '\x034♥♡❤♡♥\x03 {nick} \x034♥♡❤♡♥'.format(nick=args['<nick>'])
|
||||
return '\x0304♥♡❤♡♥\x0F {} \x0304♥♡❤♡♥'.format(args['<nick>'])
|
||||
|
||||
@command
|
||||
def bier(self, mask: IrcString, target: IrcString, args: DocOptDict):
|
||||
|
@ -233,8 +224,8 @@ class Useless(DatabasePlugin):
|
|||
|
||||
%%bier [<nick>]
|
||||
"""
|
||||
self.bot.action(target, 'schenkt ein kühles Blondes an {nick} aus.'
|
||||
.format(nick=args.get('<nick>') or mask.nick))
|
||||
nick = args.get('<nick>') or mask.nick
|
||||
self.bot.action(target, 'schenkt ein kühles Blondes an {} aus.'.format(nick))
|
||||
|
||||
@command
|
||||
def fucken(self, mask: IrcString, target: IrcString, args: DocOptDict):
|
||||
|
@ -242,8 +233,8 @@ class Useless(DatabasePlugin):
|
|||
|
||||
%%fucken [<nick>]
|
||||
"""
|
||||
self.bot.action(target, 'fuckt {nick} und tötet {nick} anschließend.'
|
||||
.format(nick=args.get('<nick>') or mask.nick))
|
||||
nick = args.get('<nick>') or mask.nick
|
||||
self.bot.action(target, 'fuckt {0} und tötet {0} anschließend.'.format(nick, nick))
|
||||
|
||||
@command
|
||||
def anhero(self, mask: IrcString, target: IrcString, args: DocOptDict):
|
||||
|
@ -269,7 +260,7 @@ class Useless(DatabasePlugin):
|
|||
%%hack [<nick>]
|
||||
"""
|
||||
nick = args.get('<nick>') or ''
|
||||
return 'hacking{nick}...'.format(nick=' %s' % nick if nick else '')
|
||||
return 'hacking{}...'.format(' %s' % nick if nick else '')
|
||||
|
||||
@command
|
||||
def gay(self, mask: IrcString, target: IrcString, args: DocOptDict):
|
||||
|
@ -300,9 +291,8 @@ class Useless(DatabasePlugin):
|
|||
|
||||
%%wrainbow <words>...
|
||||
"""
|
||||
return ' '.join([self._rainbow(i, word) for i, word
|
||||
in enumerate(args['<words>'])])
|
||||
return ' '.join([self._rainbow(i, word) for i, word in enumerate(args['<words>'])])
|
||||
|
||||
# noinspection PyMethodMayBeStatic
|
||||
def _rainbow(self, i, char):
|
||||
return '\x03{color}{char}'.format(color=RAINBOW[i % RAINBOW_LEN],
|
||||
char=char)
|
||||
return '\x030{}{}'.format(RAINBOW[i % RAINBOW_LEN], char)
|
|
@ -38,8 +38,7 @@ class Weather(Plugin):
|
|||
country=res['location']['country'],
|
||||
temp=res['item']['condition']['temp'],
|
||||
text=res['item']['condition']['text'],
|
||||
direction='↑↗→↘↓↙←↖'[round(int(res['wind']['direction'])
|
||||
/ 45) % 8],
|
||||
direction='↑↗→↘↓↙←↖'[round(int(res['wind']['direction']) / 45) % 8],
|
||||
speed=res['wind']['speed'],
|
||||
unit_temp=res['units']['temperature'],
|
||||
unit_speed=res['units']['speed'])
|
|
@ -68,15 +68,13 @@ class YouTube(Plugin):
|
|||
data = self._api(self.SEARCH, q=' '.join(args['<query>']))
|
||||
|
||||
if 'error' in data:
|
||||
return '[YouTube] Error performing search'
|
||||
return '\x02[YouTube]\x0F Error performing search'
|
||||
elif data['pageInfo']['totalResults'] is 0:
|
||||
return '[YouTube] No results found'
|
||||
return '\x02[YouTube]\x0F No results found'
|
||||
else:
|
||||
video_id = data['items'][0]['id']['videoId']
|
||||
return '{response} - https://youtu.be/{video_id}'.format(
|
||||
response=self.get_video_data(video_id),
|
||||
video_id=video_id,
|
||||
)
|
||||
data = self.get_video_data(video_id)
|
||||
return '{} - https://youtu.be/{}'.format(data, video_id)
|
||||
|
||||
@staticmethod
|
||||
def _api(url: str, **kwargs):
|
5
bot/server.py
Normal file
5
bot/server.py
Normal file
|
@ -0,0 +1,5 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import irc3d
|
||||
|
||||
if __name__ == '__main__':
|
||||
irc3d.run()
|
54
bot/utils.py
Normal file
54
bot/utils.py
Normal file
|
@ -0,0 +1,54 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
import random
|
||||
from pprint import pprint
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
TIME_UNITS = {
|
||||
's': 'seconds',
|
||||
'm': 'minutes',
|
||||
'h': 'hours',
|
||||
'd': 'days',
|
||||
'w': 'weeks',
|
||||
'mon': 'months',
|
||||
'y': 'years',
|
||||
}
|
||||
|
||||
pp = pprint
|
||||
|
||||
|
||||
def date_from_iso(date: str) -> datetime:
|
||||
return datetime.strptime(date, '%Y-%m-%dT%H:%M:%S.%fZ')
|
||||
|
||||
|
||||
def time_delta(text: str) -> timedelta:
|
||||
match = re.match(r'(\d+)(s|m|h|mon|w|y)', text)
|
||||
if match:
|
||||
num, unit = match.groups()
|
||||
num = int(num)
|
||||
unit = TIME_UNITS[unit]
|
||||
if unit == 'mon':
|
||||
num *= 4
|
||||
elif unit == 'y':
|
||||
num *= 52
|
||||
return timedelta(**{unit: num})
|
||||
|
||||
|
||||
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
|
||||
else:
|
||||
order = 'asc'
|
||||
if select:
|
||||
val -= 1
|
||||
return val, order
|
||||
except ValueError:
|
||||
pass
|
||||
|
||||
|
||||
def re_generator(low: int = 5, high: int = 20) -> str:
|
||||
return 'R{}'.format(''.join('E' for _ in range(random.randint(low, high))))
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"username": "nxy",
|
||||
"host": "znc.host",
|
||||
"port": 1337,
|
||||
"host": "localhost",
|
||||
"port": 6667,
|
||||
"ssl": true,
|
||||
"autojoins": ["#nxy-dev"],
|
||||
"flood_burst": 1,
|
||||
|
@ -9,22 +9,22 @@
|
|||
"flood_rate_delay": 1,
|
||||
"includes": [
|
||||
"irc3.plugins.uptime",
|
||||
"nxy.plugins.admin",
|
||||
"nxy.plugins.coins",
|
||||
"nxy.plugins.ctcp",
|
||||
"nxy.plugins.isup",
|
||||
"nxy.plugins.linux",
|
||||
"nxy.plugins.mcmaniac",
|
||||
"nxy.plugins.quotes",
|
||||
"nxy.plugins.rape",
|
||||
"nxy.plugins.regex",
|
||||
"nxy.plugins.seen",
|
||||
"nxy.plugins.tell",
|
||||
"nxy.plugins.timer",
|
||||
"nxy.plugins.urban",
|
||||
"nxy.plugins.useless",
|
||||
"nxy.plugins.weather",
|
||||
"nxy.plugins.youtube"
|
||||
"bot.plugins.admin",
|
||||
"bot.plugins.coins",
|
||||
"bot.plugins.ctcp",
|
||||
"bot.plugins.isup",
|
||||
"bot.plugins.linux",
|
||||
"bot.plugins.mcmaniac",
|
||||
"bot.plugins.quotes",
|
||||
"bot.plugins.rape",
|
||||
"bot.plugins.regex",
|
||||
"bot.plugins.seen",
|
||||
"bot.plugins.tell",
|
||||
"bot.plugins.timer",
|
||||
"bot.plugins.urban",
|
||||
"bot.plugins.useless",
|
||||
"bot.plugins.weather",
|
||||
"bot.plugins.youtube"
|
||||
],
|
||||
"irc3.plugins.command": {
|
||||
"guard": "irc3.plugins.command.mask_based_policy",
|
|
@ -5,9 +5,8 @@ After=network.target znc.service
|
|||
[Service]
|
||||
Type=simple
|
||||
User=nxy
|
||||
Environment=PYTHONPATH=/home/nxy/nxy
|
||||
WorkingDirectory=/home/nxy/nxy
|
||||
ExecStart=/home/nxy/.virtualenvs/nxy/bin/python nxy/bot.py config.json
|
||||
WorkingDirectory=/home/nxy/bot
|
||||
ExecStart=/home/nxy/.virtualenvs/nxy/bin/python -m bot
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
|
@ -72,11 +72,3 @@ create table if not exists last_messages (
|
|||
item text not null,
|
||||
unique (nick, channel)
|
||||
);
|
||||
|
||||
select
|
||||
item
|
||||
from
|
||||
last_messages
|
||||
where
|
||||
nick = lower('m')
|
||||
and channel = lower('nxy-dev');
|
|
@ -1,22 +0,0 @@
|
|||
rips off {user}'s legs and leaves them to die.
|
||||
grabs {user}'s head and rips it clean off their body.
|
||||
grabs a machine gun and riddles {user}'s body with bullets.
|
||||
gags and ties {user} then throws them off a bridge.
|
||||
crushes {user} with a huge spiked boulder.
|
||||
glares at {user} until they die of boredom.
|
||||
shivs {user} in the heart a few times.
|
||||
rams a rocket launcher up {user}'s ass and lets off a few rounds.
|
||||
crushes {user}'s skull in with a spiked mace.
|
||||
unleashes the armies of Isengard on {user}.
|
||||
gags and ties {user} then throws them off a building to their death.
|
||||
reaches out and punches right through {user}'s chest.
|
||||
slices {user}'s limbs off with a sharpened Katana.
|
||||
throws {user} to Cthulu and watches them get ripped to shreds.
|
||||
feeds {user} to an owlbear who then proceeds to maul them violently.
|
||||
turns {user} into a snail and salts them.
|
||||
snacks on {user}'s dismembered body.
|
||||
stuffs some TNT up {user}'s ass and waits for it to go off.
|
||||
puts {user} into a sack, throws the sack in the river, and hurls the river into space.
|
||||
goes bowling with {user}'s bloody disembodied head.
|
||||
sends {user} to /dev/null!
|
||||
feeds {user} coke and mentos till they violently explode.
|
|
@ -1,315 +0,0 @@
|
|||
Mc2GiaC
|
||||
Mc420iaC
|
||||
McAbhängiaC
|
||||
McAbnehmiaC
|
||||
McAdminiaC
|
||||
McAllesiaC
|
||||
McAmmoniaC
|
||||
McAniByteiaC
|
||||
McApothekiaC
|
||||
McArbeitiaC
|
||||
McAriaC
|
||||
McAssfistiaC
|
||||
McAstrophysiaC
|
||||
McAussichtiaC
|
||||
McAutistiaC
|
||||
McBSDiaC
|
||||
McBackForthiaC
|
||||
McBadboiaC
|
||||
McBehindiaC
|
||||
McBeileidiaC
|
||||
McBelstiaC
|
||||
McBertiaC
|
||||
McBlondiaC
|
||||
McBodybuildiaC
|
||||
McBotiaC
|
||||
McBroiaC
|
||||
McBuschiaC
|
||||
McChemtrailiaC
|
||||
McClaniaC
|
||||
McConnectiaC
|
||||
McCrackiaC
|
||||
McCubiaC
|
||||
McDafüriaC
|
||||
McDanceyiaC
|
||||
McDeadliftiaC
|
||||
McDefektiaC
|
||||
McDegradeiaC
|
||||
McDepressiviaC
|
||||
McDissiaC
|
||||
McDoktoriaC
|
||||
McDonaldiaC
|
||||
McDonaldsiaC
|
||||
McDonaldsmitterminaliaC
|
||||
McDotiaC
|
||||
McDreadiaC
|
||||
McDrogiaC
|
||||
McDruffiaC
|
||||
McEinhorniaC
|
||||
McExcercisiaC
|
||||
McFahrradiaC
|
||||
McFauliaC
|
||||
McFettiaC
|
||||
McFettsackiaC
|
||||
McFickDichiaC
|
||||
McFidelitiaC
|
||||
McFinallyHatWiederEinSSLCertiaC
|
||||
McFitiaC
|
||||
McFlaumiaC
|
||||
McFlummiaC
|
||||
McFoobariaC
|
||||
McFrostiaC
|
||||
McFuckiaC
|
||||
McFunkiaC
|
||||
McFühriaC
|
||||
McGFXiaC
|
||||
McGayiaC
|
||||
McGeburtstiaC
|
||||
McGehtimmerfrühonsBettiaC
|
||||
McGeilershitiaC
|
||||
McGeiliaC
|
||||
McGewichthebiaC
|
||||
McGleichgewichtiaC
|
||||
McGlitzerkugeliaC
|
||||
McGlitzermuscheliaC
|
||||
McGreisiaC
|
||||
McGriesgramiaC
|
||||
McGumoniaC
|
||||
McGutenMorgeniaC
|
||||
McGutenmorgeniaC
|
||||
McHDDdestroyeriaC
|
||||
McHaltetdochalleeurefressiaC
|
||||
McHartzIViaC
|
||||
McHashfagiaC
|
||||
McHashiaC
|
||||
McHaskelliaC
|
||||
McHebiaC
|
||||
McHeisenbergiaC
|
||||
McHelmiaC
|
||||
McHighiaC
|
||||
McHighlightiaC
|
||||
McHitleriaC
|
||||
McHollandiaC
|
||||
McHubbliaC
|
||||
McHübschiaC
|
||||
McIRCiaC
|
||||
McIchküssehierrumwiefickiaC
|
||||
McIchscheißaufsicherheitiaC
|
||||
McIdliaC
|
||||
McInfideliaC
|
||||
McInvalidiaC
|
||||
McIstimmermüdiaC
|
||||
McIstwiederdaiaC
|
||||
McJavascriptiaC
|
||||
McJogginghosiaC
|
||||
McJsisscheißiaC
|
||||
McJukeboxiaC
|
||||
McKanakiaC
|
||||
McKaputtiaC
|
||||
McKawaiiswagiaC
|
||||
McKeindoktoriaC
|
||||
McKeinschweißiaC
|
||||
McKinderfickiaC
|
||||
McKlabusterbeeriaC
|
||||
McKnastiaC
|
||||
McKnuddeliaC
|
||||
McKoksiaC
|
||||
McKomplettiaC
|
||||
McKonzentrationslageriaC
|
||||
McKotlplsiaC
|
||||
McKraftwerkiaC
|
||||
McKrankiaC
|
||||
McKreatiniaC
|
||||
McKrebsiaC
|
||||
McKuffariaC
|
||||
McKurdiaC
|
||||
McKüssiaC
|
||||
McLRSiaC
|
||||
McLauchiaC
|
||||
McLaufiaC
|
||||
McLayerwerbungiaC
|
||||
McLebtnureinmaliaC
|
||||
McLeichtsinniaC
|
||||
McLeschiaC
|
||||
McLiftiaC
|
||||
McLochinderschädeldeckiaC
|
||||
McLowprozessoriaC
|
||||
McLurchiaC
|
||||
McLustigiaC
|
||||
McLächerlichiaC
|
||||
McLösiaC
|
||||
McLügiaC
|
||||
McM1iaC
|
||||
McMCiaC
|
||||
McManiaC
|
||||
McManischdepressiviaC
|
||||
McMaschiniaC
|
||||
McMathematiaC
|
||||
McMathiaC
|
||||
McMaximiaC
|
||||
McMcManiaCiaC
|
||||
McMcMcMciaCiaCiaCiaC
|
||||
McMeddliaC
|
||||
McMeinuniaC
|
||||
McMemeiaC
|
||||
McMemiaC
|
||||
McMetaiaC
|
||||
McMethiaC
|
||||
McMidlifeCrisiaC
|
||||
McMilchreisiaC
|
||||
McMilfickiaC
|
||||
McMitgliediaC
|
||||
McMopediaC
|
||||
McMorgenmuffeliaC
|
||||
McMorniaC
|
||||
McMotorradiaC
|
||||
McMotziaC
|
||||
McMurukiaC
|
||||
McMuskeliaC
|
||||
McMuskelkateriaC
|
||||
McMuskelniaC
|
||||
McMüdiaC
|
||||
McNachtiaC
|
||||
McNamiaC
|
||||
McNatursektiaC
|
||||
McNaziaC
|
||||
McNerdiaC
|
||||
McNilsiaC
|
||||
McNixPeiliaC
|
||||
McNoClueiaC
|
||||
McNoHaskelliaC
|
||||
McNoMediziniaC
|
||||
McNochWachiaC
|
||||
McNopeiaC
|
||||
McNormalerSchlafrhythmusiaC
|
||||
McNormiaC
|
||||
McNorwegiaC
|
||||
McNuBSDiaC
|
||||
McNubiaC
|
||||
McOdroidiaC
|
||||
McOrciaC
|
||||
McOwealotiaC
|
||||
McOwiaC
|
||||
McPartymakeriaC
|
||||
McPausiaC
|
||||
McPedophiliaC
|
||||
McPeppiaC
|
||||
McPersoniaC
|
||||
McPortiaC
|
||||
McPrinzessinaufderErbsiaC
|
||||
McPrüdiaC
|
||||
McPumpiaC
|
||||
McPythoniaC
|
||||
McQsciaC
|
||||
McRIPiaC
|
||||
McRaidkilleriaC
|
||||
McRapeiaC
|
||||
McRauchiaC
|
||||
McRecycliaC
|
||||
McReißiaC
|
||||
McRepostiaC
|
||||
McRespectiaC
|
||||
McRetardiaC
|
||||
McRipiaC
|
||||
McRookiaC
|
||||
McRpiaC
|
||||
McRückwärtsalteriaC
|
||||
McScharfiaC
|
||||
McSchlafiaC
|
||||
McSchwitziaC
|
||||
McSchwuliaC
|
||||
McScrolliaC
|
||||
McServerlockiaC
|
||||
McSheytaniaC
|
||||
McShugoTenshiaC
|
||||
McSmetbiaC
|
||||
McSpaßverderbiaC
|
||||
McSpeediaC
|
||||
McSportiaC
|
||||
McSpätmerkiaC
|
||||
McStandhaftiaC
|
||||
McStarkiaC
|
||||
McStartssliaC
|
||||
McStatistiaC
|
||||
McStemmiaC
|
||||
McSterbiaC
|
||||
McStoßiaC
|
||||
McStripperiaC
|
||||
McSubmissiviaC
|
||||
McSztisttrauriaC
|
||||
McSüßiaC
|
||||
McTeamspeakiaC
|
||||
McTotalerkriegiaC
|
||||
McTraeumiaC
|
||||
McTsuiaC
|
||||
McUWiaC
|
||||
McUltraNubiaC
|
||||
McUmlautiaC
|
||||
McUnfaehigiaC
|
||||
McUngläubiaC
|
||||
McUnixiaC
|
||||
McUnwetteriaC
|
||||
McUwiaC
|
||||
McVapeiaC
|
||||
McVapiaC
|
||||
McVerdieniaC
|
||||
McVergasiaC
|
||||
McVergewaltiaC
|
||||
McVerrücktiaC
|
||||
McVerschwöriaC
|
||||
McVertretiaC
|
||||
McVoluminösiaC
|
||||
McVorDieHaustuereGekacktiaC
|
||||
McWaffelteigiaC
|
||||
McWankiaC
|
||||
McWeakiaC
|
||||
McWeckiaC
|
||||
McWeediaC
|
||||
McWerdeniebezahliaC
|
||||
McWerkiaC
|
||||
McWettkampfiaC
|
||||
McWhoriaC
|
||||
McWortwolkiaC
|
||||
McZeltiaC
|
||||
McZubreitfürdenspiegeliaC
|
||||
McalwaysonlineiaC
|
||||
McediTiaC
|
||||
McgegenteiliaC
|
||||
McÖdiaC
|
||||
McSchwuliaC
|
||||
McSelbsttriggertriggeriaC
|
||||
McUngläubiaC
|
||||
McParanoiaC
|
||||
McWaliaC
|
||||
McWaldiaC
|
||||
McTreniaC
|
||||
McBurkiaC
|
||||
McSchnefalliaC
|
||||
McAmmoniaC
|
||||
McAmmoniaC
|
||||
ichbingarkeinmaniac
|
||||
McThcZäpfcheniaC
|
||||
McImperativiaC
|
||||
McGysiaC
|
||||
McDrogiaC
|
||||
McGefängnisiaC
|
||||
McArschseksiaC
|
||||
McKommentarboxeinfachdirektunterdemletztenkommentariaC
|
||||
McHeisseOhreniaC
|
||||
McManiulo
|
||||
McRallyaC
|
||||
McMöchtiaC
|
||||
McOdroidiaC
|
||||
McRektiaC
|
||||
McMemeiaC
|
||||
McHantelstangiaC
|
||||
Mc1iaC
|
||||
McNixfunktioniertiaC
|
||||
McBigMac
|
||||
McExtremstschwuliaC
|
||||
McSchnelliaC
|
||||
McRomantiaC
|
||||
McOssiaC
|
||||
McHaskelliaC
|
||||
McSchlafiaC
|
||||
McGenderiaC
|
|
@ -1,185 +0,0 @@
|
|||
asks if {user} would like to dock and he happily agrees. The two giraffe dongs slosh into each other as the two sexy gorfs make out
|
||||
bounces all around {channel}, focusing on {user} and {yiffer}. *PANT PANT* (drags is dingo cock on the ground) "hey guise!! which one of you wants to plow my dirty dog baloon knot??"
|
||||
brushes his large zebradong against {user}'s asshole. {user} quickly screams "PUT IN IN ME" and {nick} obeys hir request. Then, {user} becomes jealous and gallops over to face fuck {user}.
|
||||
busts a huge creamy yiffload all over {user}
|
||||
can't help but fuck the everliving shit out of {user} with a huge foxdick
|
||||
can't take anymore, he gasps for his breath as he unloads his potent fox seed all over {user}'s turtle tits
|
||||
caresses {user}'s furry ballsack, inhaling {user}'s sweet musk through his nostrils, his member starting to grow from all the sensations
|
||||
clenches his firm, supple buttocks around the throbbing purple head of {user}'s skunkcock
|
||||
climbs on top of {user} and roars as she buttfucks the horny lion
|
||||
continues swirling her tongue around against {user}'s, as she guides one of his hands down to the waistband of her skirt, pushing the tips of his fingers between her panties and skirt
|
||||
creates a disgusting, putrid odor in {channel} causing several users to vomit onto each other, including {user} and {yiffer}. {nick} blushes when she sees what she has caused
|
||||
critches the inside of {user}'s rosebud with his entire hand while lapping up the fountain of badger butter escaping from {user}'s engorged member
|
||||
drags a foxy claw across the ridges {user}'s circumcision scar.
|
||||
drinks from the pool of thick giraffe jizzum that {user} and {yiffer} have been creating in the corner of {channel}
|
||||
enflames her smegmated goosepussy, hoping that {user} notices! "Aim for the slightly red stained feathers!" *flap flap*
|
||||
engulfs {user}'s wolfcock, relishing the salty taste of the his precum
|
||||
exposes his sheath to {user}, while slowly raising his tail as if to invite
|
||||
eyes that splurt of cockjuice with interest, using her tail to then push it firmly up against {user}'s ass, nudging the head against the open ring of flesh.
|
||||
feels {user}'s knot throbbing inside him, each pulse unleashing a fire hot load deep in his bowels, sating his lust momentarily
|
||||
felt {user}'s lukewarm wolfhood enter him time and time again, making his pussy lips twitch and love juice flow incessantly.
|
||||
fills {user} with giraffe juice creating a beautiful roselike odor in {channel}
|
||||
flaps his wings wildly as {user} pounds him mercilessly, all while giving his duck dong a firm handshake with his free paw
|
||||
gallops gingerly over to {user}'s bed and sits on the corner, showing his fangs in a friendly way. Suddenly {nick} slides his rump down {user}'s bedsheets, leaving a horrible nasty brown streak that smells like musk!!
|
||||
gallops over to {user} and attempts to plug his massive gorfdong into her tight gorfgina, but {user} quickly knocks over {nick} with her large, spotted neck and slams her wet giraffe meat into {nick}'s butthole
|
||||
gave {user} a nice and solid kick, making him collapse onto the floor, cupping {user}'s foxballs.
|
||||
gently slides his paw over {user}'s right foot while gliding a finger over his tailhole in anticipation
|
||||
gets a firm grip on {user}'s hip as he thrusts his foxhood deep within his tight and inexperienced tailhole, unexpectedly ramming his knot causing an orgasm of pain and pleasure for {user}
|
||||
gleefully backs his volerectum firmly into {user}'s cloaca, hoping that {user} is a snake... SHOW ME YOUR HEMIPENE AND RAPE MY SHITTER BITCH!
|
||||
grabs {user}, twirls him around like a dancer and places a kiss on his lips, fondling his tailhole for a second so he can taste it later
|
||||
grunts as he feels sthe plastron of {user}'s shell rubbing him raw, but moans as he feels {user}'s dick stiffen inside him and his thrusting speeds up
|
||||
gyrates her ferret-giner into {user}'s face, forcing him to take in the scent of stale urine and cedar chips...
|
||||
hops onto {user}'s lap, her bare crotch resting on his pants, and getting them a little wet from her dripping juices
|
||||
howls with pleasure as {user} pulls his knot out of his hole, stretching it to an obscene size before a loud "POP" is heard and {user}'s squirreljuice cascades down his already drenched thighs
|
||||
initiates the cuddle pile of Cthulu! Fuzzy tentacles being to lash out and drag {user} into the maw of Murrrrr.
|
||||
inserts a giner into {user}'s raccoon sheef, pumping in and out to create sheefsounds of varying pitches and phonetic properties
|
||||
is plundging deep into {user}'s anal cavity, getting fur all over the place
|
||||
is puzzled by {user}'s single cock as it's pressed against his chest stomach.
|
||||
jumps out of {user}'s packpack and sticks her butt out at {user}, revealing her bare butt cheeks her clenched asshole and pink pussy lips, and waving her tail around at him
|
||||
knocks {user} back a few feet with a stream of hot jizzum!
|
||||
lactates into a jar and hands it to {user}. {user} quickly becomes jealous of the gift and proceeds to knock the jar out of {user}'s paws and happily slurps up the man milk
|
||||
lays on her back and sticks a finger into her pussy, spreading the lips of her pussy apart with her other hand and showing {user} the little cherry-clit between the spread mounds
|
||||
lays under {user}, her bare crotch covered in her juices
|
||||
lets loose a hot steamy load all over {user}'s tongue!
|
||||
lets out a low moan as {user}'s tongue rubs against hers, sharing their saliva and spreading the lollipop sugar onto his tongue
|
||||
lets out an excited squeal as {user} walks into the back yard, and hopes he doesn't see her laying back in a lawn chair naked
|
||||
lets out a sigh of pleasure, and putting her hand on top of {user}'s, guides his hand to be cupping around her small titty, pressing her nipple between two of his fingers, and sliding his fingers back and forth against it
|
||||
lets out small gasps as {user} gets closer to her nipples, her shirt riding up on his arm to the point where it isn't really covering much of her anymore
|
||||
lets out small gasps as {user}'s hand touches her sensitive nipple directly
|
||||
lets the last of her pee trickle out of her onto the floor around {user}, before she sits on the floor in front of him, his seated face right in line with her clit
|
||||
licks along {user}'s silky lips, taking {user}'s exposed foxhood and plays with the tip, rubbing the underside with his thumb slowly towards the tip
|
||||
licks {user}'s chest at the same place where he poked her and says, "mmmm it sure is nice and warm there" as she plants small kisses on the spot, licking his bare skin
|
||||
lifts up pulls down {user}'s pants, showing her panties to {user} and says, "hey {user}, why don't you help {user} out of those naughty panties?"
|
||||
looks around {channel} for her love... WHERE ARE YOU {user}??? oh there you are!! {nick} plants a wet donkey kiss on {user}'s furry cock head, fully expecting to get raped in response!!
|
||||
looks at {user} and asks, "hey what cup size are your boobies? =D"
|
||||
looks at {user} and notices he is covered in pee too
|
||||
looks at {user}'s undies in her hand
|
||||
looks down at her tightened cooch, smiling at {user} and giving him a kiss on the tip of his nose
|
||||
looks longingly at {user}'s moist falcon cock.... pushing aside the silken down and grabbing its base... suddenly {nick} whips out some Gold Bond(R) with menthol, and sprinkles it on {user}'s wet bird of prey dong!!! {user} caws and shrieks in pain, slashing {nick}'s face with his flight feathers!! YOU ASSHOLE it always come down to abuse!!
|
||||
looks up and waves at {user}, spreading her pussy lips open for him to get a good view inside of her 9-year-old slit
|
||||
looks up at {user} with a cute wide-eyed look. Hir sweet ice-cream tasting pom-pom is nibbled on, moaning even louder before clinging to hirself tightly at feeling of the licks at hir sensitive pompom. "ahh ahh!! oh! kupopo!!"
|
||||
Masterbates, shoots a load into {user}'s right eye and with a single motion shares the love with @ {user}'s left eye. Then {nick} wipes the excess and tickles {user}'s nose simultaneously with his oh so tiny asian cock, and then finalizes the deal with a free rectal exam.
|
||||
milks his cock and drizzles pre into the coffee pot to see if {user} can taste the difference.
|
||||
moans, "aahh... mmm. aaahh..." as {user}'s finger moves around inside of her pussy, her juices seeping out onto his hand
|
||||
mounts {user} and pumps in and out hard
|
||||
moves over towards {user} and shoves a huge red rocket in thier mouth
|
||||
murrs as he slides his paw over {user}'s throbbing raccoon cock
|
||||
murrs, humping softly against {user}'s hand, twisting the tip of his finger into {user}'s lovingly rendered anus
|
||||
neighs and shudders as his cockhead flares and spews his buttery load, almost choking {user}
|
||||
nibbles softly on the carrot potruding from {user}'s juicy hole as {user}'s fluffy bunnytail tickle's his face
|
||||
notices {user} is leaking a pink liquid out of his anus and he gallops over to go drink the cloudy butt juice. The strange rectum goo is sweet and tastes like a combonation of strawberries and love
|
||||
notices {yiffer} buttfucking {user} while {user} screams. {nick} pulls out his rock hard monster of a gorfdong and uses it shut up {user}. {yiffer} thanks {nick} and continues fucking his prey
|
||||
opens her legs all the way and faces {user}, giving him a complete view of her pussy
|
||||
opens her lips slightly, and probes {user}'s larger lips with her lollipop-sugar-coated tongue
|
||||
opens his trap door in the desert floor and scurries over to {user}, trying to get at her succulant scorpion snatch! {user} sees this coming and slams her stinger into the sand, failing to realize that a spider is a small and fast target. {nick} drags {user} out of his trap and throws the web-encrusted prize at {user}, momentarily stunning her!
|
||||
pants as {user}'s dripping wet pokeball rests in her hand, and she tosses it to the ground, releasing him as she tries to catch her breath from all the pushing she did
|
||||
parts {user}'s buttcheeks and moves his cock into their anus
|
||||
peers anxiously at {user}'s encrusted, pulsating wolverine anus... I can't take it any longer, UNLOAD YOUR LOG ON ME BABY!!! {yiffer} can watch!
|
||||
picks up {user} and glares at him "look what you did to me" she says as she puts his head in the gaping hole of her pussy
|
||||
picks up {user} out of the puddle, and takes off all of his pee-covered clothes, licking and sucking the pee out of them, swallowing, and saying, "yummmmmy!"
|
||||
pokes a finger into {user}'s moist sheath, tasting the tip of his finger in excitement
|
||||
props {user}'s dead furry body over his chair and furiously humps, climaxing into his cold cadaver
|
||||
pulls both of {user}'s hands onto her butt cheeks
|
||||
pulls down {user}'s pants and points to the hole in the tip of his penis
|
||||
pulls off her dress and rubs her fuzzy back against {user}'s chest
|
||||
pulls the neck of {user}'s shirt down to show her nipples as she says, "i'm flat as a board, see!"
|
||||
pumps gallons of jizz all over {user} !
|
||||
pushes down on {user}'s rock hard wolf-cock with his palm, sliding around with his precum
|
||||
pushes down onto {user}'s lap with his weight, thrusting {user}'s knot deep within his tailhole
|
||||
pushes off of {user}'s shoulders with her hands and quickly pulls her panties down to her knees, the small wet spot right against his nose as her bare pussy rubs on the back of his neck
|
||||
pushes people aside just so he can shoot his load all over {user}'s face!
|
||||
pushes {user} feet first into her cunt and squeezes her muscles down on him, burrying him so only his head is sticking out of her pussy
|
||||
pushes {user} out until he is only buried waist deep inside of her, pushes his hands up onto her clit and says, "hold on tight, i'm going to pee on you for being mean to me and stretching me out"
|
||||
pushes {user}'s head into her crotch as he stimulates her clit, his finger still slipping in and out of her pussy, her breath coming in shorter gasps now as she says, "{user}... i'm feeling... aahhh... oooohh i'm feeling so gooooooood.... uuuhhhh"
|
||||
pushes up with her legs against the couch, her head popping out of the collar of {user}'s shirt, and with their faces pressed up against eachother's, she plants a kiss on his lips
|
||||
puts a finger in her 9-year-old asshole, "stick it right in here {user}, get your penis nice and wet in my mouth before you stick it in so it slides easy"
|
||||
puts her arms around {user}'s neck and says as she wraps her legs and bare crotch around {user}'s waist, "oh really? what else did they teach you there?"
|
||||
puts her hand in {user}'s underwear
|
||||
puts her hands on {user}'s crotch and says, "see, it's right here! i can feel it moving around too =D"
|
||||
puts his fingers on {user}'s mouth to shush him as he starts working his throbbing foxhood
|
||||
puts his muzzle between {user}'s smooth thighs and starts lapping at her slippery clit
|
||||
puts on a two-piece bathing suit and opens the door, running past {yiffer} and jumping into {user}'s arms, saying, "look, now i can be almost naked but still have clothes on!" as she places his hand on her bare stomach
|
||||
puts {user} in her mouth, licking all over him
|
||||
raises her hips a little as {user}'s finger slides into her, causing it to slip in even further into her drenched pussy, and says, "mmmmmm that's really good {user}, keep your finger there"
|
||||
raises her tail high, showing {user} her blood engorged claoca from accross the irc channel, hoping to lure him into a mid-chat yiff
|
||||
reaches backwards and rubs her hands against {user}'s sides, slipping her hands under his shirt and rubbing along his body
|
||||
really wants to blow a load all over {user}'s face but needs time to reload!
|
||||
releases his musk all over {user}'s face to try to entice him into digging his tongue deeper into his raccoongina
|
||||
ribbits and scales up {user}'s left rear leg and reaches her buffalo cunt. "*ribbit* OH MY GOD it smells like garlic and a bowl of shit, {user}!" {nick} exclaims. Being a good sport, {nick} uses his long, slender tongue and attacks {user}'s Buff-V-Jay!! "EWW it tastes like smegma!! {user} try this shit!"
|
||||
rubs against {user}'s large gorf penis causing it to become erect and thick. {nick} winks to {user} which gives her the signal to slam the blood filled sausage into {nick}
|
||||
rubs his petite bottom on {user}'s well-endowed raccoon-cock ^_^
|
||||
rubs {user}'s footpaws while groping at his crotch with his feet =^____^=
|
||||
rubs {user}'s hard knot while reaching back for some extra tailhole fun =^___^=
|
||||
rubs the strapon on {user}'s vagina, getting it wet with her juices before pushing the tip of it into her pussy, slowly pushing it farther until it is half way in
|
||||
rubs the tip of her strapon on {user}'s panties, and giggling at the wet spot forming there
|
||||
runs her own tongue along {user}'s, tasting her sweet saliva before examining her new cock, running her hands along its length and the pointed head
|
||||
runs his fingers along {user}'s soft and slender thighs, running up to his partially erect wolfhood
|
||||
runs his fingers through {user}'s silky fur, rubbing his ear to get him excited
|
||||
runs over to {user} on top of {yiffer}, pulls down his pants and underwear and chants as she dances around them, "i see your pee pee, i see your pee pee"
|
||||
says, "here it comes...!" as the stream of her pee gushes out from below her clit onto {user}'s stomach and waist, dripping all over him and her crotch
|
||||
says, "she made me put on this 1 piece" as she stands up in the water, showing {user} her one-piece bathing suit, her flat chest showing her hard nipples sticking out
|
||||
screams "Go Go Gadget Penis" and shoots a load all over {user}'s face
|
||||
screams in pleasure as he shoots pink jizzum into {user}'s eyes
|
||||
's dolpindongue *EXPLODES* in a torrent of cum which painfully impacts {user}'s skull, causing {user} to lose some hair. {nick} suddenly slams {user} in the lower neck with a fin, dealing a serious blow and knocking him unconcious. EEEK EEEK EEEK!!! {nick} forces his 15 inch dolphinwang into {user}'s asshole, immediately tearing and prolapsing it.
|
||||
shakes her booty at {user} as she says, "hey lookie, i'm only wearing paaanties!"
|
||||
shoots his load all over {user}'s face!
|
||||
shoves his talons into {user}'s minature penis, making {user} squeel in pain
|
||||
shreeks as his foot long cock explodes into {user}'s wet shithole. {nick} then rudely makes a mess of {user}'s pots and pans
|
||||
shrugs, and pulls her shirt off over her head, putting {user}'s other hand onto her stomach, and pushing his first hand closer to her hard pink nipples
|
||||
sits down and wags his tail, peering up at {user} with puppy eyes... then looks at {yiffer}, and again back to {user}.... {nick} wants something, can you guess what it is? Are you still a K-9 virgin?
|
||||
sits on {user}'s lap, her butt positioned on his crotch
|
||||
slams his giraffe meat into {user} whilst being pumped in and out of by {yiffer}, creating a gorf train orgy
|
||||
slaps {user}'s large penis around a bit
|
||||
slides her tongue out, and running it across {user}'s cheek and down onto his neck, asks, "is it OK if {yiffer} joins us?"
|
||||
slides his lumpy, steamy bear sausage into {user}'s tight butthole. {nick} pumps in and out of the boy pussy until he sprays a thick jizzum into {user}'s colon
|
||||
slides his throbbing wolfhood along {user}'s luscious breasts, leaving a trail of precum along her sweat-glistened chest
|
||||
slides two fingers into {user}'s tight and firm vagina while fondling hir sheathe
|
||||
slids his rock hard skunk penis into {user}.
|
||||
slips his tongue into {user}'s moist sheath, taking in all the flavors of his raccoon musk
|
||||
slithers around {channel} and targets {user} who seems to be lookin pretty sexy! "Hey tough guy" *exposes his distended rattlesnake anus* "Throw your cockroach cock up there!" *wafts the scent of stale snakejizz and urine at {user} to get his attention*
|
||||
slowly glides through the air. {nick} spots {user}, and gets closer. He is a much bigger bird than you thought... human-sized, in fact. {nick} lands by {user}, which is when {user} notices this bird has a huge erect cock... {nick} winks at you, and slams a claw-laden foot onto your back -- You bout to get yiffed, son.
|
||||
smiles at {user} and says, "i'm not naked! look, i'm still wearing my shirt! but i'm good, {user} made a big pokeball come out of my pussy =(" she says as she shows him her stretched pussy
|
||||
smiles at {user} and slides his hand onto her left breast "and how about now? can you feel it beating faster?"
|
||||
snickers and, sticking out her tongue, starts to run it all over {user}'s chest
|
||||
sniffs {user}'s smooth cloaca before swiping his forked tongue up and down on it, tasting hir spicy juices
|
||||
snuggletackles {user} and starts romping on top of him =^____^=
|
||||
spooges all over {user}'s face, then cock slaps {user} into a wall!
|
||||
spreads her butt cheeks open, showing {user} her asshole and says, come on, just push it right inside of me, i want to feel good too!
|
||||
spreads her pussy lips apart "is it ok in here {user}?"
|
||||
spreads the lips of her pussy for {user} to see, "yeah, see right here it's sore when you rub it she says as she points to her clit
|
||||
's pussy starts to seep warm lubricant onto {user}
|
||||
squawks and chatters at {user} while beating his parrot wings...! {nick} vengefuly claws {user} in the face and then swoops down and gets a painful grip on {user}'s bisonjunk... {user} can't reach {nick} down there!! {nick} pecks lovingly at the jerky meat and bobs his head up and down "POLLY WANT A COCK??? CAWWW!"
|
||||
squeezes {user}'s meaty dragon vent, while giving him a reach-around.
|
||||
starts bucking her hips at the same fast rhythm as {user}'s finger rubs inside her, breathing faster and faster until her head starts going numb, her body moving on its own as she moans out, "oooo {user}..!! i'm cum... i..i...aaaAAAHHHH!!"
|
||||
starts hurting {user} with a huge fur dildo
|
||||
starts to bleed out of his rectum, creating a lube for {user} to use as he mercifully tears apart {nick}'s anus
|
||||
strokes her hard, thick whalecock until it bursts all over {user} and his faggot friend {yiffer}
|
||||
strokes {user}'s flank, nuzzling up to his soft furry neck as they spoon
|
||||
sucks the pee off of {user}, collecting it all into a large spit ball and splashing it on him, before sucking it off again and gulping it down, spitting out the naked, showered, {user}
|
||||
squats down over {user} as he lays on the floor, gently (not hard enough to crush him and still letting him breathe) pressing her butt on him, his head sticking out over her pussy, as she smiles at him and says, "hi =3"
|
||||
swims around {channel} trying to get attention. "Hey {user}, have you ever read dolphinsex.org? YOU'RE GONNA NEED IT!!"... {user} gets gorfed in the blowhole by {nick}'s gargantuan frankenfurter from the fatherland! EEK *BAM* EEEK *BAM* EEEK EEK EEEEEK *BAM* *BAM BAM* EEEKEEEKEKEKEEEEEKEEEE!!!!
|
||||
tailwavies~ at {user}, showing him his engorged, dripping wolfhood
|
||||
takes advantage of {user}
|
||||
takes a painfully hard grip on {user}'s foxhood from behind and rams his knot right up his virgin tailhole
|
||||
takes {user} and ravages them from behind with a huge fox boner.
|
||||
takes {user} from {yiffer} and slaps his bare back on her mounds, chanting, "pussy pussy pussy!"
|
||||
takes {user}'s entire length into his mouth, gagging as he swallows the knot
|
||||
takes {user}'s hard rod into his maw and begins suckling like one would their mother's breast =^____^=
|
||||
ties up {user} and scrapes her jaguarginer looking for lint and smegma... GOT IT! {nick} forcefully smears the disgusting musty mess up {user}'s nose, and roars at {user} to keep them the fuck away during the torture session.
|
||||
touches snoot to nose, licks, sets {user} down o..o
|
||||
trails his fingers down {user}'s scaly underside to her sensitive claoca, feeling the heat before dipping his fingers into the moist honeypot
|
||||
tries to go down on {user}'s sweet raccoon-gina, but is pushed back by hir throbbing cock
|
||||
trips {user}'s hind legs and squishes her sealion snatch against {users}'s semi-hard bison battering ram. {nick} gets hooflammed in the skull and shrieks, then cries, looking at {yiffer} hoping for help!!
|
||||
tugs and tugs his walleyedong! (_))█████████████████████D ~~~ * {nick} swims around and gleefully sucks up his own swimmers, fighting off {user} who stops by to investigate and attempts to steal {nick}'s fishshizz!! FUCK OFF BUDDY
|
||||
turns around and slides down {user}'s chest, her flat loli nipples rubbing on his tummy as she drops to the ground, turning once more and showing everybody her flat chest
|
||||
twirls around {user}'s long llama-neck, planting a kiss on his big slimy mouth
|
||||
utters "mmmhh.... aahhh" into {user}'s ear as she breathes in and out, guiding {user}'s hand farther and farther up onto her chest, {nick} sadfaces at {user}... baby you know I want to musk you but I can't, I already used it on {yiffer}!!!
|
||||
vigorously tugs his downy-soft feather covered parrot schlong, excitedly bobbing his head up and down trying to get attention from {user}... "SQUAAAK! polly wants a cock, polly wants a cock!!"
|
||||
vomits into {user}'s mouth as he ejactulates onto the floor. {user} swallows the half digested pizza rolls and rolls around in the pool of cum
|
||||
was about to shoot a load but realized it was only {user} and decided against it
|
||||
watches {user} devour {yiffer}'s wolfcock as while touching his own racoon pussy. {nick} then teams up with {yiffer} to spitroast {user}.
|
||||
wraps his hands around {user}'s back, moving downward while kissing along his soft yet sturdy chest and abs
|
||||
writhes in pleasure as {user}'s gazellehood's head flare inside him, massaging his most inner nooks and cranies with each thrust
|
||||
writhes with pleasure as {user}'s meaty tapir dick pounds his sensitive turtlehole as {user} nuzzles at hir neck with his snout
|
||||
yells to {yiffer} to help him gangbang {user}. {yiffer} agrees to assist {nick} and they happily fuck {user} raw
|
||||
yiffs all over {user}
|
165
nxy/migrate.py
165
nxy/migrate.py
|
@ -1,165 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import os
|
||||
import sqlite3
|
||||
from datetime import datetime
|
||||
|
||||
import psycopg2
|
||||
from dotenv import load_dotenv
|
||||
from psycopg2 import Error
|
||||
from psycopg2.extras import DictCursor
|
||||
|
||||
load_dotenv(os.environ.get('DOTENV_FILE', '.env'))
|
||||
con = psycopg2.connect(os.environ['DATABASE_URI'])
|
||||
cur = con.cursor(cursor_factory=DictCursor)
|
||||
|
||||
old = sqlite3.connect(os.path.join('migrate', 'old.db'))
|
||||
old.row_factory = sqlite3.Row
|
||||
old_cur = old.cursor()
|
||||
|
||||
|
||||
def migrate_mcmaniacs():
|
||||
with open('migrate/mcmaniacs.txt', 'r') as fp:
|
||||
for m in fp:
|
||||
try:
|
||||
cur.execute('''
|
||||
insert into
|
||||
mcmaniacs (item)
|
||||
values
|
||||
(%s)
|
||||
''', [m.strip()])
|
||||
con.commit()
|
||||
except Error as ex:
|
||||
print(ex)
|
||||
con.rollback()
|
||||
|
||||
|
||||
def migrate_kills():
|
||||
with open('migrate/kills.txt', 'r') as fp:
|
||||
for m in fp:
|
||||
try:
|
||||
cur.execute('''
|
||||
insert into
|
||||
kills (item)
|
||||
values
|
||||
(%s)
|
||||
''', [m.replace('{user}', '{nick}').strip()])
|
||||
con.commit()
|
||||
except Error as ex:
|
||||
print(ex)
|
||||
con.rollback()
|
||||
|
||||
|
||||
def migrate_yiffs():
|
||||
with open('migrate/yiffs.txt', 'r') as fp:
|
||||
for m in fp:
|
||||
try:
|
||||
cur.execute('''
|
||||
insert into
|
||||
yiffs (item)
|
||||
values
|
||||
(%s)
|
||||
''', [m.replace('{user}', '{nick}').strip()])
|
||||
con.commit()
|
||||
except Error as ex:
|
||||
print(ex)
|
||||
con.rollback()
|
||||
|
||||
|
||||
def migrate_quotes():
|
||||
old_cur.execute('''
|
||||
select
|
||||
*
|
||||
from
|
||||
quote
|
||||
''')
|
||||
|
||||
for q in old_cur.fetchall():
|
||||
try:
|
||||
cur.execute('''
|
||||
insert into
|
||||
quotes (nick, item, channel, created_by, created_at)
|
||||
values
|
||||
(%s, %s, %s, %s, %s)
|
||||
''', [q['nick'].strip(),
|
||||
q['msg'].strip(),
|
||||
q['chan'].strip(),
|
||||
q['add_nick'].strip(),
|
||||
datetime.fromtimestamp(q['time'])])
|
||||
con.commit()
|
||||
except Error as ex:
|
||||
print(ex)
|
||||
con.rollback()
|
||||
|
||||
|
||||
def migrate_seens():
|
||||
old_cur.execute('''
|
||||
select
|
||||
*
|
||||
from
|
||||
seen
|
||||
''')
|
||||
|
||||
seens = {}
|
||||
for s in old_cur.fetchall():
|
||||
nick = s['name'].strip()
|
||||
s = [nick,
|
||||
s['host'].strip(),
|
||||
s['chan'].strip(),
|
||||
s['quote'].strip(),
|
||||
s['time']]
|
||||
|
||||
if nick not in seens or s[4] > seens[nick][4]:
|
||||
seens[nick] = s
|
||||
|
||||
for s in seens.values():
|
||||
s[4] = datetime.fromtimestamp(s[4])
|
||||
|
||||
try:
|
||||
cur.execute('''
|
||||
insert into
|
||||
seens (nick, host, channel, message, seen_at)
|
||||
values
|
||||
(%s, %s, %s, %s, %s)
|
||||
''', s)
|
||||
con.commit()
|
||||
except Error as ex:
|
||||
print(ex)
|
||||
con.rollback()
|
||||
|
||||
|
||||
def migrate_users():
|
||||
old_cur.execute('''
|
||||
select
|
||||
*
|
||||
from
|
||||
users
|
||||
''')
|
||||
|
||||
for u in old_cur.fetchall():
|
||||
husbando = u['husbando'].strip() if u['husbando'] else None
|
||||
waifu = u['waifu'].strip() if u['waifu'] else None
|
||||
fines = u['fines'] or None
|
||||
|
||||
if husbando or waifu or fines:
|
||||
try:
|
||||
cur.execute('''
|
||||
insert into
|
||||
users (nick, husbando, waifu, fines)
|
||||
values
|
||||
(%s, %s, %s, %s)
|
||||
''', [u['nick'].strip(),
|
||||
husbando,
|
||||
waifu,
|
||||
fines])
|
||||
con.commit()
|
||||
except Error as ex:
|
||||
print(ex)
|
||||
con.rollback()
|
||||
|
||||
|
||||
migrate_kills()
|
||||
migrate_yiffs()
|
||||
migrate_mcmaniacs()
|
||||
migrate_quotes()
|
||||
migrate_seens()
|
||||
migrate_users()
|
|
@ -1,17 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from pprint import pprint as pp
|
||||
|
||||
from .date import date_from_iso, time_delta, time_since
|
||||
from .misc import NICK_REGEX, parse_int
|
||||
|
||||
__all__ = (
|
||||
# pprint alias
|
||||
'pp',
|
||||
# date and time stuff
|
||||
'date_from_iso',
|
||||
'time_delta',
|
||||
'time_since',
|
||||
# misc
|
||||
'NICK_REGEX',
|
||||
'parse_int',
|
||||
)
|
|
@ -1,84 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
|
||||
def date_from_iso(date: str) -> datetime:
|
||||
return datetime.strptime(date, '%Y-%m-%dT%H:%M:%S.%fZ')
|
||||
|
||||
|
||||
def time_delta(text: str) -> timedelta:
|
||||
match = re.match(r'(\d+)(s|m|h|mon|w|y)', text)
|
||||
if match:
|
||||
num, unit = match.groups()
|
||||
num = int(num)
|
||||
if unit == 's':
|
||||
unit = 'seconds'
|
||||
elif unit == 'm':
|
||||
unit = 'minutes'
|
||||
elif unit == 'h':
|
||||
unit = 'hours'
|
||||
elif unit == 'd':
|
||||
unit = 'days'
|
||||
elif unit == 'w':
|
||||
unit = 'weeks'
|
||||
elif unit == 'mon':
|
||||
unit = 'weeks'
|
||||
num *= 4
|
||||
elif unit == 'y':
|
||||
unit = 'weeks'
|
||||
num *= 52
|
||||
return timedelta(**{unit: num})
|
||||
|
||||
|
||||
# Stolen from uguubot - useless?
|
||||
def time_since(date: datetime, now: datetime = None):
|
||||
"""
|
||||
Takes two datetime objects and returns the time between d and now
|
||||
as a nicely formatted string, e.g. "10 minutes". If d occurs after now,
|
||||
then "0 minutes" is returned.
|
||||
|
||||
Units used are years, months, weeks, days, hours, and minutes.
|
||||
Seconds and microseconds are ignored. Up to two adjacent units will be
|
||||
displayed. For example, "2 weeks, 3 days" and "1 year, 3 months" are
|
||||
possible outputs, but "2 weeks, 3 hours" and "1 year, 5 days" are not.
|
||||
|
||||
Adapted from http://blog.natbat.co.uk/archive/2003/Jun/14/time_since
|
||||
"""
|
||||
chunks = (
|
||||
(60 * 60 * 24 * 365, ('year', 'years')),
|
||||
(60 * 60 * 24 * 30, ('month', 'months')),
|
||||
(60 * 60 * 24 * 7, ('week', 'weeks')),
|
||||
(60 * 60 * 24, ('day', 'days')),
|
||||
(60 * 60, ('hour', 'hours')),
|
||||
(60, ('minute', 'minutes'))
|
||||
)
|
||||
|
||||
if not now:
|
||||
now = datetime.now()
|
||||
|
||||
# ignore microsecond part of 'd' since we removed it from 'now'
|
||||
delta = now - (date - timedelta(0, 0, date.microsecond))
|
||||
since = delta.days * 24 * 60 * 60 + delta.seconds
|
||||
if since <= 0:
|
||||
# d is in the future compared to now, stop processing.
|
||||
return u'0 ' + 'minutes'
|
||||
|
||||
name = None
|
||||
count = None
|
||||
seconds = None
|
||||
|
||||
for i, (seconds, name) in enumerate(chunks):
|
||||
count = since // seconds
|
||||
if count != 0:
|
||||
break
|
||||
|
||||
s = '%(number)d %(type)s' % {'number': count, 'type': name[count != 1]}
|
||||
|
||||
if i + 1 < len(chunks):
|
||||
# Now get the second item
|
||||
seconds2, name2 = chunks[i + 1]
|
||||
count2 = (since - (seconds * count)) // seconds2
|
||||
if count2 != 0:
|
||||
s += ', %d %s' % (count2, name2[count2 != 1])
|
||||
return s
|
|
@ -1,31 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
# @formatter:off
|
||||
COLORS = {
|
||||
'white': 0, # white
|
||||
'black': 1, # black
|
||||
'blue': 2, # blue (navy)
|
||||
'green': 3, # green
|
||||
'red': 4, # red
|
||||
'maroon': 5, # brown (maroon)
|
||||
'purple': 6, # purple
|
||||
'orange': 7, # orange (olive)
|
||||
'yellow': 8, # yellow
|
||||
'ltgreen': 9, # 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 = {
|
||||
'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
|
||||
}
|
||||
# @formatter:on
|
|
@ -1,20 +0,0 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
import re
|
||||
|
||||
NICK_REGEX = re.compile(r'<?[~&@%+]?([a-zA-Z0-9_\-^`|\\\[\]{}]+)>?')
|
||||
|
||||
|
||||
def parse_int(val: str, select: bool = True) -> tuple:
|
||||
try:
|
||||
val = int(val)
|
||||
if val is not 0:
|
||||
if val < 1:
|
||||
order, op = 'desc', '<='
|
||||
val *= -1
|
||||
else:
|
||||
order, op = 'asc', '>='
|
||||
if select:
|
||||
val -= 1
|
||||
return val, order, op
|
||||
except ValueError:
|
||||
pass
|
2
repl.py
2
repl.py
|
@ -8,7 +8,7 @@ import psycopg2
|
|||
from dotenv import load_dotenv
|
||||
from psycopg2.extras import DictCursor
|
||||
|
||||
from nxy.utils import *
|
||||
from bot.utils import *
|
||||
|
||||
# Load dotenv from DOTENV_FILE variable (or the default one)
|
||||
load_dotenv(os.environ.get('DOTENV_FILE', '.env'))
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#git+https://github.com/gawel/irc3.git#egg=irc3
|
||||
git+https://github.com/mrhanky17/irc3.git#egg=irc3
|
||||
aiocron==0.6
|
||||
psycopg2==2.7.1
|
||||
requests==2.14.2
|
||||
feedparser==5.2.1
|
||||
python_dotenv==0.6.4
|
||||
psycopg2==2.7.1
|
||||
|
|
30
ssl.error
30
ssl.error
|
@ -1,30 +0,0 @@
|
|||
ERROR irc3.mybot [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:749)
|
||||
Traceback (most recent call last):
|
||||
File "/home/mrhanky/.virtualenvs/irc3/lib/python3.6/site-packages/irc3-1.0.1.dev0-py3.6.egg/irc3/__init__.py", line 161, in connection_made
|
||||
transport, protocol = f.result()
|
||||
File "/usr/lib64/python3.6/asyncio/base_events.py", line 802, in create_connection
|
||||
sock, protocol_factory, ssl, server_hostname)
|
||||
File "/usr/lib64/python3.6/asyncio/base_events.py", line 828, in _create_connection_transport
|
||||
yield from waiter
|
||||
File "/usr/lib64/python3.6/asyncio/sslproto.py", line 503, in data_received
|
||||
ssldata, appdata = self._sslpipe.feed_ssldata(data)
|
||||
File "/usr/lib64/python3.6/asyncio/sslproto.py", line 201, in feed_ssldata
|
||||
self._sslobj.do_handshake()
|
||||
File "/usr/lib64/python3.6/ssl.py", line 683, in do_handshake
|
||||
self._sslobj.do_handshake()
|
||||
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:749)
|
||||
ERROR irc3.mybot [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:749)
|
||||
Traceback (most recent call last):
|
||||
File "/home/mrhanky/.virtualenvs/irc3/lib/python3.6/site-packages/irc3-1.0.1.dev0-py3.6.egg/irc3/__init__.py", line 161, in connection_made
|
||||
transport, protocol = f.result()
|
||||
File "/usr/lib64/python3.6/asyncio/base_events.py", line 802, in create_connection
|
||||
sock, protocol_factory, ssl, server_hostname)
|
||||
File "/usr/lib64/python3.6/asyncio/base_events.py", line 828, in _create_connection_transport
|
||||
yield from waiter
|
||||
File "/usr/lib64/python3.6/asyncio/sslproto.py", line 503, in data_received
|
||||
ssldata, appdata = self._sslpipe.feed_ssldata(data)
|
||||
File "/usr/lib64/python3.6/asyncio/sslproto.py", line 201, in feed_ssldata
|
||||
self._sslobj.do_handshake()
|
||||
File "/usr/lib64/python3.6/ssl.py", line 683, in do_handshake
|
||||
self._sslobj.do_handshake()
|
||||
ssl.SSLError: [SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:749)
|
Loading…
Reference in New Issue
Block a user