Пример #1
0
    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
Пример #2
0
 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']
Пример #3
0
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
Пример #4
0
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()
Пример #5
0
 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']
Пример #6
0
    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
Пример #7
0
    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
Пример #8
0
    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']
Пример #9
0
    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']
Пример #10
0
    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
Пример #11
0
    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']
Пример #12
0
    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']
Пример #13
0
    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
Пример #14
0
    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']
Пример #15
0
    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()
Пример #16
0
    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()
Пример #17
0
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