class UserComment(Model): id = Column(db.Integer, primary_key=True) text = Column(db.Text, nullable=False) created_at = Column(db.DateTime, default=datetime.datetime.utcnow) task_id = Column(db.Integer, db.ForeignKey('task.id'), nullable=False) task = relationship('Task', foreign_keys=[task_id], backref=db.backref('user_comments', lazy='dynamic'), uselist=False) author_id = Column(db.Integer, db.ForeignKey('user.id'), nullable=False) author = relationship('User', foreign_keys=[author_id], backref=db.backref('created_comments', lazy='dynamic'), uselist=False) owner_id = Column(db.Integer, db.ForeignKey('user.id'), nullable=False) owner = relationship('User', foreign_keys=[owner_id], backref=db.backref('received_comments', lazy='dynamic'), uselist=False)
class UserRating(Model): id = Column(db.Integer, primary_key=True) value = Column(db.Float) owner_id = Column(db.Integer, db.ForeignKey('user.id'), nullable=False) owner = relationship('User', foreign_keys=[owner_id], backref=db.backref('ratings_received', lazy='dynamic'), uselist=False) rater_id = Column(db.Integer, db.ForeignKey('user.id'), nullable=False) rater = relationship('User', foreign_keys=[rater_id], backref=db.backref('ratings_delivered', lazy='dynamic'), uselist=False)
class TaskPersonalOffer(Model): id = Column(db.Integer, primary_key=True) text = Column(db.Text, nullable=False) created_at = Column(db.DateTime, default=datetime.datetime.utcnow) task_id = Column(db.Integer, db.ForeignKey('task.id'), nullable=False) task = relationship('Task', foreign_keys=[task_id], uselist=False) sender_id = Column(db.Integer, db.ForeignKey('user.id'), nullable=False) sender = relationship('User', foreign_keys=[sender_id], backref=db.backref('sent_personal_offers', lazy='dynamic'), uselist=False) receiver_id = Column(db.Integer, db.ForeignKey('user.id'), nullable=False) receiver = relationship('User', foreign_keys=[receiver_id], backref=db.backref('received_personal_offers', lazy='dynamic'), uselist=False)
class DoerApplication(Model): id = Column(db.Integer, primary_key=True) user_id = Column(db.Integer, db.ForeignKey('user.id')) user = relationship('User', foreign_keys=[user_id], uselist=False) passport_scan_id = Column(db.Integer, db.ForeignKey('upload.id'), nullable=False) passport_scan = relationship('Upload', foreign_keys=[passport_scan_id], uselist=False) created_at = Column(db.DateTime, default=datetime.datetime.utcnow)
class Category(Model): id = Column(db.Integer, primary_key=True) name = Column(db.String(255)) url_name = Column( db.String(255), unique=True, default=lambda context: urlify(context.current_parameters['name'])) parent_id = Column(db.Integer, db.ForeignKey('category.id'), default=None) parent = relationship('Category', remote_side=[id], backref=db.backref('children', lazy='dynamic')) additional_fields = Column(TextPickleType(), default='', nullable=False) @property def selfApiUrl(self): return url_for('api.{}'.format(self.__table__.name), url_name=self.url_name, _external=True) # Returns self id and all descendants' ids in a list def getTreeIds(self): return list( itertools.chain([self.id], *[child.getTreeIds() for child in self.children])) @property def tasks_query(self): return self.get_tasks(just_query=True) def get_tasks(self, just_query=False): from project.modules.task import Task cat_ids = self.getTreeIds() query = Task.query.filter(Task.category_id.in_(cat_ids)) if just_query: return query return query.all() @property def doers_query(self): return self.get_doers(just_query=True) def get_doers(self, just_query=False): from project.modules.user import User cat_ids = self.getTreeIds() query = User.query.filter( User.task_categories.any(Category.id.in_(cat_ids))) if just_query: return query return query.all() @property def isSubCategory(self): return self.parent and self.parent.url_name != 'all' @property def isSuperCategory(self): return self.url_name == 'all' or self.parent == None
class PrivateMessage(Model): id = Column(db.Integer, primary_key=True) text = Column(db.Text(), nullable=False) sender_id = Column(db.Integer, db.ForeignKey('user.id')) sender = relationship('User', foreign_keys=[sender_id], backref=db.backref('pms_sent', lazy='dynamic'), uselist=False) receiver_id = Column(db.Integer, db.ForeignKey('user.id'), nullable=False) receiver = relationship('User', foreign_keys=[receiver_id], backref=db.backref('pms_received', lazy='dynamic'), uselist=False) created_at = Column(db.DateTime, default=datetime.datetime.utcnow)
class TaskConfirmation(Model): id = Column(db.Integer, primary_key=True) created_at = Column(db.DateTime, default=datetime.datetime.utcnow) task_id = Column(db.Integer, db.ForeignKey('task.id'), nullable=False) task = relationship('Task', foreign_keys=[task_id], backref=db.backref('confirmations', lazy='dynamic'), uselist=False) sender_id = Column(db.Integer, db.ForeignKey('user.id'), nullable=False) sender = relationship('User', foreign_keys=[sender_id], backref=db.backref('task_confirmations', lazy='dynamic'), uselist=False)
class MobileConfirmation(Model): id = Column(db.Integer, primary_key=True) code = Column(db.String(32), nullable=False) user_id = Column(db.Integer, db.ForeignKey('user.id')) user = relationship('User', foreign_keys=[user_id], uselist=False) created_at = Column(db.DateTime, default=datetime.datetime.utcnow)
class UserContact(Model): id = Column(db.Integer, primary_key=True) type = Column(db.String(64), nullable=False) value = Column(db.String(255), nullable=False) owner_id = Column(db.Integer, db.ForeignKey('user.id'), nullable=False) owner = relationship('User', backref=db.backref('contacts', lazy='dynamic'), uselist=False)
class UloginData(Model): id = Column(db.Integer, primary_key=True) user_id = Column(db.Integer, db.ForeignKey('user.id'), nullable=False) user = relationship('User', foreign_keys=[user_id], backref=db.backref('social_identities', lazy='dynamic'), uselist=False) network = Column(db.String(64), nullable=False) identity = Column(db.String(160), nullable=False)
class TaskOffer(Model): id = Column(db.Integer, primary_key=True) text = Column(db.Text, nullable=False) created_at = Column(db.DateTime, default=datetime.datetime.utcnow) price = Column(db.Numeric(precision=15, scale=2), default=get_price_from_task) task_id = Column(db.Integer, db.ForeignKey('task.id'), nullable=False) task = relationship('Task', foreign_keys=[task_id], backref=db.backref('offers', lazy='dynamic'), uselist=False) doer_id = Column(db.Integer, db.ForeignKey('user.id'), nullable=False) doer = relationship('User', foreign_keys=[doer_id], backref=db.backref('created_task_offers', lazy='dynamic'), uselist=False)
class Task(Model): class Status: created = 'created' assigned = 'assigned' completed = 'completed' id = Column(db.Integer, primary_key=True) title = Column(db.String(255), nullable=False) description = Column(db.Text, nullable=False) created_at = Column(db.DateTime, default=datetime.datetime.utcnow) due = Column(db.DateTime, nullable=False) customer_id = Column(db.Integer, db.ForeignKey('user.id'), nullable=False) customer = relationship('User', foreign_keys=[customer_id], backref=db.backref('created_tasks', lazy='dynamic'), uselist=False) category_id = Column(db.Integer, db.ForeignKey('category.id'), nullable=False) category = relationship('Category', backref=db.backref('tasks', lazy='dynamic'), uselist=False) contacts = Column(TextPickleType(), nullable=False) status = Column(db.String(64), nullable=False, default='created') addresses = Column(TextPickleType(), nullable=False) # None means "let the doer decide" reward = Column(db.Numeric(precision=15, scale=2), default=None) doer_id = Column(db.Integer, db.ForeignKey('user.id')) doer = relationship('User', foreign_keys=[doer_id], backref=db.backref('assigned_tasks', lazy='dynamic'), uselist=False) additional_data = Column(TextPickleType(), default='', nullable=False)
class TrustedPerson(Model): id = Column(db.Integer, primary_key=True) full_name = Column(db.Text(512), nullable=False) description = Column(db.Text, nullable=False) phone = Column(db.String(64), nullable=False) user_id = Column(db.Integer, db.ForeignKey('user.id'), nullable=False) user = relationship('User', foreign_keys=[user_id], backref=db.backref('trusted_persons', lazy='dynamic'), uselist=False)
class Payment(Model): id = Column(db.Integer, primary_key=True) user_id = Column(db.Integer, db.ForeignKey('user.id')) user = relationship('User', foreign_keys=[user_id], backref=db.backref('payments', lazy='dynamic'), uselist=False) done = Column(db.Boolean, default=False, nullable=False) created_at = Column(db.DateTime, default=datetime.datetime.utcnow)
class Upload(Model): id = Column(db.Integer, primary_key=True) created_at = Column(db.DateTime, default=datetime.datetime.utcnow) author_id = Column(db.Integer, db.ForeignKey('user.id')) author = relationship('User', foreign_keys=[author_id], backref=db.backref('uploads', lazy='dynamic'), uselist=False) type = Column(db.String(64), nullable=False) role = Column(db.String(64), nullable=False) hash = Column(db.String(64), nullable=False) description = Column(db.String(512), nullable=False) mime = Column(db.String(255), nullable=False) file_path = Column(db.String(1024), nullable=False) url = Column(db.String(1024), nullable=False)
class User(database.Model): """ Class that handles user logins and authentication. The following attributes of a login are stored in this table: * user_id (as a foreign key. When a user successfully registers, the user_id is inserted into the logins table.) * email - the user's email * hashed password - hashed password (using Flask-Bcrypt) * A foreign key relationship with UserProfile, which joins data from the Users and UserProfiles tables * A foreign key relationship with Follow, which manages a self-referential follower/following relatitionship. """ __tablename__ = 'users' id = database.Column(database.Integer, primary_key=True) email = database.Column(database.String, unique=True, nullable=False) password_hashed = database.Column(database.String(264), nullable=False) registered_on = database.Column(database.DateTime, nullable=True) email_confirmation_sent_on = database.Column(database.DateTime, nullable=True) email_confirmed = database.Column(database.Boolean, default=False) email_confirmed_on = database.Column(database.DateTime, nullable=True) def __init__(self, email: str, password_plaintext: str): self.email = email self.password_hashed = self._generate_password_hash(password_plaintext) self.registered_on = datetime.now() self.email_confirmation_sent_on = datetime.now() self.email_confirmed = False self.email_confirmed_on = None user_profiles = database.relationship('UserProfile', backref='user', lazy='dynamic') user_recipes = database.relationship('RecipeBox', backref='user', lazy='dynamic') followed = database.relationship( 'User', secondary=followers, primaryjoin=(followers.c.follower_id == id), secondaryjoin=(followers.c.followed_id == id), backref=database.backref('followers', lazy='dynamic'), lazy='dynamic') user_meals = database.relationship("Meal", backref='user', lazy='dynamic') def is_password_correct(self, password_plaintext: str): return bcrypt.check_password_hash(self.password_hashed, password_plaintext) def set_password(self, password_plaintext: str): self.password_hashed = self._generate_password_hash(password_plaintext) def follow(self, user): if not self.is_following(user): self.followed.append(user) def unfollow(self, user): if self.is_following(user): self.followed.remove(user) def is_following(self, user): return self.followed.filter( followers.c.followed_id == user.id).count() > 0 @staticmethod def _generate_password_hash(password_plaintext): return bcrypt.generate_password_hash( password_plaintext, current_app.config.get('BCRYPT_LOG_ROUNDS')).decode('utf-8') def __repr__(self): return f'<User: {self.email} {self.password_hashed}>' @property def is_authenticated(self): """Return True if the user has been successfully registered.""" return True @property def is_active(self): """Always True, as all users are active.""" return True @property def is_anonymous(self): """Always False, as anonymous users aren't supported.""" return False def get_id(self): """Return the user ID as a unicode string (`str`).""" return str(self.id)
class User(Model, UserMixin): id = Column(db.Integer, primary_key=True) full_name = Column(db.String(255), nullable=False) registered_at = Column(db.DateTime, default=datetime.datetime.utcnow) last_visited_at = Column(db.DateTime, default=None) phone = Column(db.String(100)) email = Column(db.String(100), unique=False) #created_tasks = relationship('Task', backref='customer', lazy='dynamic') #assigned_tasks = relationship('Task', backref='doer', lazy='dynamic') password = Column(db.String(64), nullable=False) password_salt = Column(db.String(8), nullable=False) city = Column(db.String(255), nullable=False) active = Column(db.Boolean, default=True, nullable=False) # Is account activated email_confirmed = Column(db.Boolean, default=False, nullable=False) # Is account activated phone_confirmed = Column(db.Boolean, default=False, nullable=False) # Is phone confirmed doer = Column(db.Boolean, default=True, nullable=False) # Does a user have doer rights task_categories = relationship('Category', secondary=category_to_doer, backref=db.backref('doers', lazy='dynamic')) balance = Column(db.Numeric(precision=15, scale=2), default=0) avatar_id = Column(db.Integer, db.ForeignKey('upload.id'), nullable=True) avatar = relationship('Upload', foreign_keys=[avatar_id], uselist=False) rights = Column(db.String(100), nullable=False, default='user') # deprecated roles = db.relationship('Role', secondary=role_to_user, backref=db.backref('users', lazy='dynamic')) age = Column(db.Integer) about = Column(db.Text(2048), default='') deleted = Column(db.Boolean, default=False, nullable=False) _rating = Column('rating', db.Float, nullable=False, default=0.0) def delete(self): self.deleted = True self.phone = '000000000' self.email = '*****@*****.**' self.rights = 'deleted' try: db.session.commit() except: db.session.rollback() raise @hybrid_property def rating(self): return self._rating @rating.setter def rating(self, value): raise Exception( 'Please, use User.add_rating(rater, value) and User.remove_rating(rating_id) methods' ) def make_doer(self): self.doer = True if self.balance == None: self.balance = 0 try: db.session.commit() except: db.session.rollback() raise def unmake_doer(self): self.doer = False try: db.session.commit() except: db.session.rollback() raise def add_rating(self, rater, value): rating = UserRating(owner=self, rater=rater, value=value) try: db.session.add(rating) db.session.commit() except: db.session.rollback() raise self._rating = db.session.query( func.avg(UserRating.value).label('average')).filter( UserRating.owner_id == self.id).one()[0] or 0 def remove_rating(self, id): rating = UserRating.query.get(id) if rating == None: raise Exception('No user rating with id ' + str(id)) try: db.session.delete(rating) db.session.commit() except: db.session.rollback() raise self._rating = db.session.query( func.avg(UserRating.value).label('average')).filter( UserRating.owner_id == self.id).one()[0] or 0 def is_active(self): return self.active def is_anonymous(self): return False def is_authenticated(self): return True def get_id(self): return str(self.id)
class User(database.Model): """ Class that represents a user of the application The following attributes of a user are stored in this table: * email - email address of the user * hashed password - hashed password (using Flask-Bcrypt) * registered_on - date & time that the user registered * email_confirmation_sent_on - date & time that the confirmation email was sent * email_confirmed - flag indicating if the user's email address has been confirmed * email_confirmed_on - date & time that the user's email address was confirmed REMEMBER: Never store the plaintext password in a database! """ __tablename__ = 'users' id = database.Column(database.Integer, primary_key=True) email = database.Column(database.String, unique=True) password_hashed = database.Column(database.String(60)) registered_on = database.Column(database.DateTime) email_confirmation_sent_on = database.Column(database.DateTime) email_confirmed = database.Column(database.Boolean, default=False) email_confirmed_on = database.Column(database.DateTime) stocks = database.relationship('Stock', backref='user', lazy='dynamic') def __init__(self, email: str, password_plaintext: str, email_confirmation_sent_on=None): """Create a new User object This constructor assumes that an email is sent to the new user to confirm their email address at the same time that the user is registered. """ self.email = email self.password_hashed = bcrypt.generate_password_hash( password_plaintext, current_app.config.get('BCRYPT_LOG_POUNDS')).decode('utf-8') self.registered_on = datetime.now() self.email_confirmation_sent_on = datetime.now() self.email_confirmed = False self.email_confirmed_on = None def is_password_correct(self, password_plaintext: str): return bcrypt.check_password_hash(self.password_hashed, password_plaintext) def __repr__(self): return f'<User: {self.email}>' def set_password(self, password_plaintext): self.password_hashed = bcrypt.generate_password_hash( password_plaintext, current_app.config.get('BCRYPT_LOG_ROUNDS')).decode('utf-8') @property def is_authenticated(self): """Return True if the user has been successfully registered.""" return True @property def is_active(self): """Always True, as all users are active.""" return True @property def is_anonymous(self): """Always False, as anonymous users aren't supported.""" return False def get_id(self): """Return the user ID as a unicode string (`str`).""" return str(self.id)