<commit_before>from wpc import db, app, login_manager
from wpc.utils import requests_get_with_retries

from flask.ext.login import UserMixin, current_user
from sqlalchemy.orm.properties import ColumnProperty
from flask import url_for

import humanize
from datetime import datetime, timedelta
from bs4 import BeautifulSoup


@login_manager.user_loader
def load_user(reddit_username):
        return Streamer.query.filter_by(reddit_username=reddit_username).first()


stream_tag = db.Table('stream_tag',
                      db.Column('stream_id', db.Integer(), db.ForeignKey('stream.id')),
                      db.Column('tag_name', db.String(256), db.ForeignKey('tag.name')))


stream_sub = db.Table('stream_sub',
                      db.Column('stream_id', db.Integer(), db.ForeignKey('stream.id')),
                      db.Column('submission_id', db.String(6), db.ForeignKey('submission.submission_id')))


class Submission(db.Model):
    submission_id = db.Column(db.String(6), primary_key=True)
    recording_available = db.Column(db.Boolean())

    def __repr__(self):
        return '<Submission %r>' % (self.submission_id)


class Stream(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    type = db.Column(db.String(50))
    scheduled_start_time = db.Column(db.DateTime())
    actual_start_time = db.Column(db.DateTime())
    status = db.Column(db.Enum('upcoming', 'live', 'completed', name='stream_status'))
    title = db.Column(db.String(200))
    submissions = db.relationship('Submission', secondary=stream_sub, backref=db.backref('streams', lazy='dynamic'))
    streamer_id = db.Column('streamer_id', db.Integer(), db.ForeignKey('streamer.id'))
    streamer = db.relationship('Streamer', backref=db.backref('streams', lazy='dynamic'))
    tags = db.relationship('Tag', secondary=stream_tag, backref=db.backref('streams', lazy='dynamic'))
    current_viewers = db.Column(db.Integer)
    confstream = db.Column(db.Boolean(), default=False)
    __mapper_args__ = {
        'polymorphic_on': type,
        'polymorphic_identity': 'stream'
    }

    def format_start_time(self, countdown=True, start_time=True):
        if not self.scheduled_start_time or (not countdown and not start_time):
            return None

        if countdown:
            return humanize.naturaltime(datetime.utcnow() - self.scheduled_start_time) +\
                ((", " + datetime.strftime(self.scheduled_start_time, "%Y-%m-%d %H:%M UTC")) if start_time else "")
        else:
            return datetime.strftime(self.scheduled_start_time, "%Y-%m-%d %H:%M UTC")

    def add_submission(self, submission):
        if submission not in self.submissions:
            self.submissions.append(submission)


class WPCStream(Stream):
    channel_name = db.Column(db.String(30), unique=True)

    def __init__(self, name):
        self.status = 'upcoming'
        self.channel_name = name
        self.submissions = []

    def __eq__(self, other):
        return type(self) == type(other) and self.channel_name == other.channel_name

    def __hash__(self):
        return hash(self.channel_name)

    def __repr__(self):
        return '<WPC Stream %d %r>' % (self.id, self.channel_name)

    def _update_status(self):
        app.logger.info("Updating status for {}".format(self))
        try:
            r = requests_get_with_retries("http://192.168.3.11/stat")
            r.raise_for_status()
        except Exception as e:
            app.logger.error("Error while updating {}".format(self))
            app.logger.exception(e)
            raise

        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 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 datetime.utcnow() - self.actual_start_time > timedelta(seconds=30):
                self.status = 'completed'
                self.actual_start_time = None
                self.current_viewers = None

    def normal_url(self):
        return url_for('.streamer_page', streamer_name=self.streamer.reddit_username, _external=True)

    def html_code(self, autoplay=False):
        return """
                <div id="{}">Loading the player...</div>

                <script type="text/javascript">
                    jwplayer("{}").setup({{
                        playlist: [{{<commit_msg>fix update_state for wpc_streams when act.start time is None<commit_after>from wpc import db, app, login_manager
from wpc.utils import requests_get_with_retries

from flask.ext.login import UserMixin, current_user
from sqlalchemy.orm.properties import ColumnProperty
from flask import url_for

import humanize
from datetime import datetime, timedelta
from bs4 import BeautifulSoup


@login_manager.user_loader
def load_user(reddit_username):
        return Streamer.query.filter_by(reddit_username=reddit_username).first()


stream_tag = db.Table('stream_tag',
                      db.Column('stream_id', db.Integer(), db.ForeignKey('stream.id')),
                      db.Column('tag_name', db.String(256), db.ForeignKey('tag.name')))


stream_sub = db.Table('stream_sub',
                      db.Column('stream_id', db.Integer(), db.ForeignKey('stream.id')),
                      db.Column('submission_id', db.String(6), db.ForeignKey('submission.submission_id')))


class Submission(db.Model):
    submission_id = db.Column(db.String(6), primary_key=True)
    recording_available = db.Column(db.Boolean())

    def __repr__(self):
        return '<Submission %r>' % (self.submission_id)


class Stream(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    type = db.Column(db.String(50))
    scheduled_start_time = db.Column(db.DateTime())
    actual_start_time = db.Column(db.DateTime())
    status = db.Column(db.Enum('upcoming', 'live', 'completed', name='stream_status'))
    title = db.Column(db.String(200))
    submissions = db.relationship('Submission', secondary=stream_sub, backref=db.backref('streams', lazy='dynamic'))
    streamer_id = db.Column('streamer_id', db.Integer(), db.ForeignKey('streamer.id'))
    streamer = db.relationship('Streamer', backref=db.backref('streams', lazy='dynamic'))
    tags = db.relationship('Tag', secondary=stream_tag, backref=db.backref('streams', lazy='dynamic'))
    current_viewers = db.Column(db.Integer)
    confstream = db.Column(db.Boolean(), default=False)
    __mapper_args__ = {
        'polymorphic_on': type,
        'polymorphic_identity': 'stream'
    }

    def format_start_time(self, countdown=True, start_time=True):
        if not self.scheduled_start_time or (not countdown and not start_time):
            return None

        if countdown:
            return humanize.naturaltime(datetime.utcnow() - self.scheduled_start_time) +\
                ((", " + datetime.strftime(self.scheduled_start_time, "%Y-%m-%d %H:%M UTC")) if start_time else "")
        else:
            return datetime.strftime(self.scheduled_start_time, "%Y-%m-%d %H:%M UTC")

    def add_submission(self, submission):
        if submission not in self.submissions:
            self.submissions.append(submission)


class WPCStream(Stream):
    channel_name = db.Column(db.String(30), unique=True)

    def __init__(self, name):
        self.status = 'upcoming'
        self.channel_name = name
        self.submissions = []

    def __eq__(self, other):
        return type(self) == type(other) and self.channel_name == other.channel_name

    def __hash__(self):
        return hash(self.channel_name)

    def __repr__(self):
        return '<WPC Stream %d %r>' % (self.id, self.channel_name)

    def _update_status(self):
        app.logger.info("Updating status for {}".format(self))
        try:
            r = requests_get_with_retries("http://192.168.3.11/stat")
            r.raise_for_status()
        except Exception as e:
            app.logger.error("Error while updating {}".format(self))
            app.logger.exception(e)
            raise

        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 and 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.actual_start_time and datetime.utcnow() - self.actual_start_time > timedelta(seconds=30):
                self.status = 'completed'
                self.actual_start_time = None
                self.current_viewers = None

    def normal_url(self):
        return url_for('.streamer_page', streamer_name=self.streamer.reddit_username, _external=True)

    def html_code(self, autoplay=False):
        return """
                <div id="{}">Loading the player...</div>

                <script type="text/javascript">
                    jwplayer("{}").setup({{
                        playlist: [{{
{'fraction_non_alphanumeric': 0.12137944396008912, 'fraction_numerical': 0.0052310374891020054, 'mean_word_length': 2.6454802259887007, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 2}, 'pii_count': 2, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2793977', 'n_tokens_mistral': 3127, 'n_tokens_neox': 2982, 'n_words': 600}