Exemple #1
0
class PeriodicTask(Model):
    __tablename__ = "periodic_task"

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(length=120), unique=True)
    task = db.Column(db.String(length=120))
    crontab_id = db.Column(db.Integer, db.ForeignKey('crontab_schedule.id'))
    crontab = db.relationship("CrontabSchedule",
                              back_populates="periodic_tasks")
    interval_id = db.Column(db.Integer, db.ForeignKey('interval_schedule.id'))
    interval = db.relationship("IntervalSchedule",
                               back_populates="periodic_tasks")
    args = db.Column(db.String(length=120))
    kwargs = db.Column(db.String(length=120))
    last_run_at = db.Column(db.DateTime, default=timezone.now)
    total_run_count = db.Column(db.Integer, default=0)
    enabled = db.Column(db.Boolean, default=True)
    no_changes = False

    def __str__(self):
        fmt = '{0.name}: {0.crontab}'
        return fmt.format(self)

    @property
    def schedule(self):
        if self.crontab:
            return self.crontab.schedule
        if self.interval:
            return self.interval.schedule
Exemple #2
0
class PartySession(InternalAPIMixin, db.Model):
    __tablename__ = 'party_sessions'

    class Roles(enum.Enum):
        ADMIN = 1000
        USER = 0

    class Permissions(enum.Enum):
        ADMIN = 1000
        CAN_CLOSE = ADMIN
        CAN_START = 500
        USER = 0

    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, nullable=False)
    party_id = db.Column(db.Integer, db.ForeignKey('parties.id'))
    party = db.relationship('Party', backref=db.backref('sessions', lazy='dynamic'))
    role = db.Column(db.Enum(Roles), default=Roles.USER)
    settings = db.Column(JSONType, nullable=False, default={})
    app_version_id = db.Column(db.Integer, db.ForeignKey('application_versions.id'))
    app_version = db.relationship(
        'ApplicationVersion', backref=db.backref('sessions', lazy='dynamic'))

    def has_permission(self, perm: Permissions) -> bool:
        return self.role.value >= perm.value

    @property
    def request_user(self):
        return partial(self.internal_request, 'login', 'get_user')

    async def get_user(self) -> RemoteUser:
        data = await self.request_user(user_id=self.user_id)
        return RemoteUser(**data)

    @hybrid_property
    def members(self):
        return self.party.members

    @_check_permission(Permissions.CAN_START)
    async def start_party(self) -> None:
        await self.party.start(self)

    async def join_server(self) -> None:
        await self.party.join_server(self)

    async def close(self, code=None, reason=None) -> None:
        # TODO: all party members want to know that
        await future_exec(self.delete)

    leave_party = close
Exemple #3
0
class Recovery(InternalAPIMixin, db.Model):
    __tablename__ = 'recoveries'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    created = db.Column(db.DateTime, default=timezone.now)
    group_id = db.Column(db.Integer, db.ForeignKey('groups.id'))  # TODO: ?
    backup_id = db.Column(db.Integer, db.ForeignKey('backups.id'))
    author_id = db.Column(db.Integer, nullable=False)

    # TODO:
    async def get_author(self):
        return await self.internal_request('login',
                                           'get_user',
                                           user_id=self.author_id)
Exemple #4
0
class ResultFormatter(db.Model):
    __tablename__ = 'formatters'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    template = db.Column(db.Text, nullable=False)
    action_id = db.Column(db.Integer, db.ForeignKey('actions.id'))
    enabled = db.Column(db.Boolean, nullable=False, default=True)
Exemple #5
0
class GeoLocation(db.Model):
    __tablename__ = 'geo_locations'

    id = db.Column(db.Integer, primary_key=True)
    point = db.Column(Geometry(geometry_type='POINT', srid=4326))
    region_id = db.Column(db.Integer, db.ForeignKey('geo_location_regions.id'))
    servers = db.relationship('Server', backref='geo_location', lazy='dynamic')
    default = db.Column(db.Boolean, nullable=False, default=False)

    @classmethod
    async def get_nearest(cls, lat, lon):
        """
        Find the nearest point to the input coordinates.
        Convert the input coordinates to a WKT point and query for nearest point.
        """
        pt = WKTElement('POINT({0} {1})'.format(lon, lat), srid=4326)
        return cls.query.order_by(cls.point.distance_box(pt)).first()

    @classmethod
    async def get_default(cls):
        return cls.query.filter_by(default=True).order_by(cls.id).first()

    @staticmethod
    async def from_point_to_xy(pt):
        """Extract x and y coordinates from a point geometry."""
        # noinspection PyUnresolvedReferences
        point_json = json.loads(db.session.scalar(func.ST_AsGeoJSON(pt.point)))
        return point_json['coordinates']
Exemple #6
0
class Bundle(db.Model):
    __tablename__ = 'bundles'

    STATUSES = (
        ('created', _('Created')),
        ('uploaded', _('Uploaded')),
        ('delivering', _('Delivering')),
        ('delivered', _('Delivered')),
        ('error', _('Error')),
    )

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(128), nullable=False)
    key = db.Column(db.String(64), nullable=False)
    filename = db.Column(db.String(128), nullable=False, unique=True)
    hash = db.Column(JSONType, nullable=False)
    filter = db.Column(JSONType, nullable=False)
    status = db.Column(ChoiceType(STATUSES), nullable=False, default='created')
    group_id = db.Column(
        db.Integer, db.ForeignKey('bundle_groups.id'), nullable=False, index=True)

    @property
    def application_version(self):
        return self.group.application_version

    @property
    def application(self):
        return self.application_version.application

    @property
    def deployment_method(self):
        return self.application.deployment_method

    @property
    def size(self):
        return default_storage.size(self.filename)

    @property
    def url(self):
        deployment_method = self.deployment_method.get_method()
        return deployment_method.url(self.filename)

    def make_hash(self, filename=None, group=None):
        newhash = {}
        group = group or self.group
        filename = filename or self.filename
        with default_storage.open(filename) as fd:
            hasher = Hasher(fd.read())
            for hash_type, hash_is_active in group.hash_types.items():
                if not hash_is_active:
                    # hash type not active, so skip
                    continue
                hash_type = hash_type.lower()
                hashing_method = getattr(hasher, hash_type, None)
                if callable(hashing_method):
                    newhash[hash_type] = hashing_method()
        return newhash

    def update_hash(self):
        self.hash = self.make_hash()
Exemple #7
0
class ApplicationVersion(db.Model):
    __tablename__ = 'application_versions'
    __table_args__ = (db.UniqueConstraint('value', 'application_id'), )

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    value = db.Column(db.String(128), nullable=False)
    application_id = db.Column(db.Integer,
                               db.ForeignKey('applications.id'),
                               nullable=False)
    environment_id = db.Column(db.Integer,
                               db.ForeignKey('environments.id'),
                               nullable=False)
    enabled = db.Column(db.Boolean, nullable=False, default=True)

    def __lt__(self, other):
        return self.value < other.value
Exemple #8
0
class Backup(db.Model):
    __tablename__ = 'backups'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    created = db.Column(db.DateTime, default=timezone.now)
    group_id = db.Column(db.Integer, db.ForeignKey('groups.id'))
    recoveries = db.relationship('Recovery', backref='backup', lazy='dynamic')
Exemple #9
0
class Action(db.Model):
    __tablename__ = 'actions'

    TYPES = (
        ('path', _('Path')),
        ('code', _('Code')),
    )

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(128), nullable=False)
    description = db.Column(db.String(512), nullable=False)
    value = db.Column(db.Text, nullable=False)
    type = db.Column(ChoiceType(TYPES))
    enabled = db.Column(db.Boolean, nullable=False, default=True)
    formatter_id = db.Column(db.Integer, db.ForeignKey('formatters.id'))

    def __repr__(self):
        return "<Action(name=%s, description=%s)>" % (self.name,
                                                      self.description)

    def __getattr__(self, item):
        return getattr(self.value_object, item)

    @cached_property
    def value_object(self) -> BaseAction:
        return import_string(self.value)()
Exemple #10
0
class Post(db.Model):
    __tablename__ = 'posts'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    created = db.Column(db.DateTime, default=timezone.now)
    content = db.Column(db.Text, nullable=False)
    active = db.Column(db.Boolean, nullable=False, default=True)
    category_id = db.Column(db.Integer, db.ForeignKey('categories.id'))
Exemple #11
0
class Item(db.Model):
    __tablename__ = 'items'
    __table_args__ = (db.UniqueConstraint('store_id', 'name'), )

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(128), nullable=True)
    store_id = db.Column(db.Integer, db.ForeignKey('stores.id'))
    category_id = db.Column(db.Integer, db.ForeignKey('category.id'))
    payload = db.Column(JSONType, nullable=False, default={})
    orders = db.relationship('Order', backref='item', lazy='dynamic')
    created = db.Column(db.DateTime, default=timezone.now)
    active = db.Column(db.Boolean, nullable=False, default=True)

    def description(self, lang):
        raise NotImplementedError

    def title(self, lang):
        raise NotImplementedError
Exemple #12
0
class Message(InternalAPIMixin, db.Model):
    __tablename__ = 'messages'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    sender_id = db.Column(db.Integer)
    created = db.Column(db.DateTime, default=timezone.now)
    updated = db.Column(db.DateTime, onupdate=timezone.now)
    active = db.Column(db.Boolean, nullable=False, default=True)
    draft = db.Column(db.Boolean, nullable=False, default=False)
    group_id = db.Column(db.Integer, db.ForeignKey('groups.id'))
    statuses = db.relationship('MessageStatus',
                               backref='message',
                               lazy='dynamic')
    reactions = db.relationship('MessageReaction',
                                backref='message',
                                lazy='dynamic')
    discriminator = db.Column(db.String)

    __mapper_args__ = {
        'polymorphic_on': discriminator,
        'polymorphic_identity': 'message',
    }

    @property
    def request_user(self):
        return partial(self.internal_request, 'login', 'get_user')

    async def get_sender(self) -> RemoteUser:
        data = await self.request_user(user_id=self.sender_id)
        return RemoteUser(**data)

    @classmethod
    @as_future
    def outgoing_messages(cls, sender_id, **kwargs):
        return cls.query.filter_by(active=True, sender_id=sender_id, **kwargs)

    @classmethod
    @as_future
    def incoming_messages(cls, receiver_id, **kwargs):
        return cls.query.filter_by(active=True, **kwargs).join(MessageStatus) \
            .filter(MessageStatus.receiver_id == receiver_id)

    @classmethod
    async def draft_messages(cls, sender_id, **kwargs):
        return await cls.outgoing_messages(sender_id).filter_by(draft=True,
                                                                **kwargs)

    @classmethod
    @as_future
    def new_messages(cls, receiver_id, **kwargs):
        return cls.query.filter_by(active=True, **kwargs).join(MessageStatus) \
            .filter(MessageStatus.receiver_id == receiver_id, MessageStatus.value == 'new')

    @as_future
    def add_reaction(self, user_id, value):
        # TODO: message_id = self.id
        pass
Exemple #13
0
class Credential(db.Model):
    __tablename__ = 'credential'

    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.ForeignKey('user.id'), nullable=False, unique=False)
    credential = db.Column(db.String, nullable=False)
    credential_type_id = db.Column(db.ForeignKey('credential_type.id'),
                                   nullable=False)
    expiration_dt = db.Column(db.DateTime(timezone=True), nullable=False)

    user = db.relationship('User',
                           backref='credential',
                           cascade="all, delete-orphan",
                           single_parent=True)

    def __repr__(self):
        return ("Credential(credential_type_id={0}, user_id={1})".format(
            self.credential_type_id, self.user_id))
Exemple #14
0
class ApplicationVersion(db.Model):
    __tablename__ = 'application_versions'
    __table_args__ = (db.UniqueConstraint('app_name', 'app_version'), )

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    app_name = db.Column(db.String(128), nullable=False)
    app_version = db.Column(db.String(128), nullable=False)
    build_id = db.Column(db.Integer, db.ForeignKey('builds.id'))
    build = db.relationship('Build')
Exemple #15
0
class URLMessage(Message):
    __tablename__ = 'url_messages'

    id = db.Column(db.Integer, db.ForeignKey('messages.id'), primary_key=True)
    content_type = db.Column(db.String(128), nullable=False)
    value = db.Column(URLType, nullable=False)

    __mapper_args__ = {
        'polymorphic_identity': 'url_message',
    }
Exemple #16
0
class ApplicationVersion(db.Model):
    __tablename__ = 'application_versions'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    value = db.Column(db.String(128), nullable=False)
    commit = db.Column(db.String(128), nullable=False, unique=True)
    application_id = db.Column(db.Integer,
                               db.ForeignKey('applications.id'),
                               nullable=False,
                               index=True)
Exemple #17
0
class ApplicationVersion(db.Model):
    __tablename__ = 'application_versions'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    value = db.Column(db.String(128), nullable=False)
    application_id = db.Column(
        db.Integer, db.ForeignKey('applications.id'), nullable=False, index=True)
    groups = db.relationship(
        'BundlesGroup', backref=db.backref('application_version'), lazy='dynamic',
        cascade='all, delete-orphan')
Exemple #18
0
class TextMessage(Message):
    __tablename__ = 'text_messages'

    id = db.Column(db.Integer, db.ForeignKey('messages.id'), primary_key=True)
    content_type = db.Column(db.String(128),
                             nullable=False,
                             default='text/plain')
    value = db.Column(db.Text, nullable=False)

    __mapper_args__ = {
        'polymorphic_identity': 'text_message',
    }
Exemple #19
0
class Application(db.Model):
    __tablename__ = 'applications'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    name = db.Column(db.String(256), nullable=False)
    deployment_method_id = db.Column(
        db.Integer, db.ForeignKey('deployment_methods.id'), nullable=False, index=True)
    filters_scheme = db.Column(JSONType, nullable=False)
    payload_scheme = db.Column(JSONType, nullable=False)
    versions = db.relationship(
        'ApplicationVersion', backref=db.backref('application'), lazy='dynamic',
        cascade='all, delete-orphan')
Exemple #20
0
class Room(InternalAPIMixin, db.Model):
    __tablename__ = 'rooms'

    id = db.Column(db.Integer, primary_key=True)
    server_id = db.Column(db.Integer, db.ForeignKey('servers.id'))
    app_version_id = db.Column(db.Integer,
                               db.ForeignKey('application_versions.id'))
    players = db.relationship('Player', backref='room', lazy='dynamic')
    settings = db.Column(JSONType, nullable=False, default={})
    max_players_count = db.Column(db.Integer, nullable=False, default=0)

    async def check_moderations(self):
        # TODO: get moderations from moderation servce
        if True:
            raise UserBannedError

    async def join(self, player):
        players = await future_exec(self.players.all)

        if len(players) >= self.max_players_count:
            raise PlayersLimitPerRoomExceeded
        await self.check_moderations()

        player.room_id = self.id
        await future_exec(self.players.append, player)

        # TODO: make other players to know about new player
        player_data1 = {}
        for p in players:
            await RemoteUser.send_message_by_user_id(
                p.id,
                message=json.dumps(player_data1),
                content_type='application/json')

        # TODO: send some info to the new player
        player_data2 = {}
        await RemoteUser.send_message_by_user_id(
            player.user_id,
            message=json.dumps(player_data2),
            content_type='application/json')
Exemple #21
0
class Order(InternalAPIMixin, db.Model):
    __tablename__ = 'orders'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    user_id = db.Column(db.Integer, nullable=False)
    item_id = db.Column(db.Integer, db.ForeignKey('items.id'))
    created = db.Column(db.DateTime, default=timezone.now)

    async def get_user(self) -> RemoteUser:
        data = await self.internal_request('login',
                                           'get_user',
                                           user_id=self.user_id)
        return RemoteUser(**data)
Exemple #22
0
class Seller(InternalAPIMixin, db.Model):
    __tablename__ = 'sellers'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    user_id = db.Column(db.Integer, nullable=False, unique=True)
    market_id = db.Column(db.Integer, db.ForeignKey('markets.id'))
    enabled = db.Column(db.Boolean, nullable=False, default=True)

    async def get_user(self) -> RemoteUser:
        data = await self.internal_request('login',
                                           'get_user',
                                           user_id=self.user_id)
        return RemoteUser(**data)
Exemple #23
0
class Player(InternalAPIMixin, db.Model):
    __tablename__ = 'players'

    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, nullable=False)
    room_id = db.Column(db.Integer, db.ForeignKey('rooms.id'))
    payload = db.Column(JSONType, nullable=False, default={})

    async def get_user(self) -> RemoteUser:
        data = await self.internal_request('login',
                                           'get_user',
                                           user_id=self.user_id)
        return RemoteUser(**data)
Exemple #24
0
class Permission(db.Model):
    __tablename__ = 'permission'

    id = db.Column(db.Integer, primary_key=True)
    domain_id = db.Column(db.ForeignKey('domain.id'), nullable=True)
    action_id = db.Column(db.ForeignKey('action.id'), nullable=True)
    resource_id = db.Column(db.ForeignKey('resource.id'), nullable=True)

    domain = db.relationship('Domain', backref='permission')
    action = db.relationship('Action', backref='permission')
    resource = db.relationship('Resource', backref='permission')

    roles = db.relationship('Role',
                            secondary=role_permission,
                            backref='permissions')

    users = association_proxy('roles', 'users')

    def __repr__(self):
        return (
            "Permission(domain_id={0},action_id={1},resource_id={2})".format(
                self.domain_id, self.action_id, self.resource_id))
Exemple #25
0
    class UserSocialAuth(_AppSession, SQLAlchemyUserMixin):
        """Social Auth association model."""
        uid = db.Column(db.String(UID_LENGTH))
        user_id = db.Column(User.id.type, db.ForeignKey(User.id), nullable=False, index=True)
        user = relationship(User, backref=backref('social_auth', lazy='dynamic'))

        @classmethod
        def username_max_length(cls):
            return User.__table__.columns.get('username').type.length

        @classmethod
        def user_model(cls):
            return User
Exemple #26
0
class Item(InternalAPIMixin, db.Model):
    __tablename__ = 'items'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    user_id = db.Column(db.Integer, nullable=False)
    market_id = db.Column(db.Integer, db.ForeignKey('markets.id'))
    orders = db.relationship('Order', backref='item', lazy='dynamic')
    created = db.Column(db.DateTime, default=timezone.now)
    payload = db.Column(JSONType, nullable=False, default={})
    price = db.Column(JSONType, nullable=False, default={})
    enabled = db.Column(db.Boolean, nullable=False, default=True)

    async def get_user(self) -> RemoteUser:
        data = await self.internal_request('login',
                                           'get_user',
                                           user_id=self.user_id)
        return RemoteUser(**data)
Exemple #27
0
class VotingMember(InternalAPIMixin, db.Model):
    __tablename__ = 'voting_members'
    __table_args__ = (
        db.UniqueConstraint('user_id', 'voting_id'),
    )

    id = db.Column(db.Integer, primary_key=True)
    user_id = db.Column(db.Integer, nullable=False)
    voting_id = db.Column(db.Integer, db.ForeignKey('voting.id'), nullable=False)
    result = db.Column(ScalarListType(), nullable=False)
    created = db.Column(db.DateTime, default=timezone.now)
    updated = db.Column(db.DateTime, onupdate=timezone.now)
    voted = db.Column(db.Boolean, default=False)
    enabled = db.Column(db.Boolean, default=True)

    async def get_user(self) -> RemoteUser:
        data = await self.internal_request('login', 'get_user', user_id=self.user_id)
        return RemoteUser(**data)

    @as_future
    def vote(self, items: Optional[list] = None) -> None:
        items = self.result or items
        if not items:
            raise VotingError('No items to vote')
        if not self.voting.active:
            raise VotingError('Voting not active')
        if not self.enabled:
            raise VotingError('Voting member disabled')
        if self.voted:
            raise VotingError('Already voted')
        if len(items) != self.voting.select_count:
            raise VotingError('Voting items count: %s/%s' % (len(items), self.voting.select_count))
        if not set(items).issubset(self.voting.items):
            raise VotingError('Voting items is %s. Must be a subset '
                              'of %s' % (','.join(items), ','.join(self.voting.items)))

        self.result = items
        self.voted = True
        self.save()

    @as_future
    def discard(self) -> None:
        if self.voting.can_discard:
            self.delete()
        else:
            raise VotingError('Cannot discard')
Exemple #28
0
class MessageStatus(InternalAPIMixin, db.Model):
    __tablename__ = 'message_statuses'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    value = db.Column(ChoiceType(MESSAGE_STATUSES), default='new')
    updated = db.Column(db.DateTime, onupdate=timezone.now)
    message_id = db.Column(db.Integer,
                           db.ForeignKey('messages.id', ondelete='CASCADE'))
    receiver_id = db.Column(db.Integer)

    @property
    def request_user(self):
        return partial(self.internal_request, 'login', 'get_user')

    async def get_receiver(self) -> RemoteUser:
        data = await self.request_user(user_id=self.receiver_id)
        return RemoteUser(**data)
Exemple #29
0
class Post(db.Model):
    __tablename__ = 'posts'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    created = db.Column(db.DateTime, default=timezone.now)
    content = db.Column(db.Text, nullable=False)
    enabled = db.Column(db.Boolean, nullable=False, default=True)
    category_id = db.Column(db.Integer, db.ForeignKey('categories.id'))
    image = db.Column(db.ImageType(width=None, height=None))

    @hybrid_property
    def active(self):
        return self.enabled and self.created <= timezone.now()

    @active.expression
    def active(cls) -> bool:
        return db.and_(cls.created <= timezone.now(), cls.enabled)
Exemple #30
0
class MessageReaction(InternalAPIMixin, db.Model):
    __tablename__ = 'message_reactions'
    __table_args__ = (db.UniqueConstraint('message_id', 'user_id', 'value'), )

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    value = db.Column(db.String(32))
    message_id = db.Column(db.Integer,
                           db.ForeignKey('messages.id', ondelete='CASCADE'))
    user_id = db.Column(db.Integer)

    @property
    def request_user(self):
        return partial(self.internal_request, 'login', 'get_user')

    async def get_user(self) -> RemoteUser:
        data = await self.request_user(user_id=self.user_id)
        return RemoteUser(**data)