예제 #1
0
파일: base.py 프로젝트: thomaserlang/seplis
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)
예제 #2
0
class Handler(base.Handler):

    __schema__ = good.Schema(
        {
            'subtitle_lang':
            good.Maybe(good.All(good.Lower(), good.Length(min=1, max=20))),
            'audio_lang':
            good.Maybe(good.All(good.Lower(), good.Length(min=1, max=20)))
        },
        default_keys=good.Optional)

    @authenticated(constants.LEVEL_USER)
    def get(self, show_id):
        data = models.User_show_subtitle_lang.get(
            user_id=self.current_user.id,
            show_id=show_id,
        )
        if data:
            self.write_object(data)
        else:
            self.set_status(204)

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

    @run_on_executor
    def _put(self, show_id):
        data = self.validate()
        with new_session() as session:
            d = models.User_show_subtitle_lang(
                user_id=self.current_user.id,
                show_id=show_id,
                subtitle_lang=data.get('subtitle_lang', None),
                audio_lang=data.get('audio_lang', None),
            )
            session.merge(d)
            session.commit()

    @authenticated(constants.LEVEL_USER)
    async def patch(self, show_id):
        await self._patch(show_id)
        self.set_status(204)

    @run_on_executor
    def _patch(self, show_id):
        data = self.validate()
        with new_session() as session:
            d = models.User_show_subtitle_lang(
                user_id=self.current_user.id,
                show_id=show_id,
            )
            if 'subtitle_lang' in data:
                d.subtitle_lang = data['subtitle_lang']
            if 'audio_lang' in data:
                d.audio_lang = data['audio_lang']
            session.merge(d)
            session.commit()
예제 #3
0
파일: user.py 프로젝트: thomaserlang/seplis
class Collection_handler(base.Handler):

    __schema__ = good.Schema({
        'name':
        good.All(
            str, good.Length(min=1, max=45),
            good.Match(re.compile(r'^[a-z0-9-_]+$', re.I),
                       message='must only contain a-z, 0-9, _ and -')),
        'email':
        good.All(str, good.Length(min=1, max=100), schemas.validate_email),
        'password':
        good.All(str, good.Length(min=6)),
    })

    async def get(self):
        users = await self.get_users()
        self.write_object(users)

    async def post(self, user_id=None):
        if user_id:
            raise exceptions.Parameter_restricted('user_id must not be set.')
        user = await self.create()
        self.set_status(201)
        self.write_object(user)

    @run_on_executor
    def get_users(self):
        username = self.get_argument('username')
        with new_session() as session:
            user = session.query(models.User).filter(
                models.User.name == username, ).first()
            if user:
                return [self.user_wrapper(user.serialize())]
            return []

    @run_on_executor
    def create(self):
        user = self.validate()
        with new_session() as session:
            u = session.query(models.User.id).filter(
                models.User.email == user['email']).first()
            if u:
                raise exceptions.User_email_duplicate()

            u = session.query(models.User.id).filter(
                models.User.name == user['name']).first()
            if u:
                raise exceptions.User_username_duplicate()

            user = models.User(
                name=user['name'],
                email=user['email'],
                password=pbkdf2_sha256.encrypt(user['password']),
            )
            session.add(user)
            session.commit()
            return user.serialize()
예제 #4
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)
class Handler(Api_handler):

    __schema__ = good.Schema({
        'message':
        good.All(str, good.Length(min=1, max=500)),
        'webhook_url':
        good.Any(good.Url('https'), good.All(str, good.Length(max=0))),
    })

    @Level(3)
    async def get(self, channel_id):
        r = await self.db.fetchone(
            'SELECT webhook_url, message FROM twitch_discord_live_notification WHERE channel_id=%s',
            (channel_id, ))
        if not r:
            self.set_status(204)
        else:
            self.write_object({
                'webhook_url': r['webhook_url'],
                'message': r['message'],
            })

    @Level(3)
    async def put(self, channel_id):
        data = self.validate()
        r = await self.db.fetchone(
            'SELECT webhook_url, message FROM twitch_discord_live_notification WHERE channel_id=%s',
            (channel_id, ))
        if not r:
            await self.db.execute(
                '''
                INSERT INTO twitch_discord_live_notification
                    (channel_id, webhook_url, message)
                VALUES 
                    (%s, %s, %s);
            ''', (
                    channel_id,
                    data['webhook_url'],
                    data['message'],
                ))
        else:
            await self.db.execute(
                '''
                UPDATE twitch_discord_live_notification SET
                    webhook_url=%s, message=%s
                WHERE channel_id=%s
            ''', (
                    data['webhook_url'],
                    data['message'],
                    channel_id,
                ))
예제 #6
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)
예제 #7
0
class Banned_words_handler(Api_handler):

    __schema__ = good.Schema({
        'banned_words': good.All(str, good.Length(min=1, max=1000)),
    })

    @Level(1)
    async def post(self, channel_id, filter_id):
        d = self.validate()
        c = await self.db.execute('''
            INSERT INTO twitch_filter_banned_words 
            (channel_id, filter_id, banned_words)
            VALUES
            (%s, %s, %s)
        ''', (channel_id, filter_id, d['banned_words']))
        r = await self.redis.publish_json(
            'tbot:server:commands', 
            ['reload_filter_banned_words', channel_id, filter_id]
        )
        self.set_status(201)
        self.write_object({
            'id': c.lastrowid,
            'banned_words': d['banned_words'],
        })

    @Level(1)
    async def put(self, channel_id, filter_id, id_):
        d = self.validate()
        await self.db.execute('''
            UPDATE twitch_filter_banned_words SET banned_words=%s 
            WHERE id=%s and channel_id=%s and filter_id=%s
        ''', (d['banned_words'], id_, channel_id, filter_id,))
        r = await self.redis.publish_json(
            'tbot:server:commands', 
            ['reload_filter_banned_words', channel_id, filter_id]
        )
        self.set_status(204)

    @Level(1)
    async def delete(self, channel_id, filter_id, id_):
        await self.db.execute('''
            DELETE FROM twitch_filter_banned_words 
            WHERE id=%s and channel_id=%s and filter_id=%s
        ''', (id_, channel_id, filter_id,))
        r = await self.redis.publish_json(
            'tbot:server:commands', 
            ['reload_filter_banned_words', channel_id, filter_id]
        )
        self.set_status(204)
예제 #8
0
파일: user.py 프로젝트: thomaserlang/seplis
class Change_password_handler(base.Handler):

    __schema__ = good.Schema({
        'password': str,
        'new_password': good.All(str, good.Length(min=6)),
    })

    @authenticated(constants.LEVEL_USER)
    async def post(self, user_id=None):
        user_id = user_id if user_id else self.current_user.id
        self.check_user_edit(user_id)
        await self.change_password(user_id)
        self.set_status(204)

    @run_on_executor
    def change_password(self, user_id):
        data = self.validate()
        if not models.User.login(int(user_id), data['password']):
            raise exceptions.Wrong_email_or_password_exception()
        with new_session() as session:
            models.User.change_password(
                user_id=user_id,
                new_password=data['new_password'],
                session=session,
            )
            tokens = session.query(models.Token).filter(
                models.Token.user_id == user_id,
                or_(
                    models.Token.expires >= datetime.utcnow(),
                    models.Token.expires == None,
                )).all()
            for token in tokens:
                if token.token == self.access_token:
                    continue
                session.delete(token)
            session.commit()
예제 #9
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)
예제 #10
0
    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))),
}


class Collection_handler(Api_handler):

    __schema__ = good.Schema(_schema, default_keys=good.Required)

    @Level(1)
    async def get(self, channel_id):
        cmds = await self.db.fetchall(
            '''
            SELECT *
            FROM twitch_commands
            WHERE channel_id=%s
            ORDER BY updated_at DESC
예제 #11
0
import good
import sqlalchemy as sa
from seplis.api.handlers import base
from seplis.api.decorators import authenticated, new_session, run_on_executor
from seplis.api import exceptions, constants, models
from seplis import schemas

_schema = {
    'name': good.All(str, good.Length(min=1, max=45)),
    'url': good.All(str, good.Length(min=1, max=200)),
    'secret': good.All(str, good.Length(min=1, max=200)),
}


class Handler(base.Handler):
    '''Edit a play server. The user must be the owner.'''

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

    @authenticated(0)
    async def get(self, id_):
        server = await self._get(id_)
        self.write_object(server)

    @authenticated(0)
    async def put(self, id_):
        ps = await self._put(id_)
        self.write_object(ps)

    @authenticated(0)
    async def delete(self, id_):
예제 #12
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(
예제 #13
0
    '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},
    default_keys=good.Optional,
)
_Show_schema = {
    'title': good.Maybe(str),
    'description': good.Maybe(Description_schema),
    'premiered': good.Maybe(date_()),
    'ended': good.Maybe(date_()),
    good.Optional('episodes'): [Episode_schema],
    'externals': good.Any(None, External_schema),
    'importers': good.Any(None, Importer_schema),
    'status': good.Coerce(int),
예제 #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)
예제 #15
0
def Length(min=None, max=None, msg=None):
    return _wrapMsg(good.Length(min, max), msg)
예제 #16
0
class Handler(base.Handler):

    __schema__ = good.Schema({
        'key': str,
        'new_password': good.All(str, good.Length(min=6)),
    })

    __arguments_schema__ = good.Schema({
        'email': [str],
    })

    async def get(self):
        args = self.validate_arguments()
        user_id = await self.get_user_id(args['email'][0])
        if not user_id:
            self.set_status(204)
            return

        smtp = aiosmtplib.SMTP(
            hostname=config['smtp']['server'], 
            port=int(config['smtp']['port']),
            use_tls=config['smtp']['use_tls'], 
            loop=self.application.ioloop,
        )
        await smtp.connect()
        if config['smtp']['user']:
            await smtp.login(config['smtp']['user'], config['smtp']['password'])

        url = await self.create_reset_url(user_id)
        message = MIMEText('''
        <html>
        <body>
            Reset your SEPLIS password here: <a href="{0}">{0}</a>
        </body>
        </html>
        '''.format(url), 'html')
        message["From"] = config['smtp']['from']
        message["To"] = args['email'][0]
        message["Subject"] = "Reset password"
        await smtp.send_message(message)

        self.set_status(204)

    async def post(self):
        await self.reset()
        self.set_status(204)

    @run_on_executor
    def get_user_id(self, email):
        with new_session() as session:
            u = session.query(models.User.id).filter(
                models.User.email == email,
            ).first()
            if u:
                return u.id

    @run_on_executor
    def create_reset_url(self, user_id):
        with new_session() as session:
            r = models.Reset_password(
                user_id=user_id,
            )
            session.add(r)
            session.commit()
            return config['web']['url'] + '/reset-password/{}'.format(r.key)

    @run_on_executor
    def reset(self):
        data = self.validate()        
        with new_session() as session:
            r = session.query(models.Reset_password.user_id).filter(
                models.Reset_password.key == data['key'],
                models.Reset_password.expires >= datetime.utcnow(),
            ).first()
            if not r:
                raise exceptions.Forbidden('Invalid reset key')
            session.query(models.Reset_password).filter(
                models.Reset_password.user_id == r.user_id,
            ).delete()
            user_id = r.user_id
            models.User.change_password(
                user_id=user_id,
                new_password=data['new_password'],
                session=session,
            )
            tokens = session.query(models.Token).filter(
                models.Token.user_id == user_id,
                sa.or_(
                    models.Token.expires >= datetime.utcnow(),
                    models.Token.expires == None,
                )
            ).all()
            for token in tokens:
                if token.token == self.access_token:
                    continue
                session.delete(token)
            session.commit()