class Role(db.Model, RoleMixin): __tablename__ = "role" id = db.Column(db.Integer(), primary_key=1, autoincrement=1) name = db.Column(db.String(255), unique=1) description = db.Column(db.String(255)) def __init__(self, name="", description=""): self.name = name self.description = description def __repr__(self): return self.name def to_json(self): role = dict() role["id"] = self.id role["name"] = self.name role["description"] = self.description return role
class User(db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(80), unique=True, nullable=False) email = db.Column(db.String(120), unique=True, nullable=False) def __repr__(self): return '<User %r>' % self.username
class Feed(db.Model): __tablename__ = "feeds" id = db.Column(db.Integer(), primary_key=1) url = db.Column(db.String(255), unique=1) account_id = db.Column(db.Integer(), db.ForeignKey("accounts.id")) def __init__(self, url="", account=None): self.url = url self.account = account def __repr__(self): return self.account.text + u"的订阅地址" def to_json(self): feed = dict() feed["id"] = self.id feed["url"] = self.url feed["account"] = self.account return feed
class Board(db.Model, TimestampMixin): id = db.Column(db.Integer, primary_key=True, nullable=False) title = db.Column(db.String(200), nullable=False) description = db.Column(db.String(200), nullable=True) status = db.Column(ChoiceType(BoardStatus, impl=db.Integer()), default=BoardStatus.NORMAL) user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False) user = db.relationship("User") posts = db.relationship("Post", backref="board", lazy='dynamic') @hybrid_property def is_deleted(self): return self.status == BoardStatus.DELETED def delete(self): self.status = BoardStatus.DELETED def is_owner(self, user: User): return self.user_id == user.id def __repr__(self): return "<Board title: %s, description: %s, status: %s," \ " created_at: %s, updated_at: %s>"\ % (self.title, self.description, self.status, self.created_at, self.updated_at)
class MatchOrderTask(AutoIncrementBase): # 状态参见 g_match_order_task_status status = db.Column(db.SmallInteger, default=g_match_order_task_status.UNPROCESSED) order_cnt = db.Column(db.Integer, nullable=False) # 需要匹配的单数
class ProxySite(db.Model): __tablename__ = "proxy_site" id = db.Column(db.Integer(), primary_key=1) url = db.Column(db.String(255)) regex = db.Column(db.String(255)) def __init__(self, url="", regex=""): self.url = url self.regex = regex def __repr__(self): return self.url def to_json(self): proxy_site = dict() proxy_site["url"] = self.url proxy_site["regex"] = self.regex return proxy_site
class Audience(db.Model): id = db.Column(db.String(50), primary_key=True) name = db.Column(db.String(100)) def __init__(self, id, name): self.id = id self.name = name
class ProxyIP(db.Model): __tablename__ = "proxy_ip" id = db.Column(db.Integer(), primary_key=1) ip_port = db.Column(db.String(20), unique=1, nullable=0) quality = db.Column(db.String(20)) def __init__(self, ip_port="", quality=""): self.ip_port = ip_port self.quality = quality def __repr__(self): return self.ip_port def to_json(self): proxy_ip = dict() proxy_ip["ip_port"] = self.ip_port proxy_ip["quality"] = self.quality return proxy_ip
class TimestampMixin(object): created_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow()) updated_at = db.Column(db.DateTime, nullable=False, default=datetime.utcnow(), onupdate=datetime.utcnow())
class User(db.Model): id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(80), unique=True) email = db.Column(db.String(120), unique=True) def __init__(self, username, email): self.username = username self.email = email
class Keywords(Base): # which kind of endorsement __tablename__ = "keywords" CommentID = db.Column(db.Integer, db.ForeignKey("comment.id", use_alter=True), nullable=False) Phase = db.Column(db.TEXT)
class FeedRecord(db.Model): __tablename__ = 'feeds' id = db.Column(db.Integer, primary_key=True) time = db.Column(db.DateTime, default=datetime.now()) quant = db.Column(db.Integer) def __repr__(self): return 'At %s eat %d ml' % (str(self.time), self.quant)
class Likes(db.Model, TimestampMixin): def __init__(self, post_id, user_id): self.post_id = post_id self.user_id = user_id id = db.Column(db.Integer, primary_key=True) post_id = db.Column(db.Integer, db.ForeignKey('post.id'), nullable=False) user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
class LoginInfo(UuidBase): user_id = db.Column(db.String(36), db.ForeignKey('user.id'), nullable=False) client_ip = db.Column(db.String(50), nullable=False) # 登录IP # relationship user = db.relationship(User)
class PinCodeBase(db.Model): __abstract__ = True created_at = db.Column(db.DateTime, default=datetime.datetime.utcnow, nullable=False) updated_at = db.Column(db.DateTime, default=datetime.datetime.utcnow, onupdate=datetime.datetime.utcnow, nullable=False) pin_code_signature = db.Column(db.String(256), nullable=False) try_times = db.Column(db.SmallInteger, default=0) def generate_signature(self, pin_code, expiration=30 * 60): s = Serializer(current_app.config['SECRET_KEY'], expires_in=expiration) self.pin_code_signature = s.dumps({'id': pin_code}) self.try_times = 0 db.session.add(self) db.session.commit() # 返回值 # 0 成功 # 1 尝试次数太多 # 2 PIN码错误 # 3 PIN码过期 @classmethod def verify(cls, unique_id, pin_code): result = cls.query.get(unique_id) if result is None: return 2 result.try_times = cls.try_times + 1 db.session.commit() if result.try_times > 5: return 1 s = Serializer(current_app.config['SECRET_KEY']) try: data = s.loads(result.pin_code_signature) except SignatureExpired: return 3 # valid signature, but expired except BadSignature: return 2 # invalid signature if data['id'] == pin_code.lower(): db.session.delete(result) db.session.commit() return 0 return 2 @classmethod def flask_check(cls, unique_id, pin_code): result = cls.verify(unique_id, pin_code) if result == 1: abort(400, code=1005, message={'pin_code': 'try too many times'}) elif result == 2: abort(400, code=1002, message={'pin_code': 'pin code does not match'}) elif result == 3: abort(400, code=1006, message={'pin_code': 'pin code is expired'})
class Checkout(db.Model): id = db.Column(db.String(50), primary_key=True) date = db.Column(db.DateTime) audience_id = db.Column(db.String(50)) def __init__(self, audience_id): self.id = generate_id() self.date = get_date() self.audience_id = audience_id
class CommentGroup(db.Model): id = db.Column(db.Integer, primary_key=True) post_id = db.Column(db.ForeignKey('post.id'), nullable=False) created_at = db.Column(db.DateTime, default=datetime.utcnow(), nullable=False) comments = db.relationship('Comment', backref='comment_group', lazy='dynamic') def __repr__(self): return '<CommentGroup id: %d> ' % self.id def get_comment_in_group(self, comment_id): return self.comments.filter(Comment.id == comment_id).first() def add_comment(self, user, comment): try: comment.user_id = user.id self.post.increase_comment_count() self.comments.append(comment) db.session.commit() except Exception as e: db.session.rollback() raise e else: return comment def add_layer_comment(self, user: User, comment: Comment, parent_comment: Comment): try: self._update_comment_step(parent_comment) # add comment comment.user_id = user.id comment.step = parent_comment.step + 1 comment.depth = parent_comment.depth + 1 self.post.increase_comment_count() self.comments.append(comment) db.session.commit() except Exception as e: db.session.rollback() raise e else: return comment def _update_comment_step(self, parent_comment: Comment): # update step self.comments \ .filter(Comment.step > parent_comment.step) \ .update({Comment.step: Comment.step + 1})
class OauthModel(db.Model): id = db.Column(db.Integer(), primary_key=True) client_id = db.Column(db.String(255), unique=True) client_secret = db.Column(db.String(255)) redirect_uri = db.Column(db.String(255)) def __init__(self, client_id, client_secret, redirect_uri): self.client_id = client_id self.client_secret = client_secret self.redirect_uri = redirect_uri
class UserRoles(db.Model): __tablename__ = 'user_roles' id = db.Column(db.Integer(), primary_key=True) user_id = db.Column(db.Integer(), db.ForeignKey('user_model.id', ondelete='CASCADE')) role_id = db.Column(db.Integer(), db.ForeignKey('roles.id', ondelete='CASCADE')) def __repr__(self): return '<UserRoles %r>' % self.name
class Role(db.Model, CRUD): __tablename__ = 'role' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(250), nullable=True, unique=True) description = db.Column(db.String(250)) user = db.relationship('User', backref='role', lazy='dynamic') def __repr__(self): return '<Role %s>' % self.name
class Role(db.Model): __tablename__ = 'roles' id = db.Column(db.Integer(), primary_key=True) name = db.Column(db.String(50), unique=True) def save_to_db(self): db.session.add(self) db.session.commit() def __repr__(self): return '<Role %r>' % self.name
class Article(Base): __tablename__ = "article" ArticleUrl = db.Column(db.String(255), unique=True, primary_key=True) ArticleTitle = db.Column(db.String(255)) ArticleAuthor = db.Column(db.Integer, db.ForeignKey("user.id", use_alter=True), nullable=False) Content = db.Column(db.TEXT) Language = db.Column(db.String(10), db.ForeignKey("language.Lang", use_alter=True), nullable=False)
class Location(db.Model): id = db.Column(db.Integer(), primary_key=True) name = db.Column(db.String(80)) lat = db.Column(db.Float()) lng = db.Column(db.Float()) # for faster calculation of Distance Difference Index('dist', func.ll_to_earth(lat, lng), postgresql_using='gist') def __init__(self, name, lat, lng): self.name = name self.lat = lat self.lng = lng
class Wallet(UuidBase): user_id = db.Column(db.String(36), db.ForeignKey('user.id'), nullable=False) currency_id = db.Column(db.String(50), nullable=False) # 货币代码 address = db.Column(db.String(100), unique=True, nullable=False) # 区块链币地址 address_qr_code = db.Column(db.String(512)) # 地址二维码 URL __table_args__ = (db.UniqueConstraint('user_id', 'currency_id'), ) # relationship user = db.relationship(User) @staticmethod def generate_wallet(user_id, currency_list): api = cryptopay_api() url = '{}/member/create_wallet'.format( current_app.config['CRYPTOPAY_BASE_URL']) data = {'currency_list': currency_list} try: wallet_list = api.post(url, data) for w in wallet_list['objects']: address_qr_code = '%s/currency_address_qr_code/%s' % ( current_app.config['CRYPTOPAY_BASE_URL'], w['address']) wallet = Wallet(user_id=user_id, currency_id=w['currency_id'], address=w['address'], address_qr_code=address_qr_code) db.session.add(wallet) db.session.commit() except CryptoPayApiError as e: abort(e.http_status_code, code=e.code, message=e.message) @staticmethod def query_wallet(wallet_list): address_list = [] for wallet in wallet_list: address_list.append(wallet.address) api = cryptopay_api() url = '{}/member/query_wallet'.format( current_app.config['CRYPTOPAY_BASE_URL']) data = {'address_list': ','.join(address_list)} try: address_balance_dict = {} query_wallet_list = api.post(url, data) for query_wallet in query_wallet_list['objects']: address_balance_dict[ query_wallet['address']] = query_wallet['balance'] for wallet in wallet_list: wallet.balance = address_balance_dict.get(wallet.address, '0') except CryptoPayApiError as e: abort(e.http_status_code, code=e.code, message=e.message)
class Account(db.Model): __tablename__ = "accounts" id = db.Column(db.Integer(), primary_key=1) name = db.Column(db.String(255), unique=1, nullable=0) text = db.Column(db.String(255), unique=1, nullable=0) info = db.Column(db.String(255), unique=0, nullable=1) auth = db.Column(db.String(255), unique=0, nullable=1) feed = db.relationship("Feed", cascade="all,delete", backref="account", uselist=0) articles = db.relationship("Article", cascade="all,delete", backref="account", lazy="dynamic") def __init__(self, name="", text="", info="", auth=""): self.name = name self.text = text self.info = info self.auth = auth def __repr__(self): return self.text def to_json(self): account = dict() account["id"] = self.id account["name"] = self.name account["text"] = self.text account["info"] = self.info account["auth"] = self.auth return account
class AuthorModel(db.Model): __tablename__ = 'author_model' id = db.Column(db.Integer, primary_key=True, autoincrement=True) forename = db.Column(db.String(255), nullable=False) surname = db.Column(db.String(255), nullable=False) def save_to_db(self): db.session.add(self) db.session.commit() def __repr__(self): return '<Author %r>' % self.surname
class ScheduleTaskBase(AutoIncrementBase): __abstract__ = True status = db.Column(db.SmallInteger, default=0) # 0 未处理 1 已处理 processed_at = db.Column(db.DateTime) def done(self, processed_at): self.status = 1 self.processed_at = processed_at @classmethod def peek(cls): return cls.query.filter_by(status=0).order_by(cls.id).first()
class RecommendScheduleTask(ScheduleTaskBase): user_id = db.Column(db.String(36), db.ForeignKey('user.id'), nullable=False, unique=True) user = db.relationship(User)
class ConfirmOrder(AutoIncrementBase): sell_user_id = db.Column(db.String(36), db.ForeignKey('user.id'), nullable=False) # 卖方用户 buy_user_id = db.Column(db.String(36), db.ForeignKey('user.id'), nullable=False) # 买方用户 amount = db.Column(db.Numeric(24, 8), nullable=False) # 数量 status = db.Column(db.SmallInteger, default=g_confirm_order_status.UNPROCESSED ) # 状态参见 g_confirm_order_status sell_user = db.relationship(User, foreign_keys=[sell_user_id]) buy_user = db.relationship(User, foreign_keys=[buy_user_id])
class CryptoCurrency(AutoIncrementBase): currency_code = db.Column(db.String(20), nullable=False) # 货币编码 erc20_token = db.Column(db.SmallInteger, nullable=False) # 代币: 0 不是 1 是 usd_price = db.Column(db.Numeric(24, 8), nullable=False) # 美元价格 sequence = db.Column(db.SmallInteger, nullable=False) # 排序 init_block_number = db.Column(db.Integer, default=0, nullable=False) # 初始索引块数 indexed_block_number = db.Column(db.Integer, default=0, nullable=False) # 已索引块数 start_price = db.Column(db.Numeric(24, 8), nullable=False) # 0 点时价格 用于计算涨幅 percent_change_1h = db.Column(db.Numeric(24, 8), default=0, nullable=False) percent_change_24h = db.Column(db.Numeric(24, 8), default=0, nullable=False) percent_change_7d = db.Column(db.Numeric(24, 8), default=0, nullable=False) __table_args__ = (db.UniqueConstraint('currency_code', 'erc20_token'), ) @property def percent_change(self): if self.start_price: return (self.usd_price - self.start_price) / self.start_price * 100 else: return 0 @staticmethod def initialize(): crypto_currency_list = [ 'BTC', 'USDT', 'ETH', 'LTC', 'EOS', 'ETC', 'DASH', 'BSV', 'XRP', 'DOGE' ] for crypto_currency in crypto_currency_list: currency = CryptoCurrency.query.filter_by( currency_code=crypto_currency, erc20_token=0).first() if currency is None: currency = CryptoCurrency(currency_code=crypto_currency, erc20_token=0, usd_price=0, start_price=0, sequence=0) db.session.add(currency) db.session.commit()