class Factory(BaseModel, db.Model): """厂房信息""" __tablename__ = "ihome_factory" UNIT_TYPE = [('元/月', '元/月'), ('元/年', '元/年')] id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(100), nullable=False) # 标题 content = db.Column(db.String(1000), nullable=False) # 内容 # 房屋主人的用户编号 user_id = db.Column(db.Integer, db.ForeignKey("ihome_user.id"), nullable=False) city_id = db.Column(db.Integer, db.ForeignKey("ihome_city.id"), nullable=False) area_id = db.Column(db.Integer, db.ForeignKey("ihome_area.id"), nullable=False) street_id = db.Column(db.Integer, db.ForeignKey("ihome_street.id"), nullable=False) village_id = db.Column(db.Integer, db.ForeignKey("ihome_village.id"), nullable=False) address = db.Column(db.String(512), default="") # 地址 acreage = db.Column(db.Integer, default=0) #面积 price = db.Column(db.Integer, default=0) #价格 unit = db.Column(ChoiceType(UNIT_TYPE)) # room_count = db.Column(db.Integer, default=1) # 房间数目 contact_person = db.Column(db.String(10), nullable=False) #联系人 contact_mobile = db.Column(db.String(15), nullable=False) # 联系电话 images = db.relationship("FactoryImage") # 房屋的图片 index_image_url = db.Column(db.String(256), default="") # 房屋主图片的路径 # 房屋的设施 facilities = db.relationship("Facility", secondary=ihome_factory_facility) def to_dict(self): print(dir(self.unit)) return { 'id': self.id, 'title': self.title, 'content': self.content, 'image': self.index_image_url if self.index_image_url else '', 'village': self.village_id, 'address': self.address, 'acreage': self.acreage, 'price': self.price, 'unit': self.unit.value, 'room_count': self.room_count, 'contact_person': self.contact_person, 'contact_mobile': self.contact_mobile, 'create_time': self.create_time.strftime('%Y-%m-%d %H:%M:%S'), 'room': self.room_count, 'images': [image.url for image in self.images], 'facilities': [facility.to_dict() for facility in self.facilities], } def to_full_dict(self): return { 'id': self.id, 'user_avatar': self.user.avatar if self.user.avatar else '', 'user_name': self.user.name, 'contact_person': self.contact_person, 'contact_mobile': self.contact_mobile, 'title': self.title, 'price': self.price, # 'address': self.area.name + self.address, 'address': self.address, 'room_count': self.room_count, 'acreage': self.acreage, 'unit': self.unit.value, 'images': [image.url for image in self.images], 'facilities': [facility.to_dict() for facility in self.facilities], }
class User(db.Model): """ Class reference to user """ ROLES = [(u'admin', _('Admin')), (u'contributor', _('Contributor')), (u'moderator', _('Moderator'))] __tablename__ = "user" id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(80), unique=True) _password = db.Column(db.String(255)) email = db.Column(db.String(120), unique=True) name = db.Column(db.String(120)) joined_date = db.Column(db.DateTime, default=datetime.now()) active = db.Column(db.Boolean, default=False) _avatar = db.Column(db.String(100), default='default.png') role = db.Column(ChoiceType(ROLES), default=u'') #: Relationships with others models documents = db.relationship('Document', backref='user', lazy='dynamic') account_registration = db.relationship('AccountRegistration', backref='user', lazy='dynamic') favorite_documents = db.relationship('Document', secondary=user_favorite_documents, backref=db.backref('users', lazy='dynamic'), lazy='dynamic') followed = db.relationship('User', secondary=followers, primaryjoin=(followers.c.follower_id == id), secondaryjoin=(followers.c.followed_id == id), backref=db.backref('followers', lazy='dynamic'), lazy='dynamic') def __getitem__(self, item): return getattr(self, item, None) @property def avatar_file(self): return profile_image.path(self.avatar) @property def avatar_url(self): if not os.path.exists(profile_image.path(self.avatar)): return urljoin(request.url_root, profile_image.url(self.username + '/default.png')) return urljoin(request.url_root, profile_image.url(self.username + '/' + self.avatar)) @hybrid_property def avatar(self): return self._avatar @avatar.setter def avatar(self, avatar): if self._avatar != 'default.png': os.remove(self.avatar_file) self._avatar = avatar @hybrid_property def password(self): return self._password @password.setter def password(self, plaintext_password): self._password = generate_password_hash(plaintext_password) def check_password(self, password): return check_password_hash(self.password, password)
class DbWorkflow(Base): __tablename__ = "db_dbworkflow" aiida_query = _QueryProperty(_AiidaQuery) id = Column(Integer, primary_key=True) uuid = Column(UUID(as_uuid=True), default=uuid_func) ctime = Column(DateTime(timezone=True), default=timezone.now) mtime = Column(DateTime(timezone=True), default=timezone.now) user_id = Column(Integer, ForeignKey('db_dbuser.id')) user = relationship('DbUser') label = Column(String(255), index=True) description = Column(Text) nodeversion = Column(Integer) lastsyncedversion = Column(Integer) state = Column(ChoiceType((_, _) for _ in wf_states), default=wf_states.INITIALIZED) report = Column(Text) # XXX the next three attributes have "blank=False", but can be null. It may # be needed to add some validation for this, but only at commit time. # To do so: see https://stackoverflow.com/questions/28228766/running-cleaning-validation-code-before-committing-in-sqlalchemy module = Column(Text) module_class = Column(Text) script_path = Column(Text) # XXX restrict the size of this column, MD5 have a fixed size script_md5 = Column(String(255)) # Blank = False. def __init__(self, *args, **kwargs): super(DbWorkflow, self).__init__(*args, **kwargs) self.nodeversion = 1 self.lastsyncedversion = 0 def get_aiida_class(self): """ Return the corresponding aiida instance of class aiida.worflow """ return Workflow.get_subclass_from_uuid(self.uuid) def set_state(self, state): self.state = state self.save() def set_script_md5(self, md5): self.script_md5 = md5 self.save() def add_data(self, dict, d_type): for k in dict.keys(): p, create = self.data.get_or_create(name=k, data_type=d_type) p.set_value(dict[k]) def get_data(self, d_type): dict = {} for p in self.data.filter(parent=self, data_type=d_type): dict[p.name] = p.get_value() return dict def add_parameters(self, _dict, force=False): if not self.state == wf_states.INITIALIZED and not force: raise ValueError( "Cannot add initial parameters to an already initialized workflow" ) self.add_data(_dict, wf_data_types.PARAMETER) def add_parameter(self, name, value): self.add_parameters({name: value}) def get_parameters(self): return self.get_data(wf_data_types.PARAMETER) def get_parameter(self, name): res = self.get_parameters() if name in res: return res[name] else: raise ValueError("Error retrieving results: {0}".format(name)) def add_results(self, _dict): self.add_data(_dict, wf_data_types.RESULT) def add_result(self, name, value): self.add_results({name: value}) def get_results(self): return self.get_data(wf_data_types.RESULT) def get_result(self, name): res = self.get_results() if name in res: return res[name] else: raise ValueError("Error retrieving results: {0}".format(name)) def add_attributes(self, _dict): self.add_data(_dict, wf_data_types.ATTRIBUTE) def add_attribute(self, name, value): self.add_attributes({name: value}) def get_attributes(self): return self.get_data(wf_data_types.ATTRIBUTE) def get_attribute(self, name): res = self.get_attributes() if name in res: return res[name] else: raise ValueError("Error retrieving results: {0}".format(name)) def clear_report(self): self.report = None self.save() def append_to_report(self, _text): self.report += str(timezone.now()) + "] " + _text + "\n" self.save() def get_calculations(self): from aiida.orm import JobCalculation return JobCalculation.query(workflow_step=self.steps) def get_sub_workflows(self): return DbWorkflow.objects.filter(parent_workflow_step=self.steps.all()) def is_subworkflow(self): """ Return True if this is a subworkflow, False if it is a root workflow, launched by the user. """ return len(self.parent_workflow_step.all()) > 0 def finish(self): self.state = wf_states.FINISHED def __str__(self): simplename = self.module_class # node pk + type if self.label: return "{} workflow [{}]: {}".format(simplename, self.pk, self.label) else: return "{} workflow [{}]".format(simplename, self.pk)
class DbWorkflowStep(Base): __tablename__ = "db_dbworkflowstep" id = Column(Integer, primary_key=True) parent_id = Column(Integer, ForeignKey('db_dbworkflow.id')) parent = relationship("DbWorkflow", backref=backref('steps', lazy='dynamic')) name = Column(String(255)) # Blank = false time = Column(DateTime(timezone=True), default=timezone.now) nextcall = Column(String(255), default=wf_default_call) # Blank = false state = Column(ChoiceType((_, _) for _ in wf_states), default=wf_states.CREATED) calculations = relationship("DbNode", secondary=table_workflowstep_calc, backref="workflow_step") sub_workflows = relationship("DbWorkflow", secondary=table_workflowstep_subworkflow, backref=backref("parent_workflow_step", lazy="dynamic")) __table_args__ = (UniqueConstraint('parent_id', 'name'), ) def add_calculation(self, step_calculation): from aiida.orm import JobCalculation if (not isinstance(step_calculation, JobCalculation)): raise ValueError( "Cannot add a non-Calculation object to a workflow step") try: self.calculations.add(step_calculation) except: raise ValueError("Error adding calculation to step") def get_calculations(self, state=None): from aiida.orm import JobCalculation if (state == None): return JobCalculation.query(workflow_step=self) else: return JobCalculation.query(workflow_step=self).filter( dbattributes__key="state", dbattributes__tval=state) def remove_calculations(self): self.calculations.all().delete() def add_sub_workflow(self, sub_wf): from aiida.orm import Workflow if (not issubclass(sub_wf.__class__, Workflow) and not isinstance(sub_wf, Workflow)): raise ValueError("Cannot add a workflow not of type Workflow") try: self.sub_workflows.add(sub_wf.dbworkflowinstance) except: raise ValueError("Error adding calculation to step") def get_sub_workflows(self): return self.sub_workflows(manager='aiidaobjects').all() def remove_sub_workflows(self): self.sub_workflows.all().delete() def is_finished(self): return self.state == wf_states.FINISHED def set_nextcall(self, _nextcall): self.nextcall = _nextcall self.save() def set_state(self, _state): self.state = _state self.save() def reinitialize(self): self.set_state(wf_states.INITIALIZED) def finish(self): self.set_state(wf_states.FINISHED) def __str__(self): return "Step {} for workflow {} [{}]".format(self.name, self.parent.module_class, self.parent.pk)
class Position(db.Model, BaseDBModel): __tablename__ = 'positions' account_id = db.Column(db.Integer, db.ForeignKey('accounts.id'), nullable=False) symbol = db.Column(db.String) qty = db.Column(db.Integer) side = db.Column(ChoiceType(SIDES)) entry_price = db.Column(db.Float) closed = db.Column(db.Boolean, default=False) _current_price = db.Column(db.Float) _current_price_last_check = db.Column(db.DateTime) _lastday_price = db.Column(db.Float) _lastday_price_last_check = db.Column(db.DateTime) account = relationship('Account', foreign_keys='Position.account_id', backref='positions') def close(self): """ Creates a closing order """ # Local from ..order import Order side = LONG if self.side == SHORT else SHORT order = Order( account=self.account, symbol=self.symbol, qty=self.qty, order_type=Order.MARKET, side=side, ) order.save_to_db() def cost_basis(self): """ Total cost basis in dollar """ return self.qty * self.entry_price def market_value(self): """ Total dollar amount of the position """ return self.qty * self.current_price() def unrealized_pl(self): """ Unrealized profit/loss in dollars """ return self.market_value() - self.cost_basis() def unrealized_plpc(self): """ Unrealized profit/loss percent """ return self.unrealized_pl() / self.cost_basis() def change_today(self): """ Percent change from last day price """ return self.current_price() - self.lastday_price() def unrealized_intraday_pl(self): """ Unrealized profit/loss in dollars for the day """ return self.change_today() * self.qty def unrealized_intraday_plpc(self): """ Unrealized profit/loss percent for the day """ cost_basis = self.cost_basis() return (self.unrealized_intraday_pl() - cost_basis) / cost_basis def current_price(self): """ Current asset price per share """ DELAY_IN_SECONDS = 10 now = datetime.now() if (not self._current_price_last_check or (now - self._current_price_last_check).total_seconds() > DELAY_IN_SECONDS): self._current_price_last_check = now self._current_price = alpaca( 'get', f'last/stocks/{self.symbol}').json()['last']['price'] return self._current_price def lastday_price(self): """ Last day’s asset price per share based on the closing value of the last trading day """ now = datetime.now() if (not self._lastday_price_last_check or now.date() != self._lastday_price_last_check.date()): self._lastday_price_last_check = now data = bars((self.symbol, ), 'day', limit=1)[self.symbol][0] self._lastday_price = self.current_price() - data['c'] return self._lastday_price def get_public_fields(): return BaseDBModel.get_public_fields() + ( 'symbol', 'qty', 'side', )
class Note(db.Model): __tablename__ = "note" NOTE_TYPES = [ (1, "database"), (2, "web"), (3, "docker"), (4, "security"), (6, "hadoop"), (5, "notice"), (7, "opsai"), (8, "opsbase"), (9, "opsskill"), (10, "opsframework"), ] id = db.Column("id", db.Integer, primary_key=True, autoincrement=True) view_count = db.Column(db.Integer, default=0) is_public = db.Column(db.Boolean, default=False) title = db.Column(db.String(256)) content = db.Column(db.Text) raw_content = db.Column(db.Text) note_type = db.Column(ChoiceType(NOTE_TYPES, impl=db.Integer())) userId = db.Column(db.Integer, db.ForeignKey("user.id")) create_time = db.Column(db.DateTime) update_time = db.Column(db.DateTime) edit_type = db.Column(db.String(50), default="richtext") user = db.relationship("User", backref=db.backref("note_set", lazy="dynamic")) def __init__( self, title, content, raw_content, note_type, user, edit_type="richtext", view_count=0, is_public=False, ): super().__init__() self.note_type = note_type self.title = title self.user = user self.edit_type = edit_type self.content = content self.view_count = view_count self.is_public = is_public self.raw_content = raw_content self.create_time = datetime.now() self.update_time = datetime.now() def save(self): db.session.add(self) db.session.commit() def update(self): db.session.commit() def remove(self): db.session.delete(self) db.session.commit()
class Question(db.Model): __versioned__ = {} MULTIPLE = '1' BOOLEAN = '2' TYPES = [(MULTIPLE, 'Flervalg'), (BOOLEAN, 'Ja/Nei')] __tablename__ = 'question' __mapper_args__ = {'order_by': 'id'} id = db.Column(db.Integer, primary_key=True) text = db.Column(db.String, info={'label': 'Oppgavetekst'}) image = db.Column(db.String, info={'label': 'Bilde'}) exam_id = db.Column(db.Integer, db.ForeignKey('exam.id')) course = association_proxy('exam', 'course') reason = db.Column(db.String, info={'label': 'Forklaring'}) type = db.Column(ChoiceType(TYPES), info={'label': 'Spørsmålstype'}) # Boolean question correct = db.Column(db.Boolean, info={'label': 'Korrekt'}) # Alternative question alternatives = db.relationship('Alternative', backref='question', order_by='Alternative.id') def __init__(self, type=None, text=None, exam_id=None, image="", correct=None): self.type = type self.text = text self.exam_id = exam_id self.image = image self.correct = correct def __repr__(self): return self.text @property def multiple(self): return self.type == self.MULTIPLE @property def choices(self): if self.multiple: return self.alternatives @property def index(self): return Question.find_index(self) @classmethod def find_index(cls, question): indexes = [ q.id for q in cls.query.filter_by(exam_id=question.exam_id).all() ] return indexes.index(question.id) + 1 def serialize(self): response = { 'id': self.id, 'text': self.text, 'exam_id': self.exam_id, 'multiple': self.multiple, 'type': self.type.code } if self.multiple: response['alternatives'] = [] for alt in self.alternatives: alt_dict = alt.serialize() del alt_dict['question_id'] response['alternatives'].append(alt_dict) else: response['correct'] = self.correct if self.image: if self.image.startswith('http://'): response['image'] = self.image else: # this is not efficient response['image'] = url_for( 'static', filename='img/' + self.course.code + '/' + self.image) return response
class Activity(db.Model, TimestampMixin): """define Activety""" __tablename__ = 'workflow_activity' id = db.Column(db.Integer(), nullable=False, primary_key=True, autoincrement=True) """Activity identifier.""" activity_id = db.Column( db.String(24), nullable=False, unique=True, index=True) """activity id of Activity.""" activity_name = db.Column( db.String(255), nullable=True, unique=False, index=False) """activity name of Activity.""" item_id = db.Column( UUIDType, nullable=True, unique=False, index=True) """item id.""" workflow_id = db.Column( db.Integer(), db.ForeignKey(WorkFlow.id), nullable=False, unique=False) """workflow id.""" workflow = db.relationship( WorkFlow, backref=db.backref('activity', lazy='dynamic') ) workflow_status = db.Column( db.Integer(), nullable=True, unique=False) """workflow status.""" flow_id = db.Column( db.Integer(), db.ForeignKey(FlowDefine.id), nullable=True, unique=False) """flow id.""" flow_define = db.relationship( FlowDefine, backref=db.backref('activity', lazy='dynamic') ) action_id = db.Column( db.Integer(), db.ForeignKey(Action.id), nullable=True, unique=False) """action id.""" action = db.relationship( Action, backref=db.backref('activity', lazy='dynamic') ) # action_version = db.Column( # db.String(24), nullable=True, unique=False) # """action version.""" action_status = db.Column( db.String(1), db.ForeignKey(ActionStatus.action_status_id), nullable=True, unique=False) """action status.""" activity_login_user = db.Column( db.Integer(), db.ForeignKey(User.id), nullable=True, unique=False) """the user of create activity.""" activity_update_user = db.Column( db.Integer(), db.ForeignKey(User.id), nullable=True, unique=False) """the user of update activity.""" ACTIVITYSTATUSPOLICY = [ (ActivityStatusPolicy.ACTIVITY_BEGIN, ActivityStatusPolicy.describe(ActivityStatusPolicy.ACTIVITY_BEGIN)), (ActivityStatusPolicy.ACTIVITY_FINALLY, ActivityStatusPolicy.describe(ActivityStatusPolicy.ACTIVITY_FINALLY)), (ActivityStatusPolicy.ACTIVITY_FORCE_END, ActivityStatusPolicy.describe(ActivityStatusPolicy.ACTIVITY_FORCE_END)), (ActivityStatusPolicy.ACTIVITY_CANCEL, ActivityStatusPolicy.describe(ActivityStatusPolicy.ACTIVITY_CANCEL)), (ActivityStatusPolicy.ACTIVITY_MAKING, ActivityStatusPolicy.describe(ActivityStatusPolicy.ACTIVITY_MAKING)), (ActivityStatusPolicy.ACTIVITY_ERROR, ActivityStatusPolicy.describe(ActivityStatusPolicy.ACTIVITY_ERROR)), ] """Subscription policy choices.""" activity_status = db.Column( ChoiceType(ACTIVITYSTATUSPOLICY, impl=db.String(1)), default=ActivityStatusPolicy.ACTIVITY_BEGIN, nullable=True, unique=False, index=False) """activity status.""" activity_start = db.Column(db.DateTime, nullable=False) """activity start date.""" activity_end = db.Column(db.DateTime, nullable=True) """activity end date.""" activity_community_id = db.Column(db.Text, nullable=True) """activity community id"""
class Order(db.Model, BaseDBModel): __tablename__ = 'orders' MARKET = 'market' STOP = 'stop' TYPES = ( (MARKET, 'Market'), (STOP, 'Stop'), ) NEW = 'new' FILLED = 'filled' CANCELLED = 'cancelled' REJECTED = 'rejected' STATUSES = ( (NEW, 'New'), (FILLED, 'Filled'), (CANCELLED, 'Cancelled'), (REJECTED, 'Rejected'), ) account_id = db.Column( db.Integer, db.ForeignKey('accounts.id'), nullable=False ) symbol = db.Column(db.String) qty = db.Column(db.Integer) needed_funds = db.Column(db.Float) filled_price = db.Column(db.Float) stop_price = db.Column(db.Float) side = db.Column(ChoiceType(SIDES)) order_type = db.Column(ChoiceType(TYPES)) status = db.Column(ChoiceType(STATUSES)) filled_at = db.Column(db.DateTime) cancelled_at = db.Column(db.DateTime) rejected_cause = db.Column(db.String) account = relationship( 'Account', foreign_keys='Order.account_id', backref='orders' ) def get_public_fields(): return BaseDBModel.get_public_fields() + ( 'symbol', 'qty', 'stop_price', 'side', 'order_type', 'status', 'filled_at', 'cancelled_at', ) def fill(self): if self.status == Order.CANCELLED: return False if self.order_type == Order.MARKET: if self.side == SHORT: if self.symbol not in ( p.symbol for p in self.account.positions ): self.status = Order.REJECTED self.rejected_cause = NOT_HOLDING_POSITION self.save_to_db() return False current_price = self.get_current_price() position = self.get_related_position() if position.qty < self.qty: self.status = Order.REJECTED self.rejected_cause = NOT_HOLDING_POSITION self.save_to_db() return False position.closed = True position.save_to_db() self.account.cash += current_price * self.qty self.status = Order.FILLED self.filled_at = datetime.now() self.filled_price = current_price self.save_to_db() if position.qty > self.qty: new_position = Position( account=self.account, symbol=self.symbol, qty=position.qty - self.qty, side=LONG, entry_price=position.entry_price, ) new_position.save_to_db() return True if self.side == LONG: current_price = self.get_current_price() account_equity = self.account.cash + self.needed_funds total_price = current_price * self.qty if account_equity < total_price: self.status = Order.REJECTED self.rejected_cause = INSUFFICIENT_FUNDS self.save_to_db() return False self.account.cash += self.needed_funds self.account.cash -= total_price self.account.save_to_db() position = Position( account=self.account, symbol=self.symbol, qty=self.qty, side=self.side, entry_price=current_price, ) position.save_to_db() self.filled_price = current_price self.filled_at = datetime.now() self.status = Order.FILLED self.save_to_db() return True raise UnsupportedOrderType def cancel(self): if self.status != Order.NEW: return False self.status = Order.CANCELLED self.account.cash += self.needed_funds self.save_to_db() self.account.save_to_db() return True def get_related_position(self): return Position.query.filter_by( account=self.account, symbol=self.symbol, side=LONG, closed=False ).first() def get_current_price(self): return bars([self.symbol], 'minute', 1)[self.symbol][0]['c'] def save_to_db(self): if self.id is None and self.side == LONG: current_price = self.get_current_price() self.needed_funds = current_price * self.qty self.account.cash -= self.needed_funds self.account.save_to_db() super().save_to_db() def __str__(self): return f'<Order [{self.symbol}] {self.side} | {self.status}>'
class DbWorkflowStep(Base): __tablename__ = "db_dbworkflowstep" id = Column(Integer, primary_key=True) parent_id = Column(Integer, ForeignKey('db_dbworkflow.id')) parent = relationship("DbWorkflow", backref='steps') user_id = Column(Integer, ForeignKey('db_dbuser.id')) user = relationship('DbUser') name = Column(String(255)) # Blank = false time = Column(DateTime(timezone=True), default=timezone.now) nextcall = Column(String(255), default=wf_default_call) # Blank = false state = Column(ChoiceType((_, _) for _ in wf_states), default=wf_states.CREATED) calculations = relationship("DbNode", secondary=table_workflowstep_calc, backref="workflow_step") sub_workflows = relationship("DbWorkflow", secondary=table_workflowstep_subworkflow, backref="parent_workflow_step") __table_args__ = ( UniqueConstraint('parent_id', 'name'), ) def add_calculation(self, step_calculation): from aiida.orm import JobCalculation if (not isinstance(step_calculation, JobCalculation)): raise ValueError("Cannot add a non-Calculation object to a workflow step") try: self.calculations.append(step_calculation._dbnode) except: raise ValueError("Error adding calculation to step") def get_calculations(self, state=None): dbnodes = self.calculations calcs = [_.get_aiida_class() for _ in dbnodes] if (state == None): return calcs else: return [_ for _ in calcs if _.get_state() == state] def remove_calculations(self): self.calculations.all().delete() def add_sub_workflow(self, sub_wf): from aiida.orm import Workflow if not issubclass(sub_wf.__class__, Workflow) and \ not isinstance(sub_wf, Workflow): raise ValueError("Cannot add a workflow not of type Workflow") try: self.sub_workflows.append(sub_wf.dbworkflowinstance) except: raise ValueError("Error adding calculation to step") def get_sub_workflows(self): return [_.get_aiida_class() for _ in self.sub_workflows] def remove_sub_workflows(self): self.sub_workflows.all().delete() def is_finished(self): return self.state == wf_states.FINISHED def set_nextcall(self, _nextcall): self.nextcall = _nextcall self.save() def set_state(self, _state): self.state = _state self.save() def reinitialize(self): self.set_state(wf_states.INITIALIZED) def finish(self): self.set_state(wf_states.FINISHED) def __str__(self): return "Step {} for workflow {} [{}]".format( self.name, self.parent.module_class, self.parent.id)
class IssueModel(BaseModel): # noqa repository_id = Column(UUIDType(binary=False), primary_key=True) name = Column(String) text = Column(String) status = Column(ChoiceType(ISSUE_STATUS))
class Actor(db.Model): __tablename__ = "actor" ap_type = "Actor" id = db.Column(db.Integer, primary_key=True) url = db.Column(URLType(), unique=True, index=True) outbox_url = db.Column(URLType()) inbox_url = db.Column(URLType()) following_url = db.Column(URLType(), nullable=True) followers_url = db.Column(URLType(), nullable=True) shared_inbox_url = db.Column(URLType(), nullable=True) type = db.Column(ChoiceType(ACTOR_TYPE_CHOICES), server_default="Person") name = db.Column(db.String(200), nullable=True) domain = db.Column(db.String(1000), nullable=False) summary = db.Column(db.String(500), nullable=True) preferred_username = db.Column(db.String(200), nullable=True) public_key = db.Column(db.String(5000), nullable=True) private_key = db.Column(db.String(5000), nullable=True) creation_date = db.Column(db.DateTime(timezone=False), default=datetime.datetime.utcnow) last_fetch_date = db.Column(db.DateTime(timezone=False), default=datetime.datetime.utcnow) manually_approves_followers = db.Column(db.Boolean, nullable=True, server_default=None) # Who follows self followers = db.relationship("Follower", backref="followers", primaryjoin=id == Follower.target_id, lazy="dynamic") # Who self follows followings = db.relationship("Follower", backref="followings", primaryjoin=id == Follower.actor_id, lazy="dynamic") # Relation on itself, intermediary with actor and target # By using an Association Object, which isn't possible except by using # two relations. This may be better than only one, and some hackish things # by querying directly the old db.Table definition meta_deleted = db.Column(db.Boolean, default=False) user_id = db.Column(db.Integer, db.ForeignKey("user.id"), nullable=True) user = db.relationship("User", backref=db.backref("actor")) __table_args__ = (UniqueConstraint("domain", "preferred_username", name="_domain_pref_username_uc"), ) def __repr__(self): return f"<Actor(id='{self.id}', user_id='{self.user_id}', preferredUsername='******', domain='{self.domain}')>" def webfinger_subject(self): return f"{self.preferred_username}@{self.domain}" def private_key_id(self): return f"{self.url}#main-key" def mention_username(self): return f"@{self.preferred_username}@{self.domain}" def is_local(self): return self.domain == current_app.config["AP_DOMAIN"] def follow(self, activity_url, target): current_app.logger.debug(f"saving: {self.id} following {target.id}") rel = Follower.query.filter(Follower.actor_id == self.id, Follower.target_id == target.id).first() if not rel: rel = Follower() rel.actor_id = self.id rel.target_id = target.id rel.activity_url = activity_url db.session.add(rel) db.session.commit() def unfollow(self, target): current_app.logger.debug(f"saving: {self.id} unfollowing {target.id}") rel = Follower.query.filter(Follower.actor_id == self.id, Follower.target_id == target.id).first() if rel: db.session.delete(rel) db.session.commit() def is_followed_by(self, target): print( f"is {self.preferred_username} followed by {target.preferred_username} ?" ) return self.followers.filter(Follower.actor_id == target.id).first() def is_following(self, target): print( f"is {self.preferred_username} following {target.preferred_username} ?" ) return self.followings.filter(Follower.target_id == target.id).first() def to_dict(self): if self.user.path_avatar(): url_avatar = url_for("get_uploads_stuff", thing="avatars", stuff=self.user.path_avatar(), _external=True) else: url_avatar = f"{current_app.config['REEL2BITS_URL']}/static/userpic_placeholder.svg" return { "@context": DEFAULT_CTX, "id": self.url, "type": self.type.code, "preferredUsername": self.preferred_username, "name": self.name, "inbox": self.inbox_url, "outbox": self.outbox_url, "followers": self.followers_url, "following": self.following_url, "manuallyApprovesFollowers": self.manually_approves_followers, "publicKey": { "id": self.private_key_id(), "owner": self.url, "publicKeyPem": self.public_key }, "endpoints": { "sharedInbox": self.shared_inbox_url }, "icon": { "type": "Image", "url": url_avatar }, }
class User(SurrogatePK, Base): __tablename__ = "s_user" id = Column(Integer, primary_key=True) username = Column(String(16)) email = db.Column(db.String(200)) email_stat = db.Column(db.Integer) password_hash = db.Column(db.String(500), nullable=False) assess_key = db.Column(db.String(500)) roles = Column(ChoiceType(ROLES), default=NORMAL) last_name = db.Column(db.String(100), nullable=True) phone = db.Column(db.String(20)) phone_stat = db.Column(db.Integer) use_folder = db.Column(db.String(500)) max_size = db.Column(db.Integer, default=1024 * 1024 * 1024) use_size = db.Column(db.Integer, default=0) def __init__(self, username, email, password, **kwargs): db.Model.__init__(self, username=username, email=email, password=password, **kwargs) self.set_password(password) self.set_assess_key(username, password) self.set_use_folder(username) @property def password(self): return None @password.setter def password(self, password): self.set_password(password) def set_password(self, password): self.password_hash = generate_password_hash(password) def check_password(self, value): return check_password_hash(self.password_hash, value) def set_assess_key(self, username, password): self.assess_key = hash_sha256('{};{};{}'.format( username, password, str(time.time()))) def set_use_folder(self, username): self.use_folder = hash_sha256('{};{}'.format(username, str(time.time()))) @property def full_name(self): return '%s %s' % (self.first_name, self.last_name) def generate_auth_token(self, expiration=600): s = Serializer(SECRET_KEY, expires_in=expiration) return s.dumps({'id': self.id}).decode() @staticmethod def verify_auth_token(token): s = Serializer(SECRET_KEY) try: data = s.loads(token) except SignatureExpired: return None # valid token, but expired except BadSignature: return None # invalid token user = User.query.get(data['id']) if user: return user return None