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.
117 lines
5.2 KiB
117 lines
5.2 KiB
6 years ago
|
import datetime
|
||
|
import os
|
||
|
|
||
|
import flask_restful.inputs
|
||
|
|
||
6 years ago
|
from db import Video, Comment, Association, Emote
|
||
6 years ago
|
from twitch import Twitch
|
||
|
|
||
|
|
||
|
class Sync(object):
|
||
|
@staticmethod
|
||
|
def _get(d, *keys, default=None):
|
||
|
try:
|
||
|
result = None
|
||
|
for key in keys:
|
||
|
if result:
|
||
|
if isinstance(result, list):
|
||
|
result = result[key]
|
||
|
else:
|
||
|
result = result.get(key, default)
|
||
|
else:
|
||
|
result = d.get(key, default)
|
||
|
return result
|
||
|
except (KeyError, IndexError):
|
||
|
return default
|
||
|
|
||
|
@staticmethod
|
||
|
def _to_datetime(val):
|
||
|
if not val:
|
||
|
return None
|
||
|
result = flask_restful.inputs.datetime_from_iso8601(val)
|
||
|
return result.astimezone(tz=datetime.timezone.utc).replace(tzinfo=None)
|
||
|
|
||
|
@classmethod
|
||
|
def perform(cls, app, db):
|
||
|
app.logger.info('Starting synchronization')
|
||
|
with app.app_context():
|
||
6 years ago
|
twitch = Twitch(os.getenv('TWITCH_CLIENT_ID'), os.getenv('TWITCH_OAUTH_TOKEN'))
|
||
|
channel = os.getenv('TWITCH_CHANNEL_ID')
|
||
6 years ago
|
updated = []
|
||
6 years ago
|
for vid in twitch.fetch_videos(channel):
|
||
6 years ago
|
id = cls._get(vid, '_id', default='').lstrip('v')
|
||
|
if not id:
|
||
|
continue
|
||
|
if cls._get(vid, 'status') == 'recording':
|
||
|
continue
|
||
|
q = db.session.query(Video).filter(Video.id == id)
|
||
|
video = q.first()
|
||
|
if not video:
|
||
|
video = Video(id=id)
|
||
|
created_at = cls._get(vid, 'created_at')
|
||
|
updated_at = cls._to_datetime(cls._get(vid, 'updated_at', default=created_at))
|
||
|
created_at = cls._to_datetime(created_at)
|
||
6 years ago
|
if not video.updated_at or video.updated_at < updated_at:
|
||
|
updated.append(id)
|
||
6 years ago
|
video.broadcast_type = cls._get(vid, 'broadcast_type')
|
||
|
video.title = cls._get(vid, 'title')
|
||
|
video.description = cls._get(vid, 'description')
|
||
|
video.game = cls._get(vid, 'game')
|
||
|
video.length = cls._get(vid, 'length')
|
||
|
video.thumbnail_small = cls._get(vid, 'thumbnails', 'small', 0, 'url')
|
||
|
video.thumbnail_medium = cls._get(vid, 'thumbnails', 'medium', 0, 'url')
|
||
|
video.thumbnail_large = cls._get(vid, 'thumbnails', 'large', 0, 'url')
|
||
|
video.created_at = created_at
|
||
|
video.updated_at = updated_at
|
||
|
video.recorded_at = cls._to_datetime(cls._get(vid, 'recorded_at'))
|
||
|
video.published_at = cls._to_datetime(cls._get(vid, 'published_at'))
|
||
|
db.session.add(video)
|
||
|
db.session.commit()
|
||
|
app.logger.info('Updated videos: %s', ', '.join(updated) if updated else 'NONE')
|
||
|
for com in twitch.fetch_comments(updated):
|
||
|
q = db.session.query(Video).filter(Video.id == cls._get(com, 'content_id'))
|
||
|
video = q.first()
|
||
|
if not video:
|
||
|
continue
|
||
|
id = cls._get(com, '_id')
|
||
6 years ago
|
q = db.session.query(Comment).filter(Comment.id == id)
|
||
|
comment = q.first()
|
||
|
if not comment:
|
||
|
comment = Comment(id=id)
|
||
|
comment.commenter_id = cls._get(com, 'commenter', '_id')
|
||
|
comment.commenter_name = cls._get(com, 'commenter', 'name')
|
||
|
comment.commenter_display_name = cls._get(com, 'commenter', 'display_name')
|
||
|
comment.commenter_logo = cls._get(com, 'commenter', 'logo')
|
||
|
comment.source = cls._get(com, 'source')
|
||
|
comment.message_body = cls._get(com, 'message', 'body')
|
||
|
comment.message_user_color = cls._get(com, 'message', 'user_color')
|
||
6 years ago
|
badges = cls._get(com, 'message', 'user_badges')
|
||
|
if badges:
|
||
|
badges = ','.join(['{_id}:{version}'.format(**b) for b in badges])
|
||
6 years ago
|
comment.message_user_badges = badges
|
||
|
comment.created_at = cls._to_datetime(cls._get(com, 'created_at'))
|
||
|
comment.updated_at = cls._to_datetime(cls._get(com, 'updated_at'))
|
||
|
q = db.session.query(Association).filter(
|
||
|
Association.video_id == video.id,
|
||
|
Association.comment_id == comment.id)
|
||
|
assoc = q.first()
|
||
|
if not assoc:
|
||
|
assoc = Association()
|
||
|
assoc.comment = comment
|
||
|
assoc.offset = cls._get(com, 'content_offset_seconds')
|
||
6 years ago
|
video.associations.append(assoc)
|
||
|
db.session.add(video)
|
||
|
db.session.commit()
|
||
6 years ago
|
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()
|
||
6 years ago
|
app.logger.info('Synchronization completed')
|