Sync events

master
Nikola Forró 6 years ago
parent ce9be0b223
commit 79aacd731a

@ -9,7 +9,7 @@ import flask_restful.reqparse
import sqlalchemy
import sqlalchemy.engine
from db import db, Video, Comment, Association, Emote, Clip
from db import db, Video, Comment, Association, Emote, Clip, Event
app = flask.Flask(__name__)
@ -37,7 +37,13 @@ app.config.update(
args=(app, db),
max_instances=1,
trigger='interval',
seconds=120)])
seconds=120),
dict(id='sync_events',
func='sync:Sync.sync_events',
args=(app, db),
max_instances=1,
trigger='interval',
seconds=600)])
if app.config.get('SQLALCHEMY_DATABASE_URI', '').startswith('sqlite://'):
@sqlalchemy.event.listens_for(sqlalchemy.engine.Engine, 'connect')
@ -119,6 +125,19 @@ clip_fields = {
'created_at': flask_restful.fields.DateTime(dt_format='iso8601'),
}
event_fields = {
'id': flask_restful.fields.String(),
'start': flask_restful.fields.DateTime(dt_format='iso8601'),
'end': flask_restful.fields.DateTime(dt_format='iso8601'),
'title': flask_restful.fields.String(),
'description': flask_restful.fields.String(),
'game_id': flask_restful.fields.Integer(),
'game_name': flask_restful.fields.String(),
'game_box_small': flask_restful.fields.String(),
'game_box_medium': flask_restful.fields.String(),
'game_box_large': flask_restful.fields.String(),
}
filter_parser = flask_restful.reqparse.RequestParser()
filter_parser.add_argument('filter', type=str)
@ -287,7 +306,7 @@ class ClipResource(flask_restful.Resource):
clip = q.first()
if not clip:
flask_restful.abort(404, message='Clip {0} does not exist'.format(slug))
return slug, 200
return clip, 200
class ClipsResource(flask_restful.Resource):
@ -317,6 +336,43 @@ class ClipsResource(flask_restful.Resource):
return clips, 200, {'X-Total-Count': count}
class EventResource(flask_restful.Resource):
@flask_restful.marshal_with(event_fields)
def get(self, id):
q = db.session.query(Event).filter(Event.id == id)
event = q.first()
if not event:
flask_restful.abort(404, message='Event {0} does not exist'.format(id))
return event, 200
class EventsResource(flask_restful.Resource):
@flask_restful.marshal_with(event_fields)
def get(self):
args = filter_parser.parse_args()
q = db.session.query(Event)
if args['filter']:
q = q.filter(Event.title.ilike('%{}%'.format(args['filter'])))
count = q.count()
if args['sort_order'] == 'random':
q = q.order_by(sqlalchemy.func.random())
elif args['sort_by']:
col = getattr(Event, args['sort_by'], None)
if col:
if args['sort_order']:
order_by = getattr(col, args['sort_order'], None)
if order_by:
q = q.order_by(order_by())
else:
q = q.order_by(col)
if args['page_size']:
q = q.limit(args['page_size'])
if args['page_number'] and args['page_size']:
q = q.offset(args['page_number'] * args['page_size'])
events = q.all()
return events, 200, {'X-Total-Count': count}
api.add_resource(VideoResource, '/videos/<int:id>')
api.add_resource(VideosResource, '/videos')
api.add_resource(CommentResource, '/videos/<int:video_id>/comments/<string:comment_id>')
@ -326,6 +382,8 @@ api.add_resource(EmoteResource, '/emotes/<int:id>')
api.add_resource(EmotesResource, '/emotes')
api.add_resource(ClipResource, '/clips/<string:slug>')
api.add_resource(ClipsResource, '/clips')
api.add_resource(EventResource, '/events/<int:id>')
api.add_resource(EventsResource, '/events')
if __name__ == '__main__':

@ -72,3 +72,18 @@ class Clip(db.Model):
thumbnail_small = db.Column(db.String)
thumbnail_medium = db.Column(db.String)
created_at = db.Column(db.DateTime)
class Event(db.Model):
__tablename__ = 'events'
id = db.Column(db.String, primary_key=True)
start = db.Column(db.DateTime)
end = db.Column(db.DateTime)
title = db.Column(db.String)
description = db.Column(db.String)
game_id = db.Column(db.Integer)
game_name = db.Column(db.String)
game_box_small = db.Column(db.String)
game_box_medium = db.Column(db.String)
game_box_large = db.Column(db.String)

@ -3,7 +3,7 @@ import os
import flask_restful.inputs
from db import Video, Comment, Association, Emote, Clip
from db import Video, Comment, Association, Emote, Clip, Event
from twitch import Twitch
@ -154,3 +154,30 @@ class Sync(object):
db.session.add(clip)
db.session.commit()
app.logger.info('Synchronization of clips completed')
@classmethod
def sync_events(cls, app, db):
app.logger.info('Starting synchronization of events')
with app.app_context():
twitch = Twitch(os.getenv('TWITCH_CLIENT_ID'), os.getenv('TWITCH_OAUTH_TOKEN'))
channel_id = os.getenv('TWITCH_CHANNEL_ID')
for evt in twitch.fetch_events(channel_id):
id = cls._get(evt, '_id')
if not id:
continue
q = db.session.query(Event).filter(Event.id == id)
event = q.first()
if not event:
event = Event(id=id)
event.start = cls._to_datetime(cls._get(evt, 'start_time'))
event.end = cls._to_datetime(cls._get(evt, 'end_time'))
event.title = cls._get(evt, 'title')
event.description = cls._get(evt, 'description')
event.game_id = cls._get(evt, 'game', '_id')
event.game_name = cls._get(evt, 'game', 'name')
event.game_box_small = cls._get(evt, 'game', 'box', 'small')
event.game_box_medium = cls._get(evt, 'game', 'box', 'medium')
event.game_box_large = cls._get(evt, 'game', 'box', 'large')
db.session.add(event)
db.session.commit()
app.logger.info('Synchronization of events completed')

@ -95,3 +95,16 @@ class Twitch(object):
if not cursor:
break
return result
def fetch_events(self, channel_id):
if not channel_id:
return []
session = FuturesSession()
def get_events():
url = 'https://api.twitch.tv/v5/channels/{0}/events'.format(channel_id)
params = dict(client_id=self.client_id)
return session.get(url, params=params)
request = get_events()
data = request.result().json()
result = data.get('events', [])
return result

Loading…
Cancel
Save