Synchronize and provide also Twitch channel emotes

master
Nikola Forró 6 years ago
parent 8245e5af29
commit f56df57490

@ -9,7 +9,7 @@ import flask_restful.reqparse
import sqlalchemy import sqlalchemy
import sqlalchemy.engine import sqlalchemy.engine
from db import db, Video, Comment, Association from db import db, Video, Comment, Association, Emote
app = flask.Flask(__name__) app = flask.Flask(__name__)
@ -74,6 +74,11 @@ comment_fields = {
'updated_at': flask_restful.fields.DateTime(dt_format='iso8601', attribute='comment.updated_at'), 'updated_at': flask_restful.fields.DateTime(dt_format='iso8601', attribute='comment.updated_at'),
} }
emote_fields = {
'id': flask_restful.fields.Integer(),
'code': flask_restful.fields.String(),
}
filter_parser = flask_restful.reqparse.RequestParser() filter_parser = flask_restful.reqparse.RequestParser()
filter_parser.add_argument('filter', type=str) filter_parser.add_argument('filter', type=str)
@ -169,10 +174,30 @@ class CommentsResource(flask_restful.Resource):
return assocs, 200, {'X-Total-Count': count} return assocs, 200, {'X-Total-Count': count}
class EmoteResource(flask_restful.Resource):
@flask_restful.marshal_with(emote_fields)
def get(self, id):
q = db.session.query(Emote).filter(Emote.id == id)
emote = q.first()
if not emote:
flask_restful.abort(404, message='Emote {0} does not exist'.format(id))
return emote, 200
class EmotesResource(flask_restful.Resource):
@flask_restful.marshal_with(emote_fields)
def get(self):
q = db.session.query(Emote)
emotes = q.all()
return emotes, 200
api.add_resource(VideoResource, '/videos/<int:id>') api.add_resource(VideoResource, '/videos/<int:id>')
api.add_resource(VideosResource, '/videos') api.add_resource(VideosResource, '/videos')
api.add_resource(CommentResource, '/videos/<int:video_id>/comments/<string:comment_id>') api.add_resource(CommentResource, '/videos/<int:video_id>/comments/<string:comment_id>')
api.add_resource(CommentsResource, '/videos/<int:id>/comments') api.add_resource(CommentsResource, '/videos/<int:id>/comments')
api.add_resource(EmoteResource, '/emotes/<int:id>')
api.add_resource(EmotesResource, '/emotes')
if __name__ == '__main__': if __name__ == '__main__':

@ -46,3 +46,10 @@ class Association(db.Model):
comment_id = db.Column(db.String, db.ForeignKey('comments.id'), primary_key=True) comment_id = db.Column(db.String, db.ForeignKey('comments.id'), primary_key=True)
offset = db.Column(db.Float) offset = db.Column(db.Float)
comment = db.relationship('Comment') comment = db.relationship('Comment')
class Emote(db.Model):
__tablename__ = 'emotes'
id = db.Column(db.Integer, primary_key=True)
code = db.Column(db.String)

@ -3,7 +3,7 @@ import os
import flask_restful.inputs import flask_restful.inputs
from db import Video, Comment, Association from db import Video, Comment, Association, Emote
from twitch import Twitch from twitch import Twitch
@ -35,9 +35,10 @@ class Sync(object):
def perform(cls, app, db): def perform(cls, app, db):
app.logger.info('Starting synchronization') app.logger.info('Starting synchronization')
with app.app_context(): with app.app_context():
twitch = Twitch(os.getenv('TWITCH_CLIENT_ID')) twitch = Twitch(os.getenv('TWITCH_CLIENT_ID'), os.getenv('TWITCH_OAUTH_TOKEN'))
channel = os.getenv('TWITCH_CHANNEL_ID')
updated = [] updated = []
for vid in twitch.fetch_videos(os.getenv('TWITCH_CHANNEL_ID')): for vid in twitch.fetch_videos(channel):
id = cls._get(vid, '_id', default='').lstrip('v') id = cls._get(vid, '_id', default='').lstrip('v')
if not id: if not id:
continue continue
@ -102,4 +103,15 @@ class Sync(object):
video.associations.append(assoc) video.associations.append(assoc)
db.session.add(video) db.session.add(video)
db.session.commit() db.session.commit()
for em in twitch.fetch_emotes(channel):
id = cls._get(em, 'id')
if not id:
continue
q = db.session.query(Emote).filter(Emote.id == id)
emote = q.first()
if not emote:
emote = Emote(id=id)
emote.code = cls._get(em, 'code')
db.session.add(emote)
db.session.commit()
app.logger.info('Synchronization completed') app.logger.info('Synchronization completed')

@ -2,8 +2,9 @@ from requests_futures.sessions import FuturesSession
class Twitch(object): class Twitch(object):
def __init__(self, client_id): def __init__(self, client_id, oauth_token):
self.client_id = client_id self.client_id = client_id
self.oauth_token = oauth_token
def fetch_videos(self, channel_id): def fetch_videos(self, channel_id):
if not channel_id: if not channel_id:
@ -54,3 +55,19 @@ class Twitch(object):
if cursor: if cursor:
pairs.append((video_id, cursor)) pairs.append((video_id, cursor))
return result return result
def fetch_emotes(self, channel_id):
if not channel_id:
return []
session = FuturesSession()
def get_emotes():
url = 'https://api.twitch.tv/v5/users/{0}/emotes'.format(channel_id)
params = dict(client_id=self.client_id)
headers = dict(authorization='OAuth {0}'.format(self.oauth_token))
return session.get(url, params=params, headers=headers)
request = get_emotes()
data = request.result().json()
result = []
for val in data.get('emoticon_sets', {}).values():
result.extend(val)
return result

@ -28,8 +28,8 @@ services:
- 5000 - 5000
# Twitch comments API service with /data/comments mounted as database storage # Twitch comments API service with /data/comments mounted as database storage
# TWITCH_CLIENT_ID and TWITCH_CHANNEL_ID are needed for Twitch API access # TWITCH_CLIENT_ID, TWITCH_OAUTH_TOKEN and TWITCH_CHANNEL_ID are needed for
# and synchronization # Twitch API access and synchronization
comments-api: comments-api:
build: build:
context: ./comments-api context: ./comments-api
@ -38,6 +38,7 @@ services:
environment: environment:
- SQLALCHEMY_DATABASE_URI=sqlite:////comments/comments.db - SQLALCHEMY_DATABASE_URI=sqlite:////comments/comments.db
- TWITCH_CLIENT_ID=__TWITCH_CLIENT_ID__ - TWITCH_CLIENT_ID=__TWITCH_CLIENT_ID__
- TWITCH_OAUTH_TOKEN=__TWITCH_OAUTH_TOKEN__
- TWITCH_CHANNEL_ID=__TWITCH_CHANNEL_ID__ - TWITCH_CHANNEL_ID=__TWITCH_CHANNEL_ID__
expose: expose:
- 5000 - 5000

Loading…
Cancel
Save