You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
144 lines
4.7 KiB
144 lines
4.7 KiB
import configparser
|
|
import logging
|
|
import os
|
|
import re
|
|
import string
|
|
|
|
import dateutil.parser
|
|
import irc.bot
|
|
import requests
|
|
|
|
|
|
config = configparser.ConfigParser()
|
|
config.read('settings.cfg')
|
|
|
|
|
|
log = logging.getLogger('irc.client')
|
|
log.addHandler(logging.StreamHandler())
|
|
|
|
if os.getenv('DEBUG', False):
|
|
log.setLevel(logging.DEBUG)
|
|
|
|
|
|
QUOTE_ADDED_PATTERN = re.compile(r'''^
|
|
(?P<user>.+)\s+-->\s+
|
|
Sweet!\s+Thanks\s+for\s+the\s+quote!\s+
|
|
\#(?P<id>\d+):\s+
|
|
"(?P<text>.+)"\s+
|
|
\[(?P<game>.+)\]\s+
|
|
\[(?P<date>.+)\]$''', re.VERBOSE)
|
|
|
|
# TODO: quote_edited, quote_removed
|
|
|
|
|
|
class TwitchBot(irc.bot.SingleServerIRCBot):
|
|
def __init__(self):
|
|
self.actions = [
|
|
(re.compile(r'^!lastquote$'), self.last_quote),
|
|
(re.compile(r'^!findquote\s+(?P<q>")?(?P<filter>.+)(?(q)")$'), self.find_quote),
|
|
(QUOTE_ADDED_PATTERN, self.add_quote),
|
|
]
|
|
self.server = config['IRC'].get('server', 'irc.chat.twitch.tv')
|
|
self.port = config['IRC'].getint('port', 6667)
|
|
self.nickname = config['IRC'].get('nickname')
|
|
self.channel = '#{0}'.format(config['IRC'].get('channel'))
|
|
self.token = config['Twitch'].get('token')
|
|
self.api_url = config['Quotes'].get('api_url')
|
|
self.api_key = config['Quotes'].get('api_key')
|
|
print('Connecting to {0}:{1}'.format(self.server, self.port))
|
|
super(TwitchBot, self).__init__([(self.server, self.port, self.token)],
|
|
self.nickname, self.nickname)
|
|
|
|
def on_welcome(self, connection, event):
|
|
connection.cap('REQ', ':twitch.tv/membership')
|
|
connection.cap('REQ', ':twitch.tv/tags')
|
|
connection.cap('REQ', ':twitch.tv/commands')
|
|
print('Joining {0}'.format(self.channel))
|
|
connection.join(self.channel)
|
|
|
|
def on_join(self, connection, event):
|
|
print('Joined {0}'.format(event.target))
|
|
|
|
def on_pubmsg(self, connection, event):
|
|
self.process_message(connection, event)
|
|
|
|
def on_whisper(self, connection, event):
|
|
self.process_message(connection, event)
|
|
|
|
def process_message(self, connection, event):
|
|
sources = [t['value'] for t in event.tags if t['key'] == 'display-name']
|
|
message = ''.join([c for c in event.arguments[0] if c in string.printable])
|
|
message = message.rstrip()
|
|
for pattern, action in self.actions:
|
|
m = pattern.match(message)
|
|
if m:
|
|
action(connection, sources[0], **m.groupdict())
|
|
|
|
def get(self, params):
|
|
r = requests.get('{0}/quotes'.format(self.api_url), params=params)
|
|
r.raise_for_status()
|
|
return r.json()
|
|
|
|
def post(self, data):
|
|
r = requests.post('{0}/quotes'.format(self.api_url), data=data,
|
|
headers={'X-Quotes-API-Key': self.api_key})
|
|
r.raise_for_status()
|
|
return r.json()
|
|
|
|
def delete(self, id):
|
|
r = requests.post('{0}/quote/{1}'.format(self.api_url, id),
|
|
headers={'X-Quotes-API-Key': self.api_key})
|
|
r.raise_for_status()
|
|
return r.json()
|
|
|
|
def last_quote(self, connection, source, **kwargs):
|
|
try:
|
|
quotes = self.get(dict(
|
|
sort_by='id',
|
|
sort_order='desc',
|
|
page_size=1))
|
|
quote = quotes[0]
|
|
except (requests.exceptions.HTTPError, IndexError):
|
|
msg = 'Sorry @{0}, no quotes found'.format(source)
|
|
else:
|
|
msg = '!quote {0}'.format(quote['id'])
|
|
connection.privmsg(self.channel, msg)
|
|
|
|
def find_quote(self, connection, source, filter, **kwargs):
|
|
if len(filter) < 3:
|
|
msg = 'Sorry @{0}, the search phrase is too short'.format(source)
|
|
connection.privmsg(self.channel, msg)
|
|
return
|
|
try:
|
|
quotes = self.get(dict(
|
|
filter=filter,
|
|
sort_by='id',
|
|
sort_order='desc',
|
|
page_size=1))
|
|
quote = quotes[0]
|
|
except (requests.exceptions.HTTPError, IndexError):
|
|
msg = 'Sorry @{0}, no quotes found'.format(source)
|
|
else:
|
|
msg = '!quote {0}'.format(quote['id'])
|
|
connection.privmsg(self.channel, msg)
|
|
|
|
def add_quote(self, connection, source, user, id, text, game, date, **kwargs):
|
|
print('Adding quote {0}: {1}'.format(id, text))
|
|
try:
|
|
self.post(dict(
|
|
id=int(id) + 10000, # FIXME
|
|
date=dateutil.parser.parse(date, dayfirst=True).date().isoformat(),
|
|
game=game,
|
|
text=text))
|
|
except requests.exceptions.HTTPError as e:
|
|
print('Failed to add quote: ', e)
|
|
|
|
|
|
def main():
|
|
bot = TwitchBot()
|
|
bot.start()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|