class Challenge(db.Model, CRUDMixin): """ Challenge model""" __tablename__ = "challenge" identifier = db.Column(db.String(255), primary_key=True) name = db.Column(db.String(255), nullable=False) description = db.Column(db.Text, nullable=False) help = db.Column(db.Text, nullable=True) external_link = db.Column(db.String(255), nullable=True) # Relations users = relationship("SolvedChallenges", back_populates="solved_challenge") def __repr__(self): return self.name or "" def to_dict(self): return dict(identifier=self.identifier, name=self.name, description=self.description, help=self.help, external_link=self.external_link) @classmethod def json_list(cls): return dict( list(map(lambda x: (x.identifier, x.to_dict()), cls.query.all())))
class Stock(db.Model, TimestampMixin): __tablename__ = "stocks" id = db.Column(db.Integer(), db.Sequence("stocks_id_seq"), primary_key=True) ticker = db.Column(db.String(15)) short_name = db.Column(db.String(255)) latest_market_data = db.Column(JSONB) company_info = db.Column(JSONB) __table_args__ = (UniqueConstraint("ticker", name="uq_stocks_ticker"), ) def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) @property def json(self): return { "id": self.id, "ticker": self.ticker, "short_name": self.short_name, "company_info": self.company_info, "latest_market_data": self.latest_market_data, } @property def json_short(self): return { "id": self.id, "ticker": self.ticker, "short_name": self.short_name, "latest_market_data": self.latest_market_data, }
class Post(ResourceMixin, db.Model): __tablename__ = 'posts' # Relationships comments = db.relationship('Comment', backref=db.backref('post', uselist=False), passive_deletes=True, lazy='dynamic') # Properties id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(100), index=True, unique=True, nullable=False) body = db.Column(db.ARRAY(db.String), nullable=False) summary = db.Column(db.String(250), nullable=False) img_src = db.Column(db.String(200)) thumbnail_src = db.Column(db.String(200)) view_count = db.Column(db.Integer, server_default='0') # Foreign Keys author_id = db.Column(db.Integer, db.ForeignKey('staff.id')) practice_area_id = db.Column(db.Integer, db.ForeignKey('practice_areas.id')) def __init__(self, **kwargs): # Call Flask-SQLAlchemy's constructor. super(Post, self).__init__(**kwargs) @hybrid_property def slug(self): return slugify(self.title) @classmethod def find_by_title(cls, title): """ Find client by user ID. :param user_id: user ID :type title: str :return: Client instance """ return cls.query.filter(cls.title == title).first() def to_json(self): return { 'id': self.id, 'title': self.title, 'author': self.author.user.first_last_name, 'body': self.body, 'summary': self.summary, 'practiceArea': self.practice_area.area, 'imgSrc': self.img_src, 'thumbnailSrc': self.thumbnail_src, 'created': self.created_on, 'updated': self.updated_on, 'views': self.view_count, 'authorPhoto': self.author.user.photo, 'slug': self.slug }
class Education(Base): """ education of a tourister """ tourister_id = db.Column(db.Integer, db.ForeignKey('touristers.id'), nullable=False) school = db.Column(db.String(30)) degree = db.Column(db.String(30))
class SocialNetwork(Base): """ different social networks of a tourister """ tourister_id = db.Column(db.Integer, db.ForeignKey('touristers.id'), nullable=False) type = db.Column(db.String(30)) src = db.Column(db.String(200))
class Language(Base): """ languages a tourister can speak/understand """ __tablename__ = 'languages' tourister_id = db.Column(db.Integer, db.ForeignKey('touristers.id'), nullable=False) name = db.Column(db.String(10), nullable=False) proficiency = db.Column(db.String(10), nullable=False)
class UserIdentifier(db.Model, CRUDMixin): __tablename__ = "user_identifier" id = db.Column(db.Integer, primary_key=True, autoincrement=True) ip_addr = db.Column(db.String(255), unique=False) user_agent = db.Column(db.String(2048), unique=False) # Relation users = relationship("User", secondary=user_identifier_association, back_populates="user_identifiers")
class Occupation(Base): """ Occupations touristers can exercise (to find matches) """ __tablename__ = 'occupations' tourister_id = db.Column(db.Integer, db.ForeignKey('touristers.id'), nullable=False) name = db.Column(db.String(30), nullable=False) affiliation = db.Column(db.String(30))
class User(db.Model, TimestampMixin): __tablename__ = "users" id = db.Column(UUID(as_uuid=True), primary_key=True, nullable=False, default=uuid4) email = db.Column(db.String(255), nullable=False) first_name = db.Column(db.String(255), nullable=False) last_name = db.Column(db.String(255), nullable=False) password = db.Column(PasswordType(schemes=["bcrypt"])) is_active = db.Column(db.Boolean(), nullable=False, server_default="1") confirmed = db.Column(db.Boolean(), nullable=False, server_default="0") email_confirmed_at = db.Column(db.DateTime()) last_logged_in = db.Column(db.DateTime()) roles = db.relationship("Role", secondary="user_roles") __table_args__ = (UniqueConstraint("email", name="uq_users_email"), ) def __init__(self, *args, **kwargs): super(User, self).__init__(*args, **kwargs) if not self.password: self.password = binascii.hexlify(os.urandom(24)).decode() @classmethod def auth(cls, **kwargs): email = kwargs.get("email") password = kwargs.get("password") if not email or not password: return None user = cls.query.filter_by(email=email).first() if not user or user.password != password: return None return user @property def json(self): return { "id": self.id, "first_name": self.first_name, "last_name": self.last_name, "email": self.email, # "portfolios": [portfolio.json for portfolio in self.portfolios], } def __repr__(self): return ( f"User(id={self.id}, email={self.email}, first_name={self.first_name}, " f"last_name={self.last_name}), confirmed={self.confirmed}")
class File(db.Model): id = db.Column(db.Integer, primary_key=True) description = db.Column(db.String(500)) filename = db.Column(db.String(64)) timestamp = db.Column(db.DateTime, default=datetime.utcnow, index=True) can_comment = db.Column(db.Boolean, default=True) flag = db.Column(db.Integer, default=0) author_id = db.Column(db.Integer, db.ForeignKey('user.id')) enc_flag = db.Column(db.Boolean, default=False) enc_policy = db.Column(db.String(200)) author = db.relationship('User', back_populates='files')
class SolvedChallenges(db.Model): __tablename__ = 'solved_challenges' user_id = db.Column(db.String(255), db.ForeignKey('user.uuid'), primary_key=True) challenge_id = db.Column(db.String(255), db.ForeignKey('challenge.identifier'), primary_key=True) time_solved = db.Column(db.DateTime, nullable=False, default=datetime.datetime.now) user = relationship("User", back_populates="solved_challenges") solved_challenge = relationship("Challenge", back_populates="users")
class User(Base): __tablename__ = "users" id = db.Column(db.Integer, primary_key=True, autoincrement=True) email = db.Column(db.String(255), unique=True, nullable=False) password = db.Column(db.String(255), nullable=False) admin = db.Column(db.Boolean, nullable=False, default=False) tourister = db.relationship('Tourister', backref='user', uselist=False) def __init__(self, email, password, admin=False): self.email = email self.password = bcrypt.generate_password_hash( password, app.config.get('BCRYPT_LOG_ROUNDS')).decode('utf-8') self.admin = admin
class CommandCache(db.Model, CRUDMixin): __tablename__ = "command_cache" hash = db.Column(db.String(255), primary_key=True) challenge_identifier = db.Column(db.String(64), primary_key=True) timestamp = db.Column(db.DateTime, nullable=False, default=datetime.datetime.now) cmd_correct = db.Column(db.Boolean, default=False, nullable=False) cmd_output = db.Column(db.Text) @classmethod def get_by_pks(cls, **kwargs): return cls.query.get( tuple(kwargs[key.name] for key in inspect(cls).primary_key))
class Task(db.Model): __tablename__ = 'tasks' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(250), unique=True, nullable=False) description = db.Column(db.String) creation_date = db.Column(db.TIMESTAMP, server_default=db.func.current_timestamp(), nullable=False) status = db.Column(db.Integer, nullable=False, default=0) # Relationships users = db.relationship('User', secondary=task_users, backref=db.backref('tasks')) @hybrid_property def nr_users(self): return len(self.annotations) def update_users(self, user_ids): new_users = db.session.query(User).filter(User.id.in_(user_ids)).all() self.users = new_users db.session.commit() def __init__(self, name, status=0): self.name = name self.status = status
class FinalFeedback(db.Model, CRUDMixin): id = db.Column(db.Integer, primary_key=True, autoincrement=True) motivation = db.Column(db.Enum(MotivationFeedback), nullable=False) user_uuid = db.Column(db.String(255), db.ForeignKey('user.uuid')) user = relationship("User", back_populates="feedback")
class Matter(ResourceMixin, db.Model): __tablename__ = 'matters' # Properties id = db.Column(db.Integer, primary_key=True) description = db.Column(db.String(1000)) file_open = db.Column(AwareDateTime(), default=tzaware_datetime) file_close = db.Column(AwareDateTime()) costs_on_account = db.Column(db.Numeric(10, 2), server_default='0') active = db.Column(db.Boolean(), nullable=False, server_default='1') def __init__(self, **kwargs): super(Matter, self).__init__(**kwargs) def to_json(self): """ Convert Matter instance to json """ clients = [client.id for client in self.clients] practice_areas = [practice_area.id for practice_area in self.practice_areas] staff = [staff_member.id for staff_member in self.staff] return { 'id': self.id, 'description': "[" + str(self.id) + "] " + (self.description if self.description else ''), 'fileOpen': self.file_open, 'fileClose': self.file_close, 'active': self.active, 'costsOnAccount': self.costs_on_account, 'clients': clients, 'practiceAreas': practice_areas, 'staff': staff }
class Role(db.Model): id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(30), unique=True) users = db.relationship('User', back_populates='role') permissions = db.relationship('Permission', secondary=roles_permissions, back_populates='roles') @staticmethod def init_role(): roles_permissions_map = { 'Locked': ['FOLLOW', 'COLLECT'], 'User': ['FOLLOW', 'COLLECT', 'COMMENT', 'UPLOAD'], 'Moderator': ['FOLLOW', 'COLLECT', 'COMMENT', 'UPLOAD', 'MODERATE'], 'Administrator': [ 'FOLLOW', 'COLLECT', 'COMMENT', 'UPLOAD', 'MODERATE', 'ADMINISTER' ] } for role_name in roles_permissions_map: role = Role.query.filter_by(name=role_name).first() if role is None: role = Role(name=role_name) db.session.add(role) role.permissions = [] for permission_name in roles_permissions_map[role_name]: permission = Permission.query.filter_by( name=permission_name).first() if permission is None: permission = Permission(name=permission_name) db.session.add(permission) role.permissions.append(permission) db.session.commit()
class User(ResourceMixin, db.Model): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String(24), unique=True, index=True) password = db.Column(db.String(128), nullable=False, server_default='') comments = db.relationship(Comment, backref='users', passive_deletes=True) def __init__(self, **kwargs): # Call Flask-SQLAlchemy's constructor. super(User, self).__init__(**kwargs) self.password = self.encrypt_password(kwargs.get('password', '')) def encrypt_password(cls, plaintext_password): """ Hash a plaintext string. :param plaintext_password: Password in plain text :type plaintext_password: str :return: str """ if plaintext_password: return pwd_context.encrypt(plaintext_password) return None def verify_password(self, password): return pwd_context.verify(password, self.password) def serialize(self): """ Return JSON fields to render the user. :return: dict """ params = { 'id': self.id, 'username': self.username, 'comments': [ _c.serialize(lite=True) for _c in Comment.query.filter(Comment.user_id == self.id) ] } return params
class Currency(db.Model): __tablename__ = 'currency' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(80), unique=True, nullable=False) short_name = db.Column(db.String(10), unique=True, nullable=False) def to_json(self): return { "id": self.id, "name": self.name, "short_name": self.short_name, } def __repr__(self): return '<id: {}>, <name: {}>, <short_name: {}>'.format( self.id, self.name, self.short_name)
class SubmittedCommand(db.Model, CRUDMixin): __tablename__ = "submitted_command" id = db.Column(db.Integer, primary_key=True, autoincrement=True) time_submitted = db.Column(db.DateTime, nullable=False, default=datetime.datetime.now) command_string = db.Column(db.Text) challenge_id = db.Column(db.String(255)) solved_challenge = db.Column(db.Boolean, default=False) # Relations user_uuid = db.Column(db.String(255), db.ForeignKey('user.uuid')) user = relationship("User", back_populates="commands") def __repr__(self): return f"<Submission for {self.challenge_id}>"
class PaypalInfo(Base): """ information needed to use user's paypal """ tourister_id = db.Column(db.Integer, db.ForeignKey('touristers.id'), nullable=False) email = db.Column(db.String(100), nullable=False)
class ServicePerks(Base): """ perks that can be added to a tourister service """ service_id = db.Column(db.Integer, db.ForeignKey('services.id'), nullable=False) value = db.Column(db.String(100))
class RideshareAdditionalInfo(Base): """ Additional info that can be added to a tourister service """ rideshare_detail_id = db.Column(db.Integer, db.ForeignKey('rideshare_detail.id'), nullable=False) value = db.Column(db.String(100))
class CurrencyPair(db.Model, BaseModel): __tablename__ = 'currency_pair' symbol = db.Column(db.String(15), unique=True, nullable=False) from_currency_id = db.Column(db.Integer, db.ForeignKey('currency.id'), nullable=False) from_currency = db.relationship("Currency", foreign_keys=[from_currency_id], lazy='subquery') to_currency_id = db.Column(db.Integer, db.ForeignKey('currency.id'), nullable=False) to_currency = db.relationship("Currency", foreign_keys=[to_currency_id], lazy='subquery') @classmethod def get_by_symbol(cls, symbol): currency_pair = cls.query.filter_by(symbol=symbol).first() if not currency_pair: raise NoCurrencyPairBySymbolException(symbol) return currency_pair def __repr__(self): return self.symbol def get_market_repr(self, market_name): if market_name == "Binance": return self.binance_repr elif market_name == "Bitmex": return self.bitmex_repr return self.symbol def get_market_order_repr(self, market_name): if market_name == "Binance": return self.binance_order_repr elif market_name == "Bitmex": return self.bitmex_repr return self.symbol @property def bitmex_repr(self): return "{}/{}".format(self.to_currency.short_name.upper(), self.from_currency.short_name.upper()) @property def binance_repr(self): return "{}{}".format(self.to_currency.short_name.upper(), self.from_currency.short_name.upper()) @property def binance_order_repr(self): return "{}/{}".format(self.to_currency.short_name.upper(), self.from_currency.short_name.upper())
class RideshareDetail(Base): """ The detail of a service a tourister can offer """ service_id = db.Column(db.Integer, db.ForeignKey('services.id'), nullable=False) price = db.Column(db.Float) miles = db.Column(db.String(20)) extraPricePerMile = db.Column(db.Float) make = db.Column(db.String(40)) year = db.Column(db.Integer) model = db.Column(db.String(20)) capacity = db.Column(db.Integer) additionalInfo = db.relationship('RideshareAdditionalInfo', backref='rideshare', lazy='dynamic')
class Trip(Base): """ trips a tourister has done """ __tablename__ = 'trips' tourister_id = db.Column(db.Integer, db.ForeignKey('touristers.id'), nullable=False) name = db.Column(db.String(30)) summary = db.Column(db.String(500)) city = db.Column(db.String(30)) highlights = db.relationship('TripHighlight', backref='service', lazy='dynamic') pricing = db.relationship('TripPricing', backref='service', uselist=False) services = db.relationship('Service', backref='service', lazy='dynamic')
class BlacklistToken(Base): """ Token Model for storing JWT tokens """ __tablename__ = 'blacklist_tokens' token = db.Column(db.String(500), unique=True, nullable=False) def __init__(self, token): self.token = token
class Appointment(ResourceMixin, db.Model): __tablename__ = 'appointments' # Properties id = db.Column(db.Integer, primary_key=True) scheduled_datetime = db.Column(db.Date, index=True) subject_matter = db.Column(db.String(1000), nullable=False) # Foreign Keys user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
class Testimonial(Base): """ testimonials given by touristees """ tourister_id = db.Column(db.Integer, db.ForeignKey('touristers.id'), nullable=False) user_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False) user = db.relationship("User", uselist=False) story = db.Column(db.String(800), nullable=False)
class Photo(db.Model): id = db.Column(db.Integer, primary_key=True) description = db.Column(db.String(500)) filename = db.Column(db.String(64)) filename_s = db.Column(db.String(64)) filename_m = db.Column(db.String(64)) timestamp = db.Column(db.DateTime, default=datetime.utcnow, index=True) can_comment = db.Column(db.Boolean, default=True) flag = db.Column(db.Integer, default=0) author_id = db.Column(db.Integer, db.ForeignKey('user.id')) author = db.relationship('User', back_populates='photos') comments = db.relationship('Comment', back_populates='photo', cascade='all') collectors = db.relationship('Collect', back_populates='collected', cascade='all') tags = db.relationship('Tag', secondary=tagging, back_populates='photos')