Ejemplo n.º 1
0
class Pagination_handler(Handler):

    __arguments_schema__ = good.Schema({
        'per_page': good.Any(
            good.All(
                [good.All(good.Coerce(int), good.Range(min=1))],
                good.Length(max=1),
            ),
            good.Default([constants.PER_PAGE])
        ),
        'page': good.Any(
            good.All(
                [good.All(good.Coerce(int), good.Range(min=1))],
                good.Length(max=1),
            ),
            good.Default([1])
        ),
    }, default_keys=good.Required, extra_keys=good.Allow,)

    def get(self, *args, **kwargs):
        args = self.validate_arguments(Pagination_handler.__arguments_schema__)
        self.per_page = args.pop('per_page', [0])[0]
        self.page = args.pop('page', [0])[0]
        self.request.arguments.pop('per_page', None)
        self.request.arguments.pop('page', None)
Ejemplo n.º 2
0
class Slots_handler(Api_handler):

    __schema__ = good.Schema({
        'emote_pool_size':
        good.All(good.Coerce(int), good.Range(min=2)),
        'payout_percent':
        good.All(good.Coerce(int), good.Range(min=1)),
        'min_bet':
        good.All(good.Coerce(int), good.Range(min=1)),
        'max_bet':
        good.All(good.Coerce(int), good.Range(min=0)),
        'emotes': [str],
        'win_message':
        good.All(good.Coerce(str), good.Length(min=1, max=250)),
        'allin_win_message':
        good.All(good.Coerce(str), good.Length(min=1, max=250)),
        'lose_message':
        good.All(good.Coerce(str), good.Length(min=1, max=250)),
        'allin_lose_message':
        good.All(good.Coerce(str), good.Length(min=1, max=250)),
    })

    async def get(self, channel_id):
        settings = await self.db.fetchone(
            'select * from twitch_gambling_slots_settings where channel_id=%s',
            (channel_id),
        )
        if not settings:
            self.set_status(204)
        else:
            settings.pop('channel_id')
            settings['emotes'] = json.loads(settings['emotes'])
            self.write_object(settings)

    @Level(3)
    async def put(self, channel_id):
        data = self.validate()
        if 'emotes' in data:
            data['emotes'] = json.dumps(data['emotes'])
        fields = ','.join([f for f in data])
        values = ','.join(['%s' for f in data])
        dup = ','.join([f'{f}=VALUES({f})' for f in data])

        await self.db.execute(
            f'''
            INSERT INTO 
                twitch_gambling_slots_settings
                (channel_id, {fields})
            VALUES
                (%s, {values})
            ON DUPLICATE KEY UPDATE {dup}
        ''', (
                channel_id,
                *data.values(),
            ))
        self.set_status(204)
Ejemplo n.º 3
0
def Range(min=None, max=None, min_included=True, max_included=True, msg=None):
    # Alter min, max when the range is not inclusive
    if min is not None and not min_included:
        min += 1
    if max is not None and not max_included:
        max -= 1
    # Finish
    return _wrapMsg(good.Range(min, max), msg)
Ejemplo n.º 4
0
class Handler(base.Handler):

    __schema__ = good.Schema({
        'rating':
        good.All(int, good.Range(min=1, max=10)),
    })

    @authenticated(0)
    async def put(self, show_id):
        await self.save(show_id)
        self.set_status(204)

    @authenticated(0)
    async def get(self, show_id):
        r = await self.get_rating(show_id)
        self.write_object(r)

    @authenticated(0)
    async def delete(self, show_id):
        await self.delete_rating(show_id)
        self.set_status(204)

    @run_on_executor
    def save(self, show_id):
        d = self.validate()
        with new_session() as session:
            r = models.User_show_rating(
                show_id=show_id,
                user_id=self.current_user.id,
                rating=d['rating'],
                updated_at=datetime.utcnow(),
            )
            session.merge(r)
            session.commit()

    @run_on_executor
    def get_rating(self, show_id):
        with new_session() as session:
            r = session.query(models.User_show_rating.rating).filter(
                models.User_show_rating.user_id == self.current_user.id,
                models.User_show_rating.show_id == show_id,
            ).first()
            return {
                'rating': r.rating if r else None,
            }

    @run_on_executor
    def delete_rating(self, show_id):
        with new_session() as session:
            session.query(models.User_show_rating).filter(
                models.User_show_rating.user_id == self.current_user.id,
                models.User_show_rating.show_id == show_id,
            ).delete()
            session.commit()
Ejemplo n.º 5
0
class Handler(Api_handler):

    __schema__ = good.Schema({
        str: [{
            'message': good.All(str, good.Length(min=0, max=200)),
            good.Optional('min_amount'): good.All(good.Coerce(int), good.Range(min=0, max=1000)),
        }],
    }, default_keys=good.Optional)

    @Level(1)
    async def get(self, channel_id):
        alerts = await self.db.fetchall(
            'SELECT type, message, min_amount FROM twitch_chat_alerts WHERE channel_id=%s',
            (channel_id,)
        )
        grouped_alerts = {}
        for a in alerts:
            l = grouped_alerts.setdefault(a['type'], [])
            l.append({
                'message': a['message'],
                'min_amount': a['min_amount'] or 0,
            })
        self.write_object(grouped_alerts)

    @Level(1)
    async def put(self, channel_id):
        data = self.validate()
        for key in data:
            ins = []
            for d in data[key]:
                if d['message']:
                    ins.append((
                        channel_id,
                        key,
                        d['message'], 
                        d.get('min_amount', 0),
                    ))
            await self.db.execute(
                'DELETE FROM twitch_chat_alerts WHERE channel_id=%s AND type=%s;', 
                (channel_id, key,)
            )
            if ins:
                await self.db.executemany('''
                    INSERT INTO twitch_chat_alerts 
                        (channel_id, type, message, min_amount)
                    VALUES 
                        (%s, %s, %s, %s)
                    ''', ins
                )
        await self.get(channel_id)
Ejemplo n.º 6
0
class Channel_admins(Api_handler):

    __schema__ = good.Schema({
        'user':
        good.All(str, good.Length(min=4, max=25)),
        'level':
        good.All(good.Coerce(int), good.Range(min=1, max=3)),
    })

    __update_schema__ = good.Schema({
        'level':
        good.All(good.Coerce(int), good.Range(min=1, max=3)),
    })

    @Level(3)
    async def get(self, channel_id):
        admins = await self.db.fetchall(
            '''
            SELECT user_id as id, user as name, level 
            FROM twitch_channel_admins 
            WHERE channel_id=%s
            ORDER BY level DESC
            ''', (channel_id, ))
        self.write_object(admins)

    @Level(3)
    async def post(self, channel_id):
        data = self.validate()

        url = 'https://api.twitch.tv/helix/users'
        users = await twitch_request(self.ahttp, url, {
            'login': data['user'],
        })
        if not users['data']:
            raise Api_exception(400, 'User does not exist on Twitch')
        user = users['data'][0]
        await self.db.execute(
            '''
            INSERT INTO 
                twitch_channel_admins 
                    (channel_id, user_id, user, level, created_at, updated_at)
            VALUES
                (%s, %s, %s, %s, now(), now())
            ON DUPLICATE KEY UPDATE 
                user=VALUES(user),
                level=VALUES(level),
                updated_at=VALUES(updated_at)
        ''', (channel_id, user['id'], user['display_name'], data['level']))

        self.set_status(204)

    @Level(3)
    async def put(self, channel_id, user_id):
        data = self.validate(self.__update_schema__)
        await self.db.execute(
            'UPDATE twitch_channel_admins SET level=%s WHERE channel_id=%s AND user_id=%s',
            (data['level'], channel_id, user_id))

    @Level(3)
    async def delete(self, channel_id, user_id):
        await self.db.execute(
            'DELETE FROM twitch_channel_admins WHERE channel_id=%s AND user_id=%s',
            (channel_id, user_id))
        self.set_status(204)
Ejemplo n.º 7
0
        try:
            utils.validate_cmd_response(v)
            return v
        except Exception as e:
            raise good.Invalid(str(e))

    return f


_schema = {
    'cmd':
    good.All(str, validate_cmd()),
    'response':
    good.All(str, validate_response()),
    good.Optional('user_level'):
    good.All(good.Coerce(int), good.Range(min=0, max=9)),
    good.Optional('enabled_status'):
    good.All(good.Coerce(int), good.Range(min=0, max=2)),
    good.Optional('global_cooldown'):
    good.All(good.Coerce(int), good.Range(min=0, max=86400)),
    good.Optional('user_cooldown'):
    good.All(good.Coerce(int), good.Range(min=0, max=86400)),
    good.Optional('mod_cooldown'):
    good.All(good.Coerce(int), good.Range(min=0, max=86400)),
    good.Optional('enabled'):
    good.All(good.Coerce(int), good.Range(min=0, max=1)),
    good.Optional('public'):
    good.All(good.Coerce(int), good.Range(min=0, max=1)),
    good.Optional('group_name'):
    good.Maybe(good.All(str, good.Length(min=0, max=50))),
}
Ejemplo n.º 8
0
import logging, good, asyncio
from ..base import Api_handler, Level, Api_exception
from tbot import config, utils
from datetime import datetime, timedelta

__schema__ = {
    'name': good.All(str, good.Length(min=1, max=100)),
    'messages': good.All([good.All(str, good.Length(min=1, max=500))], good.Length(min=1, max=100)),
    good.Optional('enabled'): good.All(good.Coerce(int), good.Range(min=0, max=1)),
    good.Optional('enabled_status'): good.All(good.Coerce(int), good.Range(min=0, max=2)),
    good.Optional('interval'): good.All(good.Coerce(int), good.Range(min=1, max=10080)),
    good.Optional('send_message_order'): good.All(good.Coerce(int), good.Range(min=1, max=2)),
}

class Handler(Api_handler):

    __schema__ = good.Schema(__schema__, default_keys=good.Optional)

    @Level(1)
    async def put(self, channel_id, id_):
        data = self.validate()
        data['updated_at'] = datetime.utcnow()
        if 'interval' in data:
            data['next_run'] = datetime.utcnow()+timedelta(minutes=data['interval'])
        if 'messages' in data:
            data['messages'] = utils.json_dumps(data['messages'])
        fields = ', '.join(['`{}`=%s'.format(k) for k in data])
        values = list(data.values())
        values.append(channel_id)
        values.append(id_)
        await self.db.execute(
Ejemplo n.º 9
0
class Handler(base.Handler):

    __schema__ = good.Schema({
        'position':
        good.All(int, good.Range(min=0, max=86400)),
    })

    @authenticated(constants.LEVEL_PROGRESS)
    async def get(self, show_id, episode_number):
        w = await self._get(show_id, episode_number)
        if not w:
            self.set_status(204)
        else:
            self.write_object(w)

    @run_on_executor
    def _get(self, show_id, episode_number):
        with new_session() as session:
            r = session.query(models.Episode_watched).filter(
                models.Episode_watched.show_id == show_id,
                models.Episode_watched.episode_number == episode_number,
            ).first()
            if r:
                return r.serialize()

    @authenticated(constants.LEVEL_PROGRESS)
    async def put(self, show_id, episode_number):
        await self._put(show_id, episode_number)
        self.set_status(204)

    @authenticated(constants.LEVEL_PROGRESS)
    async def delete(self, show_id, episode_number):
        self.request.body = {'position': 0}
        await self.reset_position(show_id, episode_number)
        self.set_status(204)

    @run_on_executor
    def _put(self, show_id, episode_number):
        data = self.validate(self.__schema__)
        with new_session() as session:
            episode = session.query(models.Episode).filter(
                models.Episode.show_id == show_id,
                models.Episode.number == episode_number,
            ).first()
            if not episode:
                raise exceptions.Episode_unknown()

            ew = session.query(models.Episode_watched).filter(
                models.Episode_watched.show_id == show_id,
                models.Episode_watched.episode_number == episode_number,
                models.Episode_watched.user_id == self.current_user.id,
            ).first()
            if not ew:
                ew = models.Episode_watched(
                    show_id=show_id,
                    episode_number=episode_number,
                    user_id=self.current_user.id,
                )
                session.add(ew)
            ew.position = data['position']
            if ew.position > 0:
                ew.watched_at = datetime.utcnow()
                ew.set_as_watching()
            else:
                ew.set_prev_as_watching()
                if ew.times == 0 and ew.position == 0:
                    session.delete(ew)
            session.commit()

    @run_on_executor
    def reset_position(self, show_id, episode_number):
        with new_session() as session:
            ew = session.query(models.Episode_watched).filter(
                models.Episode_watched.show_id == show_id,
                models.Episode_watched.episode_number == episode_number,
                models.Episode_watched.user_id == self.current_user.id,
            ).first()
            if ew:
                ew.position = 0
                if ew.times == 0:
                    ew.set_prev_as_watching()
                    session.delete(ew)
                session.commit()
Ejemplo n.º 10
0
class Handler(base.Handler):

    __schema__ = good.Schema(
        {
            'times': good.All(int, good.Range(min=-20, max=20)),
        },
        default_keys=good.Optional)

    @authenticated(constants.LEVEL_PROGRESS)
    async def get(self, show_id, episode_number):
        w = await self._get(
            show_id=show_id,
            episode_number=episode_number,
        )
        if w:
            self.write_object(w)
        else:
            self.set_status(204)

    @authenticated(constants.LEVEL_PROGRESS)
    async def put(self, show_id, episode_number):
        w = await self._put(show_id, episode_number)
        if w:
            self.write_object(w)
        else:
            self.set_status(204)

    @authenticated(0)
    async def delete(self, show_id, episode_number):
        await self._delete(show_id, episode_number)
        self.set_status(204)

    @run_on_executor
    def _get(self, show_id, episode_number):
        with new_session() as session:
            ew = session.query(models.Episode_watched).filter(
                models.Episode_watched.show_id == show_id,
                models.Episode_watched.episode_number == episode_number,
                models.Episode_watched.user_id == self.current_user.id,
            ).first()
            if ew:
                return ew.serialize()

    @run_on_executor
    def _put(self, show_id, episode_number):
        data = self.validate()
        with new_session() as session:
            ew = set_watched(
                session=session,
                user_id=self.current_user.id,
                show_id=show_id,
                episode_number=episode_number,
                times=data.get('times', 1),
            )
            session.commit()
            if ew:
                return ew.serialize()

    @run_on_executor
    def _delete(self, show_id, episode_number):
        with new_session() as session:
            ew = session.query(models.Episode_watched).filter(
                models.Episode_watched.show_id == show_id,
                models.Episode_watched.episode_number == episode_number,
                models.Episode_watched.user_id == self.current_user.id,
            ).first()
            if ew:
                ew.set_prev_as_watching()
                session.delete(ew)
            session.commit()
Ejemplo n.º 11
0
def stream_append(params):
    if params.stream_id is None:
        params.stream_id = create_stream()
    message_id = create_message(stream_id=params.stream_id, text=params.text)

    return {"message_id": message_id, "stream_id": params.stream_id}


@endpoint("stream/query",
          G.Schema({
              "stream_id":
              int,
              "updated_since":
              G.Maybe(int),
              "page":
              G.Any(int, G.Default(0), G.Range(0, 999)),
              "page_size":
              G.Any(int, G.Default(20), G.Range(1, 200)),
              "order_dir":
              G.Any("DESC", "ASC", G.Default("DESC")),
              "order_by":
              G.Any("created", "updated", G.Default("updated"))
          }))
def stream_query(params):
    return query_messages(**params)


@endpoint("stream/ping", G.Schema({"stream_id": G.Maybe(int)}))
def stream_ping(params):
    return {"success": ping_stream(params.stream_id)}
Ejemplo n.º 12
0
def SHOW_EPISODE_TYPE(msg=None):
    def f(v):
        if v not in constants.SHOW_EPISODE_TYPE:
            raise good.Invalid('invalid episodes type: {}'.format(v))
        return v
    return f

Description_schema = good.Schema({
    'text': good.Maybe(str),
    'title': good.Maybe(str),
    'url':  good.Maybe(str),
}, default_keys=good.Optional)
_Episode_schema = {
    'title': good.Maybe(str),
    good.Required('number'): good.All(good.Coerce(int), good.Range(min=1)),
    good.Optional('season'): good.Maybe(good.All(good.Coerce(int), good.Range(min=1))),
    good.Optional('episode'): good.Maybe(good.All(good.Coerce(int), good.Range(min=1))),
    'air_date': good.Maybe(date_()),
    'air_time': good.Maybe(time_()),
    'air_datetime': good.Maybe(iso8601_to_utc()),
    'description': good.Any(None, Description_schema),
    'runtime': good.Maybe(good.Coerce(int)),
}
Episode_schema = good.Schema(_Episode_schema, default_keys=good.Optional)
External_schema = good.Schema({
    good.All(good.Length(min=1, max=45)):good.Any(None, good.All(good.Coerce(str), good.Length(min=1, max=45)))
}, default_keys=good.Optional)
Importer_schema = good.Schema(
    {key: good.Maybe(good.All(str, good.Length(min=1, max=45))) \
        for key in constants.IMPORTER_TYPE_NAMES},
Ejemplo n.º 13
0
            """
            SELECT * FROM bot
            %s
            ORDER BY bot_id ASC
            LIMIT %%s OFFSET %%s
        """ % where, *params)


def get_bot(bot_id):
    with db.connect() as c:
        return c.get(
            """
            SELECT * FROM bot
            WHERE bot_id = %s
        """, bot_id)


@endpoint("bot/query",
          G.Schema({
              "name": G.Maybe(str),
              "page": G.Any(int, G.Default(0), G.Range(0, 999)),
              "page_size": G.Any(int, G.Default(100), G.Range(1, 200))
          }))
def bot_query(params):
    return query_bots(**params)


@endpoint("bot/get", G.Schema({"bot_id": int}))
def bot_get(params):
    return get_bot(params.bot_id)
Ejemplo n.º 14
0
class Points_settings_handler(Api_handler):

    __schema__ = good.Schema({
        'enabled':
        good.Boolean(),
        'points_name':
        good.All(str, good.Length(min=1, max=45)),
        'points_per_min':
        good.All(good.Coerce(int), good.Range(min=0)),
        'points_per_min_sub_multiplier':
        good.All(good.Coerce(int), good.Range(min=0)),
        'points_per_sub':
        good.All(good.Coerce(int), good.Range(min=0)),
        'points_per_cheer':
        good.All(good.Coerce(int), good.Range(min=0)),
        'ignore_users': [str],
    })

    async def get(self, channel_id):
        settings = await self.db.fetchone(
            'select * from twitch_channel_point_settings where channel_id=%s',
            (channel_id),
        )
        if not settings:
            self.set_status(204)
        else:
            self.write_object({
                'enabled':
                True if settings['enabled'] == 1 else False,
                'points_name':
                settings['points_name'],
                'points_per_min':
                settings['points_per_min'],
                'points_per_min_sub_multiplier':
                settings['points_per_min_sub_multiplier'],
                'points_per_sub':
                settings['points_per_sub'],
                'points_per_cheer':
                settings['points_per_cheer'],
                'ignore_users':
                json.loads(settings['ignore_users']),
            })

    @Level(3)
    async def put(self, channel_id):
        data = self.validate()
        if 'ignore_users' in data:
            data['ignore_users'] = json.dumps(data['ignore_users'])
        fields = ','.join([f for f in data])
        values = ','.join(['%s' for f in data])
        dup = ','.join([f'{f}=VALUES({f})' for f in data])

        await self.db.execute(
            f'''
            INSERT INTO 
                twitch_channel_point_settings
                (channel_id, {fields})
            VALUES
                (%s, {values})
            ON DUPLICATE KEY UPDATE {dup}
        ''', (
                channel_id,
                *data.values(),
            ))
        self.set_status(204)
Ejemplo n.º 15
0
class Handler(base.Handler):

    __arguments_schema__ = good.Schema(
        {
            'days_back':
            good.Any(
                good.All(good.Coerce(int), good.Range(min=0, max=7)),
                good.Default(2),
            ),
            'days_ahead':
            good.Any(good.All(good.Coerce(int), good.Range(min=0, max=14)),
                     good.Default(7)),
        },
        default_keys=good.Required)

    async def get(self, user_id):
        user_id = self.user_id_or_current(user_id)
        shows_episodes = await self.get_shows_episodes(user_id)
        if not shows_episodes:
            self.write_object([])
            return
        ids = []
        shows = {se[0]['id']: se[0] for se in shows_episodes}
        airdates = OrderedDict()
        airdate_shows = OrderedDict()
        prev = None
        for se in shows_episodes:
            if prev == None:
                prev = se[1]['air_datetime'].date()
            if prev != se[1]['air_datetime'].date():
                airdates[prev] = list(airdate_shows.values())
                prev = se[1]['air_datetime'].date()
                airdate_shows = {}
            if se[1]['show_id'] not in airdate_shows:
                airdate_shows[se[1]['show_id']] = copy.copy(
                    shows[se[1]['show_id']])
            show = airdate_shows[se[1]['show_id']]
            show.setdefault('episodes', [])
            show['episodes'].append(self.episode_wrapper(se[1]))
        if shows_episodes:
            airdates[prev] = list(airdate_shows.values())
        self.write_object([{'air_date': ad, 'shows': airdates[ad]}\
            for ad in airdates])

    @run_on_executor
    def get_shows_episodes(self, user_id):
        args = self.validate_arguments()
        now = datetime.utcnow()
        from_ = (now - timedelta(days=args['days_back'])).date()
        to_ = (now + timedelta(days=args['days_ahead'])).date()
        with new_session() as session:
            rows = session.query(models.Episode, models.Show).filter(
                models.Show_fan.user_id == user_id,
                models.Show_fan.show_id == models.Show.id,
                models.Episode.show_id == models.Show.id,
                sa.func.date(models.Episode.air_datetime) >= from_,
                sa.func.date(models.Episode.air_datetime) <= to_,
            ).order_by(
                models.Episode.air_datetime,
                models.Show.id,
            ).all()
            return [(r.Show.serialize(), r.Episode.serialize()) for r in rows]