Add TwitchBot.sync() method and fix logging

master
Nikola Forró 7 years ago
parent 4cd9b04856
commit c0ca339442

@ -8,6 +8,8 @@ import dateutil.parser
import irc.bot import irc.bot
import requests import requests
from twitch import Twitch
config = configparser.ConfigParser() config = configparser.ConfigParser()
config.read('settings.cfg') config.read('settings.cfg')
@ -33,10 +35,13 @@ QUOTE_ADDED_PATTERN = re.compile(r'''^
class TwitchBot(irc.bot.SingleServerIRCBot): class TwitchBot(irc.bot.SingleServerIRCBot):
def __init__(self): def __init__(self):
self.actions = [ self.patterns = [
(QUOTE_ADDED_PATTERN, self.add_quote),
]
self.commands = [
(re.compile(r'^!lastquote$'), self.last_quote), (re.compile(r'^!lastquote$'), self.last_quote),
(re.compile(r'^!findquote\s+(?P<q>")?(?P<filter>.+)(?(q)")$'), self.find_quote), (re.compile(r'^!findquote\s+(?P<q>")?(?P<filter>.+)(?(q)")$'), self.find_quote),
(QUOTE_ADDED_PATTERN, self.add_quote), (re.compile(r'^!sync(\s+(?P<since>.+))?$'), self.sync),
] ]
self.server = config['IRC'].get('server', 'irc.chat.twitch.tv') self.server = config['IRC'].get('server', 'irc.chat.twitch.tv')
self.port = config['IRC'].getint('port', 6667) self.port = config['IRC'].getint('port', 6667)
@ -45,7 +50,7 @@ class TwitchBot(irc.bot.SingleServerIRCBot):
self.token = config['Twitch'].get('token') self.token = config['Twitch'].get('token')
self.api_url = config['Quotes'].get('api_url') self.api_url = config['Quotes'].get('api_url')
self.api_key = config['Quotes'].get('api_key') self.api_key = config['Quotes'].get('api_key')
print('Connecting to {0}:{1}'.format(self.server, self.port)) log.info('Connecting to %s:%d', self.server, self.port)
super(TwitchBot, self).__init__([(self.server, self.port, self.token)], super(TwitchBot, self).__init__([(self.server, self.port, self.token)],
self.nickname, self.nickname) self.nickname, self.nickname)
@ -53,11 +58,11 @@ class TwitchBot(irc.bot.SingleServerIRCBot):
connection.cap('REQ', ':twitch.tv/membership') connection.cap('REQ', ':twitch.tv/membership')
connection.cap('REQ', ':twitch.tv/tags') connection.cap('REQ', ':twitch.tv/tags')
connection.cap('REQ', ':twitch.tv/commands') connection.cap('REQ', ':twitch.tv/commands')
print('Joining {0}'.format(self.channel)) log.info('Joining %s', self.channel)
connection.join(self.channel) connection.join(self.channel)
def on_join(self, connection, event): def on_join(self, connection, event):
print('Joined {0}'.format(event.target)) log.info('Joined %s', event.target)
def on_pubmsg(self, connection, event): def on_pubmsg(self, connection, event):
self.process_message(connection, event) self.process_message(connection, event)
@ -69,7 +74,7 @@ class TwitchBot(irc.bot.SingleServerIRCBot):
sources = [t['value'] for t in event.tags if t['key'] == 'display-name'] 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 = ''.join([c for c in event.arguments[0] if c in string.printable])
message = message.rstrip() message = message.rstrip()
for pattern, action in self.actions: for pattern, action in self.patterns + self.commands:
m = pattern.match(message) m = pattern.match(message)
if m: if m:
action(connection, sources[0], **m.groupdict()) action(connection, sources[0], **m.groupdict())
@ -122,8 +127,35 @@ class TwitchBot(irc.bot.SingleServerIRCBot):
msg = '!quote {0}'.format(quote['id']) msg = '!quote {0}'.format(quote['id'])
connection.privmsg(self.channel, msg) connection.privmsg(self.channel, msg)
def sync(self, connection, source, since=None, **kwargs):
if since is None:
try:
quotes = self.get(dict(
sort_by='id',
sort_order='desc',
page_size=1))
quote = quotes[0]
except requests.exceptions.HTTPError as e:
log.error('Failed to get quotes: %s', str(e))
return
except IndexError:
log.error('No quotes available')
return
else:
since = quote['date']
api_url = config['Twitch'].get('api_url')
client_id = config['Twitch'].get('client_id')
user_id = config['Twitch'].get('target_user_id')
since = dateutil.parser.parse(since).date()
messages = Twitch(api_url, client_id, log).get_messages(user_id, since)
for message in messages:
for pattern, action in self.patterns:
m = pattern.match(message)
if m:
action(connection, m.group('user'), **m.groupdict())
def add_quote(self, connection, source, user, id, text, game, date, **kwargs): def add_quote(self, connection, source, user, id, text, game, date, **kwargs):
print('Adding quote {0}: {1}'.format(id, text)) log.info('Adding quote %s: %s', id, text)
try: try:
self.post(dict( self.post(dict(
id=int(id) + 10000, # FIXME id=int(id) + 10000, # FIXME
@ -131,7 +163,7 @@ class TwitchBot(irc.bot.SingleServerIRCBot):
game=game, game=game,
text=text)) text=text))
except requests.exceptions.HTTPError as e: except requests.exceptions.HTTPError as e:
print('Failed to add quote: ', e) log.error('Failed to add quote: %s', str(e))
def main(): def main():

@ -0,0 +1,57 @@
import dateutil.parser
import requests
class Twitch(object):
def __init__(self, api_url, client_id, log=None):
self.api_url = api_url
self.client_id = client_id
self.log = log
def _get_videos(self, user_id):
def request(offset, limit):
url = '{0}/channels/{1}/videos'.format(self.api_url, user_id)
params = dict(client_id=self.client_id, offset=offset, limit=limit)
r = requests.get(url, params=params)
r.raise_for_status()
return r.json()
result = []
data = request(0, 1)
total = data.get('_total', 0)
limit = 100
for offset in range(0, total, limit):
data = request(offset, limit)
for vid in data.get('videos', []):
result.append(dict(
id=int(vid['_id'].lstrip('v')),
title=vid['title'],
date=dateutil.parser.parse(vid['recorded_at']).date()))
return result
def _get_comments(self, video_id):
def request(cursor):
url = '{0}/videos/{1}/comments'.format(self.api_url, video_id)
params = dict(client_id=self.client_id, cursor=cursor)
r = requests.get(url, params=params)
r.raise_for_status()
return r.json()
result = []
cursor = ''
while True:
data = request(cursor)
for comment in data.get('comments', []):
result.append(comment['message']['body'])
cursor = data.get('_next')
if not cursor:
break
return result
def get_messages(self, user_id, since):
videos = self._get_videos(user_id)
result = []
for video in [v for v in videos if v['date'] >= since]:
if self.log:
self.log.info('Processing VOD %d (%s)', video['id'], video['title'])
comments = self._get_comments(video['id'])
result.extend(comments)
return result
Loading…
Cancel
Save