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
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)()
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()
class PayloadScheme(db.Model): __tablename__ = 'payload_scheme' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(64), unique=True) description = db.Column(db.String(512)) payload = db.Column(JSONType, nullable=False, default={})
class Currency(db.Model): __tablename__ = 'currencies' id = db.Column(db.Integer, primary_key=True, autoincrement=True) name = db.Column(db.String(128), nullable=True, unique=True) title = db.Column(db.String(128), nullable=True, unique=True) symbol = db.Column(db.String(128), nullable=True, unique=True) format = db.Column(db.String(128), nullable=True) active = db.Column(db.Boolean, nullable=False, default=True)
class Market(db.Model): __tablename__ = 'markets' id = db.Column(db.Integer, primary_key=True, autoincrement=True) name = db.Column(db.String(128), nullable=True) title = db.Column(db.String(512), nullable=True) enabled = db.Column(db.Boolean, nullable=False, default=True) sellers = db.relationship('Seller', backref='market', lazy='dynamic') items = db.relationship('Item', backref='market', lazy='dynamic')
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')
class Category(db.Model): __tablename__ = 'categories' id = db.Column(db.Integer, primary_key=True, autoincrement=True) name = db.Column(db.String(128), nullable=False, unique=True) description = db.Column(db.String(512), nullable=False) posts = db.relationship('Post', backref='category', lazy='dynamic') def __repr__(self): return '<Category(name=%s)>' % self.name
class Category(db.Model): __tablename__ = 'categories' id = db.Column(db.Integer, primary_key=True, autoincrement=True) name = db.Column(db.String(128), nullable=False, unique=True) description = db.Column(db.String(512), nullable=False) posts = db.relationship('Post', backref='category', lazy='dynamic') def get_posts(self): return self.posts.filter_by(active=True).all()
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)
class CrontabSchedule(Model): """ Task result/status. """ __tablename__ = "crontab_schedule" __table_args__ = (db.UniqueConstraint('minute', 'hour', 'day_of_week', 'day_of_month', 'month_of_year'), ) id = db.Column(db.Integer, primary_key=True, autoincrement=True) minute = db.Column(db.String(length=120), default="*") hour = db.Column(db.String(length=120), default="*") day_of_week = db.Column(db.String(length=120), default="*") day_of_month = db.Column(db.String(length=120), default="*") month_of_year = db.Column(db.String(length=120), default="*") periodic_tasks = db.relationship('PeriodicTask') def __str__(self): rfield = lambda f: f and str(f).replace(' ', '') or '*' return '{0} {1} {2} {3} {4} (m/h/d/dM/MY)'.format( rfield(self.minute), rfield(self.hour), rfield(self.day_of_week), rfield(self.day_of_month), rfield(self.month_of_year), ) @property def schedule(self): spec = { 'minute': self.minute, 'hour': self.hour, 'day_of_week': self.day_of_week, 'day_of_month': self.day_of_month, 'month_of_year': self.month_of_year } return schedules.crontab(**spec) # noinspection PyProtectedMember @classmethod def from_schedule(cls, session, schedule): spec = { 'minute': schedule._orig_minute, 'hour': schedule._orig_hour, 'day_of_week': schedule._orig_day_of_week, 'day_of_month': schedule._orig_day_of_month, 'month_of_year': schedule._orig_month_of_year } obj = cls.filter_by(session, **spec).first() if obj is None: return cls(**spec) else: return obj
class Bot(db.Model): """ Automation format: { "connect": [ { "group": "name_1" }, { "group": "name_2" }, ... { "group": "name_N" } ] } """ __tablename__ = 'bots' id = db.Column(db.Integer, primary_key=True, autoincrement=True) name = db.Column(db.String(128), nullable=False, unique=True) description = db.Column(db.String(512), nullable=False) payload = db.Column(JSONType, nullable=False, default={}) automation = db.Column(JSONType, nullable=False, default={}) last_login = db.Column(db.DateTime, nullable=True, default=None) created = db.Column(db.DateTime, default=timezone.now) enabled = db.Column(db.Boolean, nullable=False, default=True) actions = db.relationship('Action', secondary=bot_action_association, backref='bots', lazy='dynamic') @property def connect_groups(self) -> List[str]: return [item['group'] for item in self.automation['connect']] def __str__(self): return self.name def __repr__(self): return "<Bot(name=%s, description=%s)>" % (self.name, self.description) @hybrid_property def photo(self): return self.payload.get('avatar') @hybrid_property def first_name(self): return self.payload.get('first_name') @hybrid_property def last_name(self): return self.payload.get('last_name')
class Application(db.Model): __tablename__ = 'applications' id = db.Column(db.Integer, primary_key=True, autoincrement=True) name = db.Column(db.String(256), nullable=False) repo_url = db.Column(db.String(512), nullable=False) repo_branch = db.Column(db.String(128), default='master') repo_ssh_key = db.Column(db.Text) versions = db.relationship('ApplicationVersion', backref='application', lazy='dynamic', cascade='all, delete-orphan')
class Group(db.Model): __tablename__ = 'groups' 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) recoveries = db.relationship('Recovery', backref='group', lazy='dynamic') backups = db.relationship('Backup', backref='group', lazy='dynamic') def __repr__(self): return '<Group(name=%s)>' % self.name
class Environment(db.Model): __tablename__ = 'environments' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(64), unique=True) description = db.Column(db.String(512), nullable=False) discovery = db.Column(URLType, nullable=False) payload = db.Column(JSONType, nullable=False, default={}) color = db.Column(ColorType) active = db.Column(db.Boolean, nullable=False, default=True) app_versions = db.relationship('ApplicationVersion', backref='environment', lazy='dynamic')
class Application(db.Model): __tablename__ = 'applications' id = db.Column(db.Integer, primary_key=True, autoincrement=True) name = db.Column(db.String(128), nullable=False, unique=True) title = db.Column(db.String(512), nullable=False, unique=True) enabled = db.Column(db.Boolean, nullable=False, default=True) versions = db.relationship('ApplicationVersion', backref='application', lazy='dynamic') @as_future def latest_version(self): return self.versions.last()
class Group(InternalAPIMixin, db.Model): __tablename__ = 'groups' TYPES = ( ('p', _('Personal')), ('m', _('Multiple')), ('c', _('Channel')), ) id = db.Column(db.Integer, primary_key=True, autoincrement=True) name = db.Column(db.String(128), nullable=False, unique=True) type = db.Column(ChoiceType(TYPES)) 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) @as_future def get_messages(self, user_id=None, **kwargs) -> dict: default_kwargs = dict(active=True) if user_id is not None: default_kwargs.update(sender_id=user_id) default_kwargs.update(kwargs) data = {'model_name': 'Message', 'filter_data': default_kwargs} return self.internal_request('message', 'get_models', **data) @as_future def get_memberships(self, user_id=None, **kwargs): default_kwargs = dict(active=True) if user_id is not None: default_kwargs.update(user_id=user_id) default_kwargs.update(kwargs) return self.memberships.filter_by(**default_kwargs)
class Group(db.Model): __tablename__ = 'groups' id = db.Column(db.Integer, primary_key=True, autoincrement=True) name = db.Column(db.String(128), nullable=False, unique=True) type = db.Column(ChoiceType(GROUP_TYPES)) 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) messages = db.relationship('Message', backref='group', lazy='dynamic') @as_future def get_messages(self, user_id=None, **kwargs): default_kwargs = dict(active=True) if user_id is not None: default_kwargs.update(sender_id=user_id) default_kwargs.update(kwargs) return self.messages.filter_by(**default_kwargs) @as_future def get_memberships(self, user_id=None, **kwargs): default_kwargs = dict(active=True) if user_id is not None: default_kwargs.update(user_id=user_id) default_kwargs.update(kwargs) return self.memberships.filter_by(**default_kwargs)
class BaseModerationAction(InternalAPIMixin, db.Model): __abstract__ = True id = db.Column(db.Integer, primary_key=True, autoincrement=True) action_type = db.Column(ChoiceType(ACTION_TYPES), nullable=False) moderator_id = db.Column(db.Integer, nullable=False) user_id = db.Column(db.Integer, nullable=False) created_at = db.Column(db.DateTime, nullable=False, default=timezone.now) reason = db.Column(db.String(512), nullable=False) is_active = db.Column(db.Boolean, nullable=False, default=True) extra_data = db.Column(JSONType, nullable=False, default={}) def __init__(self, **kwargs): # for IDE inspection super().__init__(**kwargs) @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) async def get_moderator(self) -> RemoteUser: data = await self.request_user(user_id=self.moderator_id) return RemoteUser(**data) @as_future def turn_on(self, commit: bool = False) -> None: """Set action in active state.""" self.is_active = True self.save(commit) @as_future def turn_off(self, commit: bool = False) -> None: """Set action in inactive state.""" self.is_active = False self.save(commit) @hybrid_property def active(self) -> bool: return self.is_active @classmethod async def actions_query(cls, user_id: str, **filters) -> db.Query: """Get actions query for current user id.""" return cls.query.filter_by(active=True, user_id=user_id, **filters) @staticmethod async def send_email(user: RemoteUser, subject, message, from_email=None, **kwargs): await user.send_mail(subject, message, from_email, **kwargs) @staticmethod async def send_message(user: RemoteUser, message): await user.send_message(message)
class Scope(db.Model): __tablename__ = 'scope' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(255), nullable=False) def __repr__(self): return "Scope(id={0}, name={1})".format(self.id, self.name)
class GeoLocationRegion(db.Model): __tablename__ = 'geo_location_regions' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(64), unique=True) locations = db.relationship('GeoLocation', backref='region', lazy='dynamic')
class Category(db.Model): __tablename__ = 'category' id = db.Column(db.Integer, primary_key=True, autoincrement=True) name = db.Column(db.String(128), nullable=True, unique=True) scheme = db.Column(JSONType, nullable=False, default={}) items = db.relationship('Item', backref='category', lazy='dynamic') active = db.Column(db.Boolean, nullable=False, default=True)
class Role(db.Model): __tablename__ = 'role' id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(100)) def __repr__(self): return "Role(title={0})".format(self.title)
class AuditLog(InternalAPIMixin, db.Model): __tablename__ = 'audit_log' ACTIONS = ( ('create', _('Create')), ('update', _('Update')), ('delete', _('Delete')), ) id = db.Column(db.Integer, primary_key=True, autoincrement=True) created = db.Column(db.DateTime, default=timezone.now) service_name = db.Column(db.String(512), nullable=False) model_name = db.Column(db.String(512), nullable=False) object_id = db.Column(db.Integer, nullable=False) author_id = db.Column(db.Integer, nullable=False) action = db.Column(ChoiceType(ACTIONS), nullable=False) current_version = db.Column(db.Integer, nullable=False) previous_version = db.Column(db.Integer, nullable=False) async def get_author(self): return await self.internal_request('login', 'get_user', user_id=self.author_id) async def _get_version_object(self, version): kwargs = { 'model_name': self.model_name, 'object_id': self.object_id, 'version': version } return self.internal_request(service_name, 'object_version', **kwargs) async def get_current_object(self): return await self._get_version_object(version=self.current_version) async def get_previous_object(self): return await self._get_version_object(version=self.previous_version) async def recover(self): kwargs = { 'model_name': self.model_name, 'object_id': self.object_id, 'version': self.previous_version } await self.internal_request(service_name, 'object_recover', **kwargs)
class Store(db.Model): __tablename__ = 'stores' id = db.Column(db.Integer, primary_key=True, autoincrement=True) name = db.Column(db.String(128), nullable=True, unique=True) payload = db.Column(JSONType, nullable=False, default={}) orders = db.relationship('Order', backref='store', lazy='dynamic') items = db.relationship('Item', backref='store', lazy='dynamic') active = db.Column(db.Boolean, nullable=False, default=True)
class Backup(db.Model): __tablename__ = 'backups' id = db.Column(db.Integer, primary_key=True, autoincrement=True) group_id = db.Column(db.Integer, db.ForeignKey('groups.id')) name = db.Column(db.String(128), nullable=False) description = db.Column(db.String(512)) file = db.Column(db.FileType(upload_to='backups'), nullable=False) author_id = db.Column(db.Integer, nullable=False) created = db.Column(db.DateTime, default=timezone.now) recoveries = db.relationship('Recovery', backref='backup', lazy='dynamic') def __repr__(self): return '<Backup(name=%s)>' % self.name @as_future def recover(self): pass
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')
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', }
class Voting(db.Model): __tablename__ = 'voting' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(128), nullable=False) description = db.Column(db.String(512), nullable=False) start_at = db.Column(db.DateTime, default=timezone.now) finish_at = db.Column(db.DateTime, nullable=False) items = db.Column(ScalarListType(), nullable=False) users = db.Column(ScalarListType(), default=[]) enabled = db.Column(db.Boolean, default=True) anonymous = db.Column(db.Boolean, default=True) can_discard = db.Column(db.Boolean, default=True) select_count = db.Column(db.Integer, default=1) members = db.relationship('VotingMember', backref='voting', lazy='dynamic') @validates('finish_at') def validate_finish_at(self, key, value): if value <= self.start_at: raise ValueError('`finish_at` must be more then `start_at`') return value @hybrid_property def active(self) -> bool: return self.finish_at > timezone.now() >= self.start_at and self.enabled @active.expression def active(cls) -> bool: return db.and_( cls.finish_at > timezone.now(), cls.start_at <= timezone.now(), cls.enabled ) def result(self) -> list: if timezone.now() < self.start_at: raise VotingError('Voting not started') if self.anonymous: return [m.result for m in self.memderships] else: return [(m.result, m.user_id) for m in self.memderships]
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')