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 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 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 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 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 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 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 TaskComment(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('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('comments', lazy='dynamic'), uselist=False)
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 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 Constant(Model): id = Column(db.Integer, primary_key=True) slogan = Column(db.Text, default='', nullable=False) min_commission = Column(db.Integer, default=100, nullable=False) active = Column(db.Boolean, default=True) seo_keywords = Column(db.Text, default='') seo_description = Column(db.Text, default='')
class InfoPage(Model): id = Column(db.Integer, primary_key=True) url_name = Column( db.String(255), unique=True, default=lambda context: urlify(context.current_parameters['title'])) text = Column(db.Text, nullable=False) title = Column(db.Text(4096), nullable=False) listed = Column(db.Boolean, default=True) sort_order = Column(db.Integer, default=1, nullable=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 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)
import datetime from flask.ext.login import UserMixin, AnonymousUserMixin from sqlalchemy.orm import column_property from sqlalchemy.ext.hybrid import hybrid_property from sqlalchemy import select, func from project.modules.user_role import role_to_user from project.modules.user_rating import UserRating from project.database import db, Model, Column, relationship from project import config category_to_doer = db.Table( 'category_to_doer', Column('category_id', db.Integer, db.ForeignKey('category.id')), Column('user_id', db.Integer, db.ForeignKey('user.id'))) class Anonymous(AnonymousUserMixin): def __init__(self): self.full_name = 'anonymous' self.rights = 'guest' self.task_categories = dict() 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'),
class Role(Model): id = Column(db.Integer, primary_key=True) name = Column(db.String(255), nullable=False, unique=True)
class CommissionSettings(Model): id = Column(db.Integer, primary_key=True) lower_bound = Column(db.Integer, nullable=False) upper_bound = Column(db.Integer, nullable=False) commission = Column(db.Float, default=0.1, nullable=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 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)