def _update_status(self): app.logger.info("Updating status for {}".format(self)) r = requests_get_with_retries( "http://{}:{}@{}/stat".format( app.config['RTMP_LOGIN'], app.config['RTMP_PASSWORD'], app.config['RTMP_SERVER'])) r.raise_for_status() soup = BeautifulSoup(r.content, 'xml') for stream in soup.find_all('stream'): if stream.find('name').string == self.channel_name: client_num = int(stream.find('nclients').string) is_live = stream.find('codec') if is_live: self.status = 'live' self.current_viewers = client_num - 1 if self.actual_start_time is None: self.actual_start_time = datetime.utcnow() # workaround for situations when update_state changes status before streamer get authorization elif self.status == 'live' and (self.actual_start_time is None or datetime.utcnow() - self.actual_start_time > timedelta(seconds=30)): self.status = 'completed' self.actual_start_time = None self.current_viewers = None break # same workaround else: if self.status == 'live' and (self.actual_start_time is None or datetime.utcnow() - self.actual_start_time > timedelta(seconds=30)): self.status = 'completed' self.actual_start_time = None self.current_viewers = None
def _update_title_from_channel(self): r = requests_get_with_retries("https://api.twitch.tv/kraken/channels/{}".format(self.channel)) r.raise_for_status() stream = r.json() if stream is not None: if stream['status'] is not None: self.title = stream['status']
def get_stream_from_url(url, submission=None, only_new=False): assert bool(submission) == bool(only_new) db_stream = None ytid = youtube_video_id(url) if ytid is not None: db_stream = YoutubeStream.query.filter_by(ytid=ytid).first() if db_stream is None: r = requests_get_with_retries( "https://www.googleapis.com/youtube/v3/videos?id={}&part=liveStreamingDetails&key={}".format(ytid, app.config['YOUTUBE_KEY']), retries_num=15) item = r.json()['items'] if item: if 'liveStreamingDetails' in item[0]: return YoutubeStream(ytid) tc = twitch_channel(url) if tc is not None: db_stream = TwitchStream.query.filter_by(channel=tc).first() if db_stream is None: return TwitchStream(tc) if submission and submission not in db_stream.submissions: return db_stream wc = wpc_channel(url) if wc is not None: db_stream = WPCStream.query.filter_by(channel_name=wc).first() if db_stream and submission and submission not in db_stream.submissions: return db_stream return None if only_new else db_stream
def get_random_bonus_twitch_streams(): def is_programming_stream(s): status = s['channel']['status'] if re.search('[Pp]rogramming', status): #[Pp]rogramming return True if re.search('[Gg]ame[ ]?[Dd]ev', status): return True if 'rogramming' in status: # just in case ;) return True return False app.logger.info("Getting random bonus twitch stream") r = requests_get_with_retries( "https://api.twitch.tv/kraken/streams?game=Creative", headers={'Client-ID': app.config['TWITCH_APP_ID']}) streams = sorted([ s for s in r.json()['streams'] if is_programming_stream(s) and not is_blacklisted(s['channel']['name']) ], key=lambda s: s['viewers'], reverse=True) print streams for stream in streams[:4]: ts = get_or_create(TwitchStream, channel=stream['channel']['name']) ts._update_status() db.session.add(ts) db.session.commit()
def _update_title_from_channel(self): r = requests_get_with_retries("https://api.twitch.tv/kraken/channels/{}".format(self.channel), headers={'Client-ID': app.config['TWITCH_APP_ID']}) r.raise_for_status() stream = r.json() if stream is not None: if stream['status'] is not None: self.title = stream['status']
def populate(self, form): self.info = form.info.data tc = form.twitch_channel_extract() # delete inapropriate tstream if tc != self.twitch_channel: ts = self.streams.filter_by(type='twitch_stream').first() if ts: ts.streamer = None # rebind tstream streamer = Streamer.query.filter_by(twitch_channel=tc).first() if streamer and streamer != current_user: streamer.twitch_channel = None for ts in streamer.streams.filter_by(type='twitch_stream'): ts.streamer = self self.twitch_channel = tc if tc else None yc = form.youtube_channel_extract() # delete inapropriate ystreams if yc != self.youtube_channel: for ys in self.streams.filter_by(type='youtube_stream'): ys.streamer = None # rebind ystreams streamer = Streamer.query.filter_by(youtube_channel=yc).first() if streamer and streamer != current_user: # to not make api-requests yn = streamer.youtube_name if yn is not None: self.youtube_name = yn self.youtube_channel = streamer.youtube_channel streamer.youtube_name = None streamer.youtube_channel = None for ys in streamer.streams.filter_by(type='youtube_stream'): ys.streamer = self # get yc name if yc and (yc != self.youtube_channel or self.youtube_name is None): try: r = requests_get_with_retries( "https://www.googleapis.com/youtube/v3/channels?id={}&part=snippet&key={}".format( yc, app.config['YOUTUBE_KEY']), retries_num=15) r.raise_for_status() except Exception as e: app.logger.error("Error while updating {}".format(self)) app.logger.exception(e) raise for item in r.json()['items']: self.youtube_name = item['snippet']['title'] self.youtube_channel = yc if yc else None
def _update_vod_views(self): app.logger.info("Updating view count for {}".format(self)) r = requests_get_with_retries( "https://www.googleapis.com/youtube/v3/videos?id={}&part=statistics&key={}".format( self.ytid, app.config['YOUTUBE_KEY']), retries_num=15) r.raise_for_status() for item in r.json()['items']: self.vod_views = item['statistics']['viewCount']
def _update_status(self): app.logger.info("Updating status for {}".format(self)) print "https://www.googleapis.com/youtube/v3/videos?id={}&part=snippet,liveStreamingDetails&key={}".format(self.ytid, app.config['YOUTUBE_KEY']) r = requests_get_with_retries( "https://www.googleapis.com/youtube/v3/videos?id={}&part=snippet,liveStreamingDetails&key={}".format( self.ytid, app.config['YOUTUBE_KEY']), retries_num=15) r.raise_for_status() if not r.json()['items']: self.status = 'completed' self.current_viewers = None return for item in r.json()['items']: self.youtube_channel = get_or_create(YoutubeChannel, channel_id=item['snippet']['channelId']) self.youtube_channel.title = item['snippet']['channelTitle'] # if there is streamer with this channel if self.youtube_channel.streamer is not None: self.streamer = self.youtube_channel.streamer elif self.streamer is not None: # if streamer has no yc and didn't ever checked profile if not self.streamer.checked: self.streamer.youtube_channel_class = self.youtube_channel # otherwise else: self.streamer = None self.title = item['snippet']['title'] if 'liveStreamingDetails' in item: self.scheduled_start_time = item['liveStreamingDetails'].get('scheduledStartTime', None) if 'concurrentViewers' in item['liveStreamingDetails']: self.current_viewers = item['liveStreamingDetails']['concurrentViewers'] if item['snippet']['liveBroadcastContent'] == "none" and not self.actual_start_time: # TODO: it is probably better to have a separate column for vids self.actual_start_time = item['snippet'].get('publishedAt') if item['snippet']['liveBroadcastContent'] == 'live': self._go_live() if 'actualStartTime' in item['liveStreamingDetails']: self.actual_start_time = item['liveStreamingDetails'].get('actualStartTime', None) else: # Youtube is weird, and sometimes this happens. If there is no actual start time, then we fall back to scheduledStartTime self.actual_start_time = item['liveStreamingDetails'].get('scheduledStartTime', None) elif item['snippet']['liveBroadcastContent'] == 'upcoming': self.status = 'upcoming' else: self.status = 'completed' self.current_viewers = None
def __init__(self, channel_id, title=None): self.channel_id = channel_id if title: self.title = title else: r = requests_get_with_retries( "https://www.googleapis.com/youtube/v3/channels?id={}&part=snippet&key={}".format( channel_id, app.config['YOUTUBE_KEY']), retries_num=15) r.raise_for_status() for item in r.json()['items']: self.title = item['snippet']['title']
def _update_status(self): app.logger.info("Updating status for {}".format(self)) r = requests_get_with_retries( "https://www.googleapis.com/youtube/v3/videos?id={}&part=snippet,liveStreamingDetails&key={}".format( self.ytid, app.config['YOUTUBE_KEY']), retries_num=15) r.raise_for_status() if not r.json()['items']: self.status = 'completed' self.current_viewers = None return for item in r.json()['items']: self.youtube_channel = get_or_create(YoutubeChannel, channel_id=item['snippet']['channelId']) self.youtube_channel.title = item['snippet']['channelTitle'] # if there is streamer with this channel if self.youtube_channel.streamer is not None: self.streamer = self.youtube_channel.streamer elif self.streamer is not None: # if streamer has no yc and didn't ever checked profile if not self.streamer.checked: self.streamer.youtube_channel_class = self.youtube_channel # otherwise else: self.streamer = None self.title = item['snippet']['title'] if 'liveStreamingDetails' in item: self.scheduled_start_time = item['liveStreamingDetails'].get('scheduledStartTime', None) if 'concurrentViewers' in item['liveStreamingDetails']: self.current_viewers = item['liveStreamingDetails']['concurrentViewers'] if item['snippet']['liveBroadcastContent'] == "none" and not self.actual_start_time: # TODO: it is probably better to have a separate column for vids self.actual_start_time = item['snippet'].get('publishedAt') if item['snippet']['liveBroadcastContent'] == 'live': self._go_live() if 'actualStartTime' in item['liveStreamingDetails']: self.actual_start_time = item['liveStreamingDetails'].get('actualStartTime', None) else: # Youtube is weird, and sometimes this happens. If there is no actual start time, then we fall back to scheduledStartTime self.actual_start_time = item['liveStreamingDetails'].get('scheduledStartTime', None) elif item['snippet']['liveBroadcastContent'] == 'upcoming': self.status = 'upcoming' else: self.status = 'completed' self.current_viewers = None
def _update_status(self): app.logger.info("Updating status for {}".format(self)) try: r = requests_get_with_retries( "https://www.googleapis.com/youtube/v3/videos?id={}&part=snippet,liveStreamingDetails&key={}".format( self.ytid, app.config['YOUTUBE_KEY']), retries_num=15) r.raise_for_status() except Exception as e: app.logger.error("Error while updating {}".format(self)) app.logger.exception(e) raise if not r.json()['items']: self.status = 'completed' self.current_viewers = None return for item in r.json()['items']: self.title = item['snippet']['title'] if 'liveStreamingDetails' in item: self.scheduled_start_time = item['liveStreamingDetails']['scheduledStartTime'] if 'concurrentViewers' in item['liveStreamingDetails']: self.current_viewers = item['liveStreamingDetails']['concurrentViewers'] if item['snippet']['liveBroadcastContent'] == 'live': self.status = 'live' if 'actualStartTime' in item['liveStreamingDetails']: self.actual_start_time = item['liveStreamingDetails']['actualStartTime'] else: # Youtube is weird, and sometimes this happens. If there is no actual start time, then we fall back to scheduledStartTime self.actual_start_time = item['liveStreamingDetails']['scheduledStartTime'] elif item['snippet']['liveBroadcastContent'] == 'upcoming': self.status = 'upcoming' else: self.status = 'completed' self.current_viewers = None # add channel to streamer table if it's needed and fix if it's needed if self.streamer is not None: yc = item['snippet']['channelId'] streamer = Streamer.query.filter_by(youtube_channel=yc).first() # if there is streamer with that channel if streamer: self.streamer = streamer # there is no streamer with that channel elif not self.streamer.checked: self.streamer.youtube_channel = yc self.streamer.youtube_name = item['snippet']['channelTitle']
def _update_status(self): app.logger.info("Updating status for {}".format(self)) # add channel to streamer table if it's needed and fix if it's needed streamer = Streamer.query.filter_by(twitch_channel=self.channel).first() # if there is streamer with this channel if streamer: self.streamer = streamer elif self.streamer is not None: # if self.streamer has no tc and didn't ever checked profile if self.streamer.twitch_channel is None and\ not self.streamer.checked: self.streamer.twitch_channel = self.channel else: self.streamer = None r = requests_get_with_retries("https://api.twitch.tv/kraken/streams/{}".format(self.channel), headers={'Client-ID': app.config['TWITCH_APP_ID']}) r.raise_for_status() stream = r.json()['stream'] if stream is not None: self._go_live() if 'status' in stream['channel']: self.title = stream['channel']['status'] self.current_viewers = stream['viewers'] self.last_time_live = datetime.utcnow() if self.actual_start_time is None: self.actual_start_time = self.last_time_live else: if self.status == 'live': # this is workaround for situations like stream going offline shortly if datetime.utcnow() - self.last_time_live > timedelta(minutes=12): self.status = 'completed' self.current_viewers = None if self.status == 'upcoming': self._update_title_from_channel()
def _update_status(self): app.logger.info("Updating status for {}".format(self)) # add channel to streamer table if it's needed and fix if it's needed streamer = Streamer.query.filter_by(twitch_channel=self.channel).first() # if there is streamer with this channel if streamer: self.streamer = streamer elif self.streamer is not None: # if self.streamer has no tc and didn't ever checked profile if self.streamer.twitch_channel is None and\ not self.streamer.checked: self.streamer.twitch_channel = self.channel else: self.streamer = None r = requests_get_with_retries("https://api.twitch.tv/kraken/streams/{}".format(self.channel)) r.raise_for_status() stream = r.json()['stream'] if stream is not None: self._go_live() if 'status' in stream['channel']: self.title = stream['channel']['status'] self.current_viewers = stream['viewers'] self.last_time_live = datetime.utcnow() if self.actual_start_time is None: self.actual_start_time = self.last_time_live else: if self.status == 'live': # this is workaround for situations like stream going offline shortly if datetime.utcnow() - self.last_time_live > timedelta(minutes=12): self.status = 'completed' self.current_viewers = None if self.status == 'upcoming': self._update_title_from_channel()
def get_stream_from_url(url, submission_id=None, only_new=False): assert bool(submission_id) == bool(only_new) db_stream = None ytid = youtube_video_id(url) if ytid is not None: db_stream = YoutubeStream.query.filter_by(ytid=ytid).first() if db_stream is None: r = requests_get_with_retries( "https://www.googleapis.com/youtube/v3/videos?id={}&part=liveStreamingDetails&key={}" .format(ytid, app.config['YOUTUBE_KEY']), retries_num=15, verify=False) item = r.json()['items'] if item: if 'liveStreamingDetails' in item[0]: return YoutubeStream(ytid) tc = twitch_channel(url) if tc is not None: db_stream = TwitchStream.query.filter_by(channel=tc).first() if db_stream is None: return TwitchStream(tc) if submission_id and submission_id not in [ s.submission_id for s in db_stream.submissions ]: return db_stream wc = wpc_channel(url) if wc is not None: db_stream = WPCStream.query.filter_by(channel_name=wc).first() if db_stream and submission_id and\ submission_id not in [s.submission_id for s in db_stream.submissions]: return db_stream return None if only_new else db_stream