123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139 |
- # -*- coding: utf-8 -*-
- import time
- import json
- import codecs
- import sys
- from socket import timeout, error as SocketError
- from ssl import SSLError
- try:
- # py2
- from urllib2 import URLError
- from httplib import HTTPException
- except ImportError:
- # py3
- from urllib.error import URLError
- from http.client import HTTPException
- from instagram_private_api import ClientError
- from .logger import log, seperator
- """
- This feature of PyInstaLive was originally written by https://github.com/taengstagram
- The code below and in downloader.py that's related to the comment downloading
- feature is modified by https://github.com/notcammy
- """
- class CommentsDownloader(object):
- def __init__(self, api, broadcast, destination_file):
- self.api = api
- self.broadcast = broadcast
- self.destination_file = destination_file
- self.comments = []
- def get_live(self, first_comment_created_at=0):
- comments_collected = self.comments
- before_count = len(comments_collected)
- try:
- comments_res = self.api.broadcast_comments(
- self.broadcast['id'], last_comment_ts=first_comment_created_at)
- comments = comments_res.get('comments', [])
- first_comment_created_at = (
- comments[0]['created_at_utc'] if comments else int(time.time() - 5))
- comments_collected.extend(comments)
- after_count = len(comments_collected)
- if after_count > before_count:
- broadcast = self.broadcast.copy()
- broadcast.pop('segments', None) # save space
- broadcast['comments'] = comments_collected
- with open(self.destination_file, 'w') as outfile:
- json.dump(broadcast, outfile, indent=2)
- self.comments = comments_collected
- except (SSLError, timeout, URLError, HTTPException, SocketError) as e:
- log('[W] Comment collection error: %s' % e, "YELLOW")
- except ClientError as e:
- if e.code == 500:
- log('[W] Comment collection ClientError: %d %s' % (e.code, e.error_response), "YELLOW")
- elif e.code == 400 and not e.msg:
- log('[W] Comment collection ClientError: %d %s' % (e.code, e.error_response), "YELLOW")
- else:
- raise e
- finally:
- time.sleep(4)
- return first_comment_created_at
- def get_replay(self):
- comments_collected = []
- starting_offset = 0
- encoding_tag = self.broadcast['encoding_tag']
- while True:
- comments_res = self.api.replay_broadcast_comments(
- self.broadcast['id'], starting_offset=starting_offset, encoding_tag=encoding_tag)
- starting_offset = comments_res.get('ending_offset', 0)
- comments = comments_res.get('comments', [])
- comments_collected.extend(comments)
- if not comments_res.get('comments') or not starting_offset:
- break
- time.sleep(4)
- if comments_collected:
- self.broadcast['comments'] = comments_collected
- self.broadcast['initial_buffered_duration'] = 0
- with open(self.destination_file, 'w') as outfile:
- json.dump(self.broadcast, outfile, indent=2)
- self.comments = comments_collected
- def save(self):
- broadcast = self.broadcast.copy()
- broadcast.pop('segments', None)
- broadcast['comments'] = self.comments
- with open(self.destination_file, 'w') as outfile:
- json.dump(broadcast, outfile, indent=2)
- @staticmethod
- def generate_log(comments, download_start_time, srt_file, comments_delay=10.0):
- python_version = sys.version.split(' ')[0]
- subtitles_timeline = {}
- for i, c in enumerate(comments):
- if 'offset' in c:
- for k in c['comment'].keys():
- c[k] = c['comment'][k]
- c['created_at_utc'] = download_start_time + c['offset']
- created_at_utc = str(2 * (c['created_at_utc'] // 2))
- comment_list = subtitles_timeline.get(created_at_utc) or []
- comment_list.append(c)
- subtitles_timeline[created_at_utc] = comment_list
- if subtitles_timeline:
- timestamps = sorted(subtitles_timeline.keys())
- mememe = False
- subs = []
- for i, tc in enumerate(timestamps):
- t = subtitles_timeline[tc]
- clip_start = int(tc) - int(download_start_time) + int(comments_delay)
- if clip_start < 0:
- clip_start = 0
- srt = ''
- if sys.version.split(' ')[0].startswith('2'):
- for c in t:
- if (c['user']['is_verified']):
- srt += '{}{}\n\n'.format(time.strftime('%H:%M:%S\n', time.gmtime(clip_start)), '{} {}: {}'.format(c['user']['username'], "(V)", c['text'].encode('ascii', 'xmlcharrefreplace')))
- else:
- srt += '{}{}\n\n'.format(time.strftime('%H:%M:%S\n', time.gmtime(clip_start)), '{}: {}'.format(c['user']['username'], c['text'].encode('ascii', 'xmlcharrefreplace')))
- else:
- for c in t:
- if (c['user']['is_verified']):
- srt += '{}{}\n\n'.format(time.strftime('%H:%M:%S\n', time.gmtime(clip_start)), '{} {}: {}'.format(c['user']['username'], "(v)", c['text']))
- else:
- srt += '{}{}\n\n'.format(time.strftime('%H:%M:%S\n', time.gmtime(clip_start)), '{}: {}'.format(c['user']['username'], c['text']))
- subs.append(srt)
- with codecs.open(srt_file, 'w', 'utf-8-sig') as srt_outfile:
- srt_outfile.write(''.join(subs))
|