class Watch(Base): """Watch target and user.""" __tablename__ = 'toranoana_watch' id = Column(Integer, primary_key=True) print_target_id = Column(String, nullable=False) genre_id = Column(Integer, ForeignKey(Genre.id)) genre = relationship(Genre) male = Column( ChoiceType(Target, impl=Integer()), nullable=False, ) female = Column( ChoiceType(Target, impl=Integer()), nullable=False, ) @hybrid_property def male_text(self) -> str: return TARGET_LABEL[self.male] @hybrid_property def female_text(self) -> str: return TARGET_LABEL[self.female]
class Socket(SQLModelMixin, db.Model): __tablename__ = 'sockets' id = db.Column(db.Integer, primary_key=True, autoincrement=True) uuid = db.Column(db.String(36), index=True, default=lambda: unicode(uuid4()).lower()) name = db.Column(db.String(20), index=True) description = db.Column(db.String(100)) type = db.Column(ChoiceType(SocketType, impl=db.Integer()), default=SocketType.TCP) direction = db.Column(ChoiceType(SocketDirection, impl=db.Integer()), default=SocketDirection.Listen) uri = db.Column(db.String(100)) address = db.Column(IPAddressType, nullable=False) port = db.Column(db.Integer, nullable=False) proc_id = db.Column(db.Integer, db.ForeignKey('trade_processes.id'), index=True) @property def ip(self): return self.address.exploded @ip.setter def ip(self, addr): self.address = ip_address(unicode(addr)) @observes('uri') def uriObserver(self, uri): if 'default' in uri: uri_pattern = re.compile( r'(?:\w+:)?default\s+-h\s+(?P<ip>[\d.]+)\s+-p\s+(?P<port>\d+)') else: uri_pattern = re.compile( r'(?P<protocal>[^:]+)://(?P<ip>[^:]+):(?P<port>.+)$') parse = uri_pattern.match(uri).groupdict() if re.match('[Uu][Dd][Pp]', parse.get('protocal', '')): self.type = SocketType.UDP else: self.type = SocketType.TCP if (parse['ip'] in ['127.0.0.1', 'localhost', u'127.0.0.1', u'localhost'] and (self.direction == SocketDirection.Listen.value or self.direction == SocketDirection.Listen or (isinstance(self.direction, SocketDirection) and self.direction.is_(None)) or self.direction is None)): self.address = ip_address(u'0.0.0.0') else: self.address = ip_address(unicode(parse['ip'])) self.port = int(parse['port'])
class DataSource(SQLModelMixin, db.Model): __tablename__ = "data_sources" id = db.Column(db.Integer, primary_key=True, autoincrement=True) name = db.Column(db.String(20), unique=True, index=True) description = db.Column(db.String(100)) sys_id = db.Column(db.Integer, db.ForeignKey('trade_systems.id'), index=True) src_type = db.Column(ChoiceType(DataSourceType, impl=db.Integer()), default=DataSourceType.SQL, nullable=False) src_model = db.Column(ChoiceType(DataSourceModel, impl=db.Integer()), nullable=False) source = db.Column(JSONType, nullable=False) disabled = db.Column(db.Boolean, default=False)
class TradeProcess(SQLModelMixin, db.Model): def __init__(self, name, sys_id, svr_id, type=HaType.Master, **kwargs): self.name = name self.sys_id = sys_id self.svr_id = svr_id self.type = type super(TradeProcess, self).__init__(**kwargs) __tablename__ = 'trade_processes' id = db.Column(db.Integer, primary_key=True, autoincrement=True) uuid = db.Column(db.String(36), index=True, default=lambda: unicode(uuid4()).lower()) name = db.Column(db.String(20), nullable=False, index=True) description = db.Column(db.String(100)) type = db.Column(ChoiceType(HaType, impl=db.Integer()), default=HaType.Master) version = db.Column(JSONType, default=[]) version_method = db.Column(db.String(100)) base_dir = db.Column(db.String(100)) exec_file = db.Column(db.String(50), nullable=False) param = db.Column(db.String(50)) sys_id = db.Column(db.Integer, db.ForeignKey('trade_systems.id'), index=True) svr_id = db.Column(db.Integer, db.ForeignKey('servers.id'), index=True) sockets = db.relationship('Socket', backref='process') disabled = db.Column(db.Boolean, default=False) config_files = db.relationship( 'ConfigFile', backref='process', primaryjoin="and_(ConfigFile.proc_id==TradeProcess.id," "ConfigFile.disabled==False)")
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 Tag(BaseModel): __tablename__ = "tags" name = db.Column(db.String(32), unique=True, nullable=False) tag_type = db.Column(ChoiceType(TagType, impl=db.Integer()), nullable=False) games_in_genre = db.relationship('Game', secondary="assoc_game_genres", back_populates="genres") games_in_tag = db.relationship('Game', secondary="assoc_game_tags", back_populates="tags") def __init__(self, name, tag_type="Generic"): self.name = name self.tag_type = tag_type @property def is_genre(self): return self.tag_type is TagType.GENRE @property def is_generic(self): return self.tag_type is TagType.GENERIC
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 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)
def upgrade(): """Upgrade database.""" op.create_table( 'crawler_job', sa.Column('id', sa.Integer, primary_key=True, autoincrement=True), sa.Column('job_id', UUIDType, index=True), sa.Column('spider', sa.String(255), index=True), sa.Column('workflow', sa.String(255), index=True), sa.Column('results', sa.Text, nullable=True), sa.Column('status', ChoiceType(JobStatus, impl=sa.String(10)), nullable=False), sa.Column('logs', sa.Text, nullable=True), sa.Column('scheduled', sa.DateTime, default=datetime.now, nullable=False, index=True)) op.create_table( 'crawler_workflows_object', sa.Column('job_id', UUIDType, primary_key=True), sa.Column('object_id', sa.Integer, sa.ForeignKey( 'workflows_object.id', ondelete="CASCADE", onupdate="CASCADE", ), primary_key=True))
class IntervalSchedule(Model): __tablename__ = "interval_schedule" PERIOD_CHOICES = (('days', _('Days')), ('hours', _('Hours')), ('minutes', _('Minutes')), ('seconds', _('Seconds')), ('microseconds', _('Microseconds'))) id = db.Column(db.Integer, primary_key=True, autoincrement=True) every = db.Column(db.Integer, nullable=False) period = db.Column(ChoiceType(PERIOD_CHOICES)) periodic_tasks = db.relationship('PeriodicTask') @property def schedule(self): return schedules.schedule( datetime.timedelta(**{self.period.code: self.every})) @classmethod def from_schedule(cls, session, schedule, period='seconds'): every = max(schedule.run_every.total_seconds(), 0) obj = cls.filter_by(session, every=every, period=period).first() if obj is None: return cls(every=every, period=period) else: return obj def __str__(self): if self.every == 1: return _('every {0.period_singular}').format(self) return _('every {0.every} {0.period}').format(self) @property def period_singular(self): return self.period[:-1]
class Collection(TableBase): __tablename__ = 'collection' __tableargs__ = (sqlalchemy.UniqueConstraint('name', 'type')) TYPES = [('tag', 'Tag'), ('category', 'Category')] id = Column(Integer, primary_key=True) type = Column(ChoiceType(TYPES)) name = Column(String(length=50)) featured = Column(Boolean, default=False) create_ts = Column(ArrowType, default=arrow.utcnow) modify_ts = Column(ArrowType, default=arrow.utcnow) applications = relationship('Application', secondary=ApplicationCollection, back_populates='collections') def to_json(self): return { 'id': self.id, 'type': self.type.value, 'name': self.name, 'featured': self.featured, 'create_ts': self.create_ts.isoformat(), 'modify_ts': self.modify_ts.isoformat(), 'applications': [] }
class ExpenseCategory(Base): """ Возможные статьи расходов. """ __tablename__ = 'expense_category' id = Column(Integer, Sequence('id'), primary_key=True, autoincrement=True) name = Column(ChoiceType(EXPENSES))
class Checksum(SingleStringValueModel): TYPE_SHA256 = 'sha256' TYPE_MD5 = 'md5' TYPES = [(TYPE_SHA256, 'sha256'), (TYPE_MD5, 'md5')] type = db.Column(ChoiceType(TYPES)) def __str__(self): return '<Checksum {0.id} {0.type} {0.value}>'.format(self)
class Workflow(db.Model): """Represents a workflow instance storing the state of the workflow.""" __tablename__ = "workflows_workflow" uuid = db.Column(UUIDType, primary_key=True, nullable=False, default=uuid.uuid4()) name = db.Column(db.String(255), default="Default workflow", nullable=False) created = db.Column(db.DateTime, default=datetime.now, nullable=False) modified = db.Column(db.DateTime, default=datetime.now, onupdate=datetime.now, nullable=False) id_user = db.Column(db.Integer, default=0, nullable=False) extra_data = db.Column(JSONType().with_variant( postgresql.JSON(none_as_null=True), 'postgresql', ), default=lambda: dict(), nullable=False) status = db.Column(ChoiceType(WorkflowStatus, impl=db.Integer()), default=WorkflowStatus.NEW, nullable=False) objects = db.relationship("WorkflowObjectModel", backref='workflows_workflow', cascade="all, delete-orphan") def __repr__(self): """Represent a Workflow instance.""" return "<Workflow(name: %s, cre: %s, mod: %s," \ "id_user: %s, status: %s)>" % \ (str(self.name), str(self.created), str(self.modified), str(self.id_user), str(self.status)) def __str__(self): """Represent a Workflow instance.""" return self.__repr__() @classmethod def delete(cls, uuid): """Delete a workflow.""" to_delete = Workflow.query.get(uuid) db.session.delete(to_delete) def save(self, status=None): """Save object to persistent storage.""" with db.session.begin_nested(): self.modified = datetime.now() if status is not None: self.status = status if self.extra_data is None: self.extra_data = dict() flag_modified(self, 'extra_data') db.session.merge(self)
class Purchase(Base): """ Логическая трата, которых может быть несколько в сообщении пользователя. """ __tablename__ = 'purchase' id = Column(Integer, Sequence('id'), primary_key=True, autoincrement=True) kind = Column(ChoiceType(PurchaseInputKind), default=PurchaseInputKind.simple) user_message_id = Column(Integer) status = Column(ChoiceType(PurchaseStatus), default=PurchaseStatus.open) position = Column(Integer) currency = Column(CurrencyType, default=OLD_BELARUSSIAN_RUBLE_CODE) user_id = Column(Integer) epoch = Column(TIMESTAMP()) price = Column(Float(asdecimal=True)) expense = Column(Integer, ForeignKey('expense_category.id')) conversation_id = Column(Integer, ForeignKey('conversation.id')) note = Column(String(200)) conversation = relationship('Conversation', back_populates='purchases') @property def bot_message_id(self): """ Предвычесленный id резульирующего сообщения, описывающего реакцию бота на каждое из введенных логических трат. """ return self.user_message_id + self.position @property def rounded_price(self): """ Цену округляем до двух знаков после запятой. """ return round(self.price, 2) @property def currency_code(self): """ Костыль библиотеки, в которой нет BYN кода. """ return NEW_BELARUSSIAN_RUBLE_CODE if self.currency == OLD_BELARUSSIAN_RUBLE_CODE else self.currency @property def category_name(self): return dict(EXPENSES).get(str(self.expense), "").capitalize()
class StandardAbapAuthSelectionOptionMixin: CHOICE_SIGN = [('I', 'Include'), ('E', 'Exclude')] CHOICE_OPTION = [('EQ', 'Equal'), ('NE', 'Not Equal'), ('GT', 'Greater Than'), ('GE', 'Greater or Equal'), ('LT', 'Lower Than'), ('LE', 'Lower or Equal')] SIGN = Column( ChoiceType(CHOICE_SIGN), nullable=False, default='I', qt_label='Incl./Excl.', qt_description= 'Should the specified items be included or excluded? Default is to include them', choices=CHOICE_SIGN, ) OPTION = Column( ChoiceType(CHOICE_SIGN), nullable=False, default='EQ', qt_label='Sel. Option', qt_description='Selection option', choices=CHOICE_OPTION, ) LOW = Column( String(12), nullable=False, qt_label='Lower Range Value', qt_description='Lower Range Value. Must be specified.', ) HIGH = Column( String(12), nullable=True, qt_label='Higher Range Value', qt_description='Higher Range Value. Optional.', )
class OpPrivilege(SQLModelMixin, db.Model): __tablename__ = 'privileges' id = db.Column(db.Integer, primary_key=True, autoincrement=True) @property def name(self): return '{}.{}'.format(self.uri, self.bit.name) uri = db.Column(db.String(100), nullable=False, index=True) bit = db.Column(ChoiceType(MethodType, impl=db.Integer())) def HasMethod(self, method): return self.bit.value & method.value == method.value
class Search(Base): TYPES = [(str(SauceNao.API_HTML_TYPE), 'HTML type'), (str(SauceNao.API_JSON_TYPE), 'JSON type')] output_type = db.Column(ChoiceType(TYPES)) checksums = db.relationship('Checksum', secondary=search_checksums, lazy='subquery', backref=db.backref('searchs', lazy=True)) combine_api_types = db.Column(db.Boolean) results = db.relationship('Result', secondary=search_results, lazy='subquery', backref=db.backref('searchs', lazy=True))
class Server(SQLModelMixin, db.Model): __tablename__ = 'servers' id = db.Column(db.Integer, primary_key=True, autoincrement=True) uuid = db.Column(db.String(36), index=True, default=lambda: unicode(uuid4()).lower()) name = db.Column(db.String(20), unique=True, index=True) survey = db.Column(JSONType, default={}) description = db.Column(db.String(100)) platform = db.Column(ChoiceType(PlatformType, impl=db.Integer()), default=PlatformType.Linux) manage_ip = db.Column(IPAddressType, index=True) disabled = db.Column(db.Boolean, default=False) admin_user = db.Column(db.String(20), index=True) admin_pwd = db.Column(db.String(32)) processes = db.relationship( 'TradeProcess', backref='server', lazy='dynamic', primaryjoin="and_(TradeProcess.svr_id == Server.id," "TradeProcess.disabled == False)") @property def ip(self): return self.manage_ip.exploded @ip.setter def ip(self, addr): self.manage_ip = ip_address(unicode(addr)) @property def user(self): return self.admin_user @user.setter def user(self, username): self.admin_user = username @property def password(self): if globalEncryptKey: return AESCrypto.decrypt(self.admin_pwd, globalEncryptKey) else: return self.admin_pwd @password.setter def password(self, password): if globalEncryptKey: self.admin_pwd = AESCrypto.encrypt(password, globalEncryptKey) else: self.admin_pwd = password
class CrawlerJob(db.Model): """Keeps track of submitted crawler jobs.""" __tablename__ = 'crawler_job' id = db.Column(db.Integer, primary_key=True, autoincrement=True) job_id = db.Column(UUIDType, index=True) spider = db.Column(db.String(255), index=True) workflow = db.Column(db.String(255), index=True) results = db.Column(db.Text, nullable=True) status = db.Column(ChoiceType(JobStatus, impl=db.String(10)), nullable=False) logs = db.Column(db.Text, nullable=True) scheduled = db.Column(db.DateTime, default=datetime.now, nullable=False, index=True) @classmethod def create(cls, job_id, spider, workflow, results=None, logs=None, status=JobStatus.PENDING): """Create a new entry for a scheduled crawler job.""" obj = cls( job_id=job_id, spider=spider, workflow=workflow, results=results, logs=logs, status=status, ) db.session.add(obj) return obj @classmethod def get_by_job(cls, job_id): """Get a row by Job UUID.""" try: return cls.query.filter_by(job_id=job_id).one() except NoResultFound: raise CrawlerJobNotExistError(job_id) def save(self): """Save object to persistent storage.""" with db.session.begin_nested(): db.session.add(self)
class Flights(ResourceMixin, db.Model): TYPES = [('A', 'Arrival'), ('D', 'Departure')] __tablename__ = 'flights' id = db.Column(db.Integer(), primary_key=True) flight_num = db.Column(db.String(10), nullable=False) terminal = db.Column(db.String(5), nullable=False) scheduled_time = db.Column(AwareDateTime(), nullable=False) actual_time = db.Column(AwareDateTime(), nullable=False) type_ = db.Column(ChoiceType(TYPES), nullable=False) pax = db.Column(db.Integer, nullable=False, default=0) num_containers = db.Column(db.Integer, nullable=False, default=0) bay = db.Column(db.String(5), nullable=False) def __init__(self, **kwargs): super(Flights, self).__init__(**kwargs) def to_dict(self): return { 'flight_num': self.flight_num, 'terminal': self.terminal, 'scheduled_time': localize(self.scheduled_time), 'type': self.type_.value, 'containers': self.num_containers, 'actual_time': localize(self.actual_time), 'bay': self.bay } # @classmethod # def update_arrival_time(cls): # records = Flights.query.filter( # ((now() + td(minutes=30) > Flights.scheduled_time) & (now() + td(hours=4) <= Flights.scheduled_time)) # ).all() # noise = rng.normal(0, 5, len(records)) # for r, n in zip(records, noise): # r.time += td(minutes=n) # db.session.add(r) # db.session.commit() @classmethod def get_flight_from_time(cls, start: dt, forecast=4): results = Flights.query.filter((Flights.scheduled_time >= start) & ( Flights.scheduled_time <= start + td(hours=forecast))).all() return [i.to_dict() for i in results]
class Notice(Base): """Notice.""" __tablename__ = 'saomd_notice' id = Column(Integer, primary_key=True) notice_id = Column(Integer, nullable=False) server = Column(ChoiceType(Server, impl=Integer()), nullable=False) title = Column(String, nullable=False) duration = Column(String) short_description = Column(String)
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)
class Conversation(Base): """ Пользователь может ввести в одном сообщении как одну трату, так и несколько (несколько скопированных sms, либо несколько трат в одной строке). За кулисами сообщение разбивается на отдельные траты. Данная модель определяет реплику пользователя и реплику-ответ бота, т.е. своеобразный элемент диалога. """ __tablename__ = 'conversation' id = Column(Integer, Sequence('id'), primary_key=True, autoincrement=True) purchases = relationship('Purchase', back_populates='conversation') status = Column(ChoiceType(ConversationStatus), default=ConversationStatus.open) bot_message_id = Column(Integer) @property def purchases_count(self): return len(self.purchases)
class EventParticipation(InternalAPIMixin, db.Model): __tablename__ = 'event_participations' __table_args__ = ( db.UniqueConstraint('user_id', 'event_id'), ) STATUSES = ( ('joined', _('Joined')), ('leaved', _('Leaved')) ) id = db.Column(db.Integer, primary_key=True, autoincrement=True) created_at = db.Column(db.DateTime, nullable=False, default=timezone.now) status = db.Column(ChoiceType(STATUSES)) payload = db.Column(JSONType, nullable=False, default={}) user_id = db.Column(db.Integer, nullable=False) event_id = db.Column(db.Integer, db.ForeignKey('events.id'), nullable=False) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.Schema = self.get_schema_class() @classmethod def get_schema_class(cls): class _Schema(ma.Schema): class Meta: model = cls fields = ('payload', 'created_at', 'status', 'event') return _Schema def dumps(self) -> dict: return self.Schema().dump(self).data async def on_status_changed(self) -> None: user = await self.get_user() msg = { 'type': EVENT_PARTICIPATION_STATUS_CHANGED, 'data': self.dumps() } await user.send_message(message=json.dumps(msg), content_type='application/json') async def get_user(self): return await self.internal_request('login', 'get_user', user_id=self.user_id)
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 OperationBook(SQLModelMixin, db.Model): __tablename = 'operation_book' id = db.Column(db.Integer, primary_key=True, autoincrement=True) uuid = db.Column(db.String(36), index=True, default=lambda: unicode(uuid4()).lower()) name = db.Column(db.String(20), index=True) description = db.Column(db.String(100)) type = db.Column(ChoiceType(ScriptType, impl=db.Integer())) catalog_id = db.Column(db.Integer, db.ForeignKey('operation_catalogs.id'), index=True) detail = db.Column(JSONType, nullable=False, default={}) sys_id = db.Column(db.Integer, db.ForeignKey('trade_systems.id'), index=True) disabled = db.Column(db.Boolean, default=False) order = db.Column(db.Integer) operations = db.relationship( 'Operation', backref='operate_define', primaryjoin="and_(Operation.book_id==OperationBook.id," "Operation.disabled==False)") @observes('sys_id') def remoteConfigObserver(self, sys_id): sys = TradeSystem.find(id=sys_id) if sys: if ((isinstance(self.type, ScriptType) and not self.type.IsInteractivator()) or (self.type != ScriptType.Interactivator.value and self.type != ScriptType.Interactive_Checker.value)): new_dtl = json.loads(json.dumps(self.detail)) new_dtl.update({ 'remote': { 'params': { 'ip': sys.ip, 'user': sys.login_user, 'password': sys.login_pwd }, 'name': self.detail['remote']['name'] } }) self.detail = new_dtl
class Server(InternalAPIMixin, db.Model): __tablename__ = 'servers' STATUSES = ( ('active', _('Active')), ('failed', _('Failed')), ('overload', _('Overload')), ) id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(64), unique=True) location = db.Column(URLType, nullable=False, unique=True) geo_location_id = db.Column(db.Integer, db.ForeignKey('geo_locations.id')) last_heartbeat = db.Column(db.DateTime) status = db.Column(ChoiceType(STATUSES)) last_failure_tb = db.Column(db.Text) enabled = db.Column(db.Boolean, nullable=False, default=True) rooms = db.relationship('Room', backref='server', lazy='dynamic') cpu_load = db.Column(db.Float, nullable=False, default=0.0) ram_usage = db.Column(db.Float, nullable=False, default=0.0) @hybrid_property def active(self): return self.enabled and self.status == 'active' @classmethod async def get_optimal(cls, region_id): # TODO: return cls.query.filter_by(active=True).first() @as_future def heartbeat(self, report: Union[HeartbeatReport, RequestError]): if isinstance(report, RequestError): self.status = 'failed' self.last_failure_tb = traceback.format_tb(report.__traceback__) elif isinstance(report, HeartbeatReport): self.last_heartbeat = timezone.now() self.cpu_load = report.cpu_load self.ram_usage = report.ram_usage self.status = 'overload' if report.is_overload() else 'active' else: raise ValueError('`report` argument should be either instance of' 'HeartbeatReport or RequestError') self.save()
class SearchImagePage(db.Model): TYPE_SIMILAR = '1' TYPE_SIZE = '2' TYPES = [ (TYPE_SIMILAR, 'Similar'), (TYPE_SIZE, 'Size'), ] id = db.Column(db.Integer, primary_key=True) created_at = db.Column(TIMESTAMP, default=datetime.utcnow, nullable=False) page = db.Column(db.Integer, default=1, nullable=False) search_type = db.Column(ChoiceType(TYPES)) search_img_id = db.Column(db.Integer, db.ForeignKey('search_image.id')) search_img = relationship('SearchImage', foreign_keys='SearchImagePage.search_img_id', lazy='subquery', backref=db.backref('pages', lazy=True)) match_results = db.relationship('MatchResult', secondary=search_image_match_results, lazy='subquery', backref=db.backref('search_image_pages', lazy=True))
class File(TableBase): __tablename__ = 'file' TYPES = [ ('header', 'header'), ('icon', 'icon'), ('list', 'list'), ('screenshot', 'screenshot'), ('pbw', 'pbw'), ] id = Column(Integer, primary_key=True) sha256 = Column(String(length=64), unique=True) application_id = Column(Integer, ForeignKey('application.id'), nullable=False) type = Column(ChoiceType(TYPES)) path = Column(String) image_width = Column(Integer, default=0) image_height = Column(Integer, default=0) application = relationship('Application', back_populates='files')