class Subscription(db.Model, AccountDb): subscription_id = Column(db.Integer, primary_key=True) name = Column(db.String(16)) email = Column(db.String(255)) customer_id = Column(db.Integer, ForeignKey("customer.customer_id")) __table_args__ = (UniqueConstraint('customer_id', 'name', 'email'),) def __str__(self): return "<Subscription of %s to %s>" % (self.email, self.name) def __repr__(self): return str(self) @classmethod @duplicate_handle(errors.SubscriptionAlreadyExists) def new_subscription(cls, name, email, customer_id): subscription = cls() subscription.name = name subscription.email = email subscription.customer_id = customer_id db.session.add(subscription) return subscription
class ItemRemovedTrackerEntry(TrackerEntry): """ TrackerEntry that indicates that an item has been removed from a survey. """ id = db.Column(db.Integer, db.ForeignKey(TrackerEntry.id, ondelete='CASCADE'), primary_key=True) # polymorphic config __tablename__ = 'item_removed_tracker_entry' __mapper_args__ = {'polymorphic_identity': __tablename__} # columns parent_item_name = db.Column(db.String(50)) removed_item_name = db.Column(db.String(50)) # foreign keys parent_item_id = db.Column( db.Integer, db.ForeignKey('survey_base.id', onupdate='CASCADE', ondelete='CASCADE')) # relationships parent_item = db.relationship('SurveyBase', uselist=False, foreign_keys=[parent_item_id], backref=backref( 'item_removed_parent_tracker_entries', cascade='all, delete')) def __init__(self, dataclient: DataClient, parent_item_name: str, parent_item: 'SurveyBase', removed_item_name: str, **kwargs): super(ItemRemovedTrackerEntry, self).__init__(dataclient, **kwargs) self.parent_item_name = ellipse(parent_item_name, 50) self.removed_item_name = ellipse(removed_item_name, 50) self.parent_item = parent_item
class Action(db.Model): """.""" __tablename__ = "actions" action_id = db.Column(db.Integer, autoincrement=True, primary_key=True) action_type = db.Column(db.String(20), nullable=False, unique=True) def __repr__(self): """Provide helpful representation when printed.""" return "<action {}: {}>".format( self.action_id, self.action_type, )
class FeedbackCategory(db.Model): """.""" __tablename__ = "feedback_categories" category_id = db.Column(db.Integer, autoincrement=True, primary_key=True) category_name = db.Column(db.String(60)) def __repr__(self): """Provide helpful representation when printed.""" return "<from {}: {}>".format( self.category_id, self.category_name, )
class Flavor(db.Model, AccountDb): display_fields = ("flavor_id", "vcpus", "ram", "disk", "network") service_id = Column(db.Integer, ForeignKey('service.service_id')) flavor_id = Column(db.String(32), primary_key=True) vcpus = Column(db.Integer) ram = Column(db.Integer) disk = Column(db.Integer) network = Column(db.Integer) @classmethod @duplicate_handle(errors.FlavorAlreadyExists) def new_flavor(cls, service_id, flavor_id, vcpus, ram, disk, network=None): flavor = cls() flavor.flavor_id = flavor_id flavor.service_id = service_id flavor.vcpus = vcpus flavor.ram = ram flavor.disk = disk flavor.network = network db.session.add(flavor) db.session.flush() return flavor def __str__(self): params = { 'vcpus': self.vcpus, 'ram': self.ram, 'disk': self.disk, 'flavor_id': self.flavor_id } return ", ".join("%s: %s" % k_v for k_v in params.items()) @duplicate_handle(errors.FlavorAlreadyExists) def update(self, parameters): super().update(parameters) @classmethod def get_service_id(cls, flavor_id): flavor = cls.query.get(flavor_id) if flavor is not None: return flavor.service_id else: raise errors.FlavorNotFound()
class Team(db.Model): """ a team """ id = db.Column(db.Integer, primary_key=True) owner_id = db.Column(db.Integer, db.ForeignKey('user.id')) name = db.Column(db.String(), nullable=False, unique=True) color = db.Column(db.Integer, nullable=False) owner = db.relationship('User', foreign_keys=owner_id) # l'objet users utilise la reference owner_id alors qu'il ne devrait pas!! qrs = db.relationship('FoundQR', backref='team', cascade='all, delete') pictures = db.relationship('Picture', backref='team', cascade='all, delete') def __repr__(self): return f'<Team {self.name}, owner {self.owner.name}, color {self.color}>'
class Tag(db.Model): __tablename = 'tags' id = db.Column(db.Integer, primary_key=True) tagname = db.Column(db.String(24)) tagnumber = db.Column(db.Integer) @staticmethod def tagadd(tagname,tagnumber): tag = Tag() tag.tagname = tagname tag.tagnumber = tagnumber db.session.add(tag) db.session.commit() def to_json(all_vendors): v = [ven.dobule_to_dict() for ven in all_vendors] return v
class Party(db.Model): id = db.Column(db.Integer, primary_key=True) # polymorphic config person_type = db.Column(db.String(50)) __tablename__ = 'person' __mapper_args__ = { 'polymorphic_identity': __tablename__, 'polymorphic_on': person_type } owned_objects = db.relationship('OwnershipBase', back_populates='owners', secondary=ownership_table) @property @abstractmethod def roles(self) -> List[Role]: raise NotImplementedError
class Program(db.Model): """All loyalty program.""" __tablename__ = "programs" program_id = db.Column(db.Integer, autoincrement=True, primary_key=True) vendor_id = db.Column(db.Integer, db.ForeignKey('vendors.vendor_id'), nullable=False) type_id = db.Column(db.Integer, db.ForeignKey('program_types.type_id'), nullable=False) program_name = db.Column(db.String(32), nullable=False, unique=True) vendor = db.relationship('Vendor', backref=db.backref('programs', order_by=program_id)) def __repr__(self): """Provide helpful representation when printed.""" return "<program {}: {} | vendor: {}>".format(self.program_id, self.program_name, self.vendor.vendor_id, )
class QuestionnaireRemovedTrackerEntry(TrackerEntry): """ TrackerEntry that indicates that a Questionnaire was deleted by it's owner. """ id = db.Column(db.Integer, db.ForeignKey(TrackerEntry.id, ondelete='CASCADE'), primary_key=True) # polymorphic config __tablename__ = 'questionnaire_removed_tracker_entry' __mapper_args__ = {'polymorphic_identity': __tablename__} # columns questionnaire_name = db.Column(db.String(50)) def __init__(self, dataclient: DataClient, questionnaire_name: str, **kwargs): super(QuestionnaireRemovedTrackerEntry, self).__init__(dataclient, **kwargs) self.questionnaire_name = ellipse(questionnaire_name, 50)
class Post(db.Model): id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(80)) body = db.Column(db.Text) pub_date = db.Column(db.DateTime) category_id = db.Column(db.Integer, db.ForeignKey('category.id')) category = db.relationship('Category', backref=db.backref('posts', lazy='dynamic')) def __init__(self, title, body, category, pub_date=None): self.title = title self.body = body if pub_date is None: pub_date = datetime.utcnow() self.pub_date = pub_date self.category = category def __repr__(self): return '<Post %r>' % self.title
class PromoCode(db.Model, AccountDb): promocode_id = Column(db.Integer, primary_key=True) value = Column(db.String(32)) customer_id = Column(db.Integer, ForeignKey("customer.customer_id", ondelete="CASCADE"), index=True) display_fields = frozenset(["value"]) def __str__(self): return "<PromoCode card %s customer_id:%s>" % (self.value, self.customer_id) @classmethod def new_code(cls, value, customer_id): promocode = cls() promocode.value = value promocode.customer_id = customer_id db.session.add(promocode) @classmethod def get_by_customer_id(cls, customer_id): return cls.query.filter_by(customer_id=customer_id)
class BlacklistToken(Base): """Token model for storing JWT tokens.""" token = db.Column(db.String(500), unique=True, nullable=False) blacklisted_on = db.Column(db.DateTime, nullable=False) def __init__(self, token): self.token = token self.blacklisted_on = datetime.datetime.now() @staticmethod def check_blacklist(auth_token): """Check whether an auth token has been blacklisted.""" res = BlacklistToken.query.filter_by(token=str(auth_token)).first() if res: return True else: return False def __repr__(self): return '<id: token: {}'.format(self.token)
class QuestionResponse(OwnershipBase): id = db.Column(db.Integer, db.ForeignKey(OwnershipBase.id, ondelete="CASCADE", onupdate="CASCADE"), primary_key=True) value = db.Column(db.SmallInteger, nullable=False) verified = db.Column(db.Boolean, default=False, nullable=False) verification_token = db.Column(db.String(32)) question_id = db.Column(db.Integer, db.ForeignKey('question.id')) def __init__(self, data_subject: DataSubject = None, **kwargs): super(QuestionResponse, self).__init__(**kwargs) if data_subject is not None: self.owners.append(data_subject) self.owners += self.question.owners def verify(self) -> bool: """ Used to verify a QuestionResponse to make it count into the statistic. :return: bool Indicating whether the answer count for the corresponding question increased """ question = self.question data_subject = next( filter(lambda x: isinstance(x, DataSubject), self.owners)) earlier_results = question.get_question_responses_by_subject( data_subject) verified_results = list(filter(lambda x: x.verified, earlier_results)) for vr in verified_results: # remove previous verified result(s?) question.remove_question_result(vr) self.verified = True self.verification_token = None return len(verified_results) == 0 # no previous verified results?
class ServicePrice(db.Model, AccountDb): service_id = Column(db.String(32), primary_key=True) price = Column(db.DECIMAL(precision=conf.backend.decimal.precision, scale=conf.backend.decimal.scale)) tariff_id = Column(db.Integer, ForeignKey("tariff.tariff_id"), primary_key=True) need_changing = Column(db.Boolean()) def __init__(self, service_id, price, need_changing=False): self.service_id = service_id self.price = price self.need_changing = need_changing def display(self, short=True): service = Service.get_by_id(self.service_id) return {"service": service.display(short), "price": decimal_to_string(self.price), "need_changing": self.need_changing} @property def service(self): # we can't do it by relationship, because some services # can be fixed services which are configured from config file return Service.get_by_id(self.service_id)
class TrackerEntry(OwnershipBase): """ Base class for all tracker entries. Stores timestamp of the event and DataClient who triggered the event. """ id = db.Column(db.Integer, db.ForeignKey(OwnershipBase.id, ondelete='CASCADE'), primary_key=True) # polymorphic config __tablename__ = 'tracker_entry' __mapper_args__ = {'polymorphic_identity': __tablename__} # columns timestamp = db.Column(db.DateTime) dataclient_email = db.Column(db.String(100)) def __init__(self, dataclient: DataClient, **kwargs): super(TrackerEntry, self).__init__(**kwargs) self.timestamp = datetime.now() self.dataclient_email = dataclient.email
class Account(db.Model, AccountDb): id_field = "account_id" account_id = Column(db.Integer, primary_key=True) customer_id = Column(db.Integer, ForeignKey("customer.customer_id")) currency = Column(db.String(3)) balance = Column(db.DECIMAL(precision=conf.backend.decimal.precision, scale=conf.backend.decimal.scale)) withdraw = Column(db.DECIMAL(precision=conf.backend.decimal.precision, scale=conf.backend.decimal.scale)) history = relationship("AccountHistory", lazy="dynamic") def __str__(self): return "<Account {0.account_id} {0.customer_id} {0.currency} {0.balance}>".format(self) @classmethod def create(cls, currency, customer, user_id, comment="create new account", start_balance=Decimal(0)): account = cls() account.currency = currency account.balance = start_balance account.withdraw = Decimal(0) db.session.flush() account.history.append(AccountHistory.create(customer, account.account_id, user_id, comment, start_balance)) return account def modify(self, customer, delta, user_id, comment, transaction_id=None): self.balance = Account.balance + delta self.history.append(AccountHistory.create(customer, self.account_id, user_id, comment, delta, transaction_id=transaction_id)) db.session.flush() def charge(self, delta): self.withdraw = Account.withdraw + delta db.session.flush() @property def current(self): return self.balance - self.withdraw
class Violation(db.Model): id = db.Column(db.Integer, primary_key=True) release_id = db.Column(db.Integer) description = db.Column(db.String(255)) checked = db.Column(db.Boolean) created_time = db.Column(db.TIMESTAMP) release = None def _init_(self, release_id, description, checked): self.release_id = release_id self.description = description self.checked = checked def serialize(self): return { 'id': self.id, 'release_id': self.release_id, 'description': self.description, 'cheked': self.checked, 'created_time': self.created_time, 'release': self.release.serialize() }
class OwnershipBase(db.Model): id = db.Column(db.Integer, primary_key=True) # polymorphic config ownership_base_type = db.Column(db.String(50)) __tablename__ = 'ownership_base' __mapper_args__ = { 'polymorphic_identity': __tablename__, 'polymorphic_on': ownership_base_type } owners = db.relationship('Party', back_populates='owned_objects', secondary=ownership_table) def accessible_by(self, party): if party is None: return False if Role.Root in party.roles: return True if Role.Admin in party.roles: return True return party in self.owners
class SubscriptionSwitch(db.Model): confirmation_id = Column(db.Integer, primary_key=True) enable = Column(db.Boolean) name = Column(db.String(16)) customer_id = Column(db.Integer, ForeignKey("customer.customer_id")) __table_args__ = (UniqueConstraint('customer_id', 'name'),) def __str__(self): return "<SubscriptionSwitch to %s>" % self.name def __repr__(self): return str(self) @classmethod @duplicate_handle(errors.SubscriptionSwitchAlreadyExists) def new_switch(cls, enable, name, customer_id): switch = cls() switch.name = name switch.enable = enable switch.customer_id = customer_id db.session.add(switch) return switch
class Tariff(db.Model, AccountDb): id_field = "tariff_id" unique_field = "localized_name" tariff_id = Column(db.Integer, primary_key=True) localized_name = relationship("TariffLocalization", cascade="all") description = Column(db.Text()) currency = Column(db.String(3)) parent_id = Column(db.Integer, ForeignKey('tariff.tariff_id', ondelete='CASCADE')) parent = relationship('Tariff', remote_side=[tariff_id]) deleted = Column(db.DateTime()) created = Column(db.DateTime()) modified = Column(db.DateTime()) services = relationship("ServicePrice", cascade="save-update, merge, delete, delete-orphan") mutable = Column(db.Boolean()) default = Column(db.Boolean(), index=True) history = relationship('TariffHistory', remote_side=[tariff_id], lazy="dynamic", cascade="all") display_fields = frozenset(["description", "created", "deleted", "tariff_id", "parent_id", "mutable", "default", "currency", "modified"]) def __str__(self): return "<Tariff %s>" % self.name @property def name(self): return self.localized_name_as_dict()[DEFAULT_LANGUAGE].localized_name def localized_name_as_dict(self): return {localization.language: localization for localization in self.localized_name} def update_localized_name(self, localized_name): current = self.localized_name_as_dict() for language, value in localized_name.items(): if language in current: current[language].localized_name = value else: self.localized_name.append(TariffLocalization.create_localization(language, value)) def get_localized_name(self, language): localized_name = self.localized_name_as_dict() return (localized_name.get(language) or localized_name[DEFAULT_LANGUAGE]).localized_name @classmethod @duplicate_handle(errors.TariffAlreadyExists) def create_tariff(cls, localized_name, description, currency, parent_id=None, services=None): tariff = cls() tariff.description = description tariff.currency = currency.upper() tariff.parent_id = parent_id now = utcnow().datetime tariff.created = now tariff.modified = now tariff.deleted = None tariff.update_localized_name(localized_name) tariff.mutable = True if parent_id and not services: tariff.update_services(Tariff.get_by_id(parent_id).services) if services: tariff.update_services(services) db.session.add(tariff) db.session.flush() return tariff @duplicate_handle(errors.TariffAlreadyExists) def update(self, localized_name=None, description=None, services=None, currency=None): if not self.mutable: if services and self.services_to_change(): return self.update_new_vm_services(services) raise errors.ImmutableTariff() if self.deleted: raise errors.RemovedTariff() if localized_name: self.update_localized_name(localized_name) if description: self.description = description if services: self.update_services(services) if currency: self.currency = currency.upper() if db.session.is_modified(self): self.modified = utcnow().datetime return True return False def services_as_dict(self, lower=False): lower_func = (lambda x: x.lower()) if lower else lambda x: x return {lower_func(service.service_id): service for service in self.services} def service_price(self, service_id): service_id = str(service_id) sp = self.services_as_dict(lower=True).get(service_id.lower()) if not sp: logbook.warning("Tariff {} don't have service {}", self, service_id) return None return sp.price def services_to_change(self): return {service.service_id for service in self.services if service.need_changing} def service_ids(self): return {service.service_id for service in self.services} def flavors(self): services = set() for service_price in self.services: service = service_price.service if service.category_id == Category.VM: services.add(service.flavor.flavor_id) return frozenset(services) def update_new_vm_services(self, services): current_services = self.services_as_dict() services_to_update = self.services_to_change() for service in services: service_id = service['service_id'] if service_id in services_to_update: current_services[service_id].price = service['price'] current_services[service_id].need_changing = False def update_services(self, services): current_services = self.services_as_dict() new_services = set() for service in services: if isinstance(service, dict): service_id = service["service_id"] price = service["price"] else: service_id = service.service_id price = service.price if service_id in current_services: current_services[service_id].price = price else: self.services.append(ServicePrice(service_id, price)) new_services.add(service_id) removed_services = set(current_services.keys()) - new_services if removed_services: logbook.debug("Remove services {} from tariff {}", removed_services, self) for service_id in removed_services: self.services.remove(current_services[service_id]) def display(self, short=True): res = super().display(short) res["localized_name"] = {loc.language: loc.localized_name for loc in self.localized_name} if not short: res["services"] = [s.display() for s in self.services] # HACK to show used customers by request if isinstance(short, list): res["used"] = self.used() return res def display_for_customer(self): tariff_info = { "services": [s.display() for s in self.services], "localized_name": {loc.language: loc.localized_name for loc in self.localized_name} } return tariff_info def remove(self): if self.deleted: return False if self.used() > 0 or self.deferred_changes(): raise errors.RemoveUsedTariff() self.deleted = utcnow().datetime return True def mark_immutable(self): if self.mutable: self.mutable = False self.modified = utcnow().datetime return True return False @classmethod def delete_by_prefix(cls, prefix, field=None): field = field or cls.unique_field if not field: raise Exception("Field for removing is not set") member = getattr(cls, field) if field == "localized_name": query = cls.query.join(Tariff.localized_name).\ filter(TariffLocalization.localized_name.ilike("%{}%".format(prefix + "%"))) else: query = cls.query.filter(member.like(prefix + "%")) query = query.filter(or_(cls.default == None, cls.default == False)) ids = [tariff_id for tariff_id, in query.with_entities(cls.id_field)] if not ids: return 0 ServicePrice.query.filter(ServicePrice.tariff_id.in_(ids)).delete(False) TariffHistory.query.filter(TariffHistory.tariff_id.in_(ids)).delete(False) TariffLocalization.query.filter(TariffLocalization.parent_id.in_(ids)).delete(False) return cls.query.filter(cls.tariff_id.in_(ids)).delete("fetch") @classmethod def get_default(cls): return cls.query.filter(cls.default == True) def make_default(self): if self.default: return if self.deleted: raise errors.RemovedTariff() if self.mutable: raise errors.MutableTariffCantBeDefault() self.get_default().update({"default": False}) db.session.flush() self.default = True def used(self): from model import Customer """ Returns number of customer who use this tariff """ return Customer.query.filter(Customer.tariff_id == self.tariff_id, Customer.deleted == None).count() def deferred_changes(self): from model import Deferred """ Returns number of usages in deferred changes """ return Deferred.query.filter(Deferred.tariff_id == self.tariff_id).count() def get_history(self, date_before, date_after): history = self.history.filter(TariffHistory.tariff_id == self.tariff_id) if date_after: history = history.filter(TariffHistory.date > date_after) if date_before: history = history.filter(TariffHistory.date < date_before) return history.order_by(desc(TariffHistory.history_id))
class Note(db.Model): id = db.Column(db.Integer, primary_key=True) text = db.Column(db.String(60), nullable=False) notebook_id = db.Column(db.Integer, db.ForeignKey("notebook.id"), nullable=False) notebook = db.relationship("Notebook", back_populates="notes")
class TariffHistory(db.Model, AccountDb): EVENT_CREATE = "create" EVENT_UPDATE = "update" EVENT_DELETE = "delete" EVENT_ASSIGN = "assign" EVENT_UNASSIGN = "unassign" EVENT_IMMUTABLE = "immutable" EVENTS = {EVENT_CREATE, EVENT_UPDATE, EVENT_DELETE} MAX_AGE_OF_UPDATES_TO_AUTO_COLLAPSE = timedelta(seconds=conf.backend.tariff.max_age_of_updates_to_auto_collapse) history_id = Column(db.Integer, primary_key=True) event = Column(db.String(16)) user_id = Column(db.Integer, ForeignKey('user.user_id', ondelete="set null")) user = relationship("User") tariff_id = Column(db.Integer, ForeignKey('tariff.tariff_id')) tariff = relationship("Tariff") customer_id = Column(db.Integer, ForeignKey('customer.customer_id')) customer = relationship("Customer") date = Column(db.DateTime()) snapshot = deferred(Column(db.Text())) display_fields = frozenset(("history_id", "user", "event", "date", "localized_name", "snapshot")) display_fields_short = frozenset(("history_id", "user", "event", "date", "localized_name")) extract_fields = {"user": User.display} def __str__(self): return "<TariffHistory '%s' %s by %s>" % (self.tariff.name, self.event, self.date) def __repr__(self): return str(self) @classmethod def create(cls, event, user_id, tariff, customer=None): history_item = cls() history_item.event = event history_item.user_id = user_id history_item.tariff = tariff history_item.customer = customer history_item.date = tariff.modified history_item.snapshot = json.dumps(tariff.display(short=True), cls=DateTimeJSONEncoder) db.session.add(history_item) db.session.flush() if event == cls.EVENT_UPDATE: history_item._reduce_history_of_update_operations() return history_item def _reduce_history_of_update_operations(self): query = self.query.filter(TariffHistory.history_id != self.history_id, TariffHistory.tariff_id == self.tariff_id, TariffHistory.event == self.EVENT_UPDATE, TariffHistory.user_id == self.user_id, TariffHistory.date <= self.date + timedelta(seconds=1), TariffHistory.date >= self.date - self.MAX_AGE_OF_UPDATES_TO_AUTO_COLLAPSE) n = query.delete(False) logbook.debug("Reduced {} history records for tariff {}", n, self.tariff) return n @property def localized_name(self): return conf.tariff.events.get(self.event)
class Annotation(Basemodel): __tablename__ = 'annotations' deviceID = db.Column(db.String(50), index=True) file_path = db.Column(db.String(255), nullable=False) file_location = db.Column(db.String(255), nullable=False) def __init__(self, deviceID, file_path, file_location): """ Params: str: file_path: file's path on remote's device str: file_location: file's path on server Return: """ self.deviceID = deviceID self.file_path = file_path self.file_location = file_location @classmethod def save(self, annotate_data): """ Params: dict: annotate_data Return file's location on server """ file_path = annotate_data["path_file"] file_name = file_path.replace("/storage/emulated/0/Download/", "").replace("/", "__") deviceID = str(annotate_data.get("deviceID", "nodevice")) path_to_foder_deviceID = "./data/json_data/" + deviceID os.makedirs(path_to_foder_deviceID, exist_ok=True) os.makedirs(os.path.join(path_to_foder_deviceID, "versions"), exist_ok=True) file_name_main = "{}.json".format(file_name) file_location_main = "{}/{}".format(path_to_foder_deviceID, file_name_main) file_name_version = "{}_{}.json".format( file_name, datetime.datetime.now().strftime("%s")) file_location_version = "{}/versions/{}".format( path_to_foder_deviceID, file_name_version) try: savefile = open(file_location_version, "w") savefile.write(json.dumps(annotate_data)) savefile.close() savefile = open(file_location_main, "w") savefile.write(json.dumps(annotate_data)) savefile.close() annotattion = Annotation(deviceID=deviceID, file_path=file_path, file_location=file_location_version) db.session.add(annotattion) db.session.commit() return file_path, file_location_version except Exception as e: _logger.error(e) db.session.rollback() raise e
class User(db.Model): """Creating class for users.""" __tablename__ = "users" user_id = db.Column(db.Integer, autoincrement=True, primary_key=True) first_name = db.Column(db.String(64), nullable=False) last_name = db.Column(db.String(64), nullable=False) username = db.Column(db.String(64), nullable=False) email = db.Column(db.String(64), nullable=False) password = db.Column(db.String(64), nullable=False) location = db.Column(db.String(64), nullable=True) profile_image = db.Column(db.Text, nullable=True) date_joined = db.Column(db.DateTime, nullable=False) following = db.relationship( 'User', secondary='connections', primaryjoin='Connection.follower_user_id == User.user_id', secondaryjoin='Connection.following_user_id == User.user_id', backref=db.backref('followers'), ) def __repr__(self): """For a more manageable way to print object's attributes.""" return "{}'s Info: {} {}, {}".format(self.username, self.first_name, self.last_name, self.email) @classmethod def get_by_username(cls, username): """Gets the user object given a username.""" try: return User.query.filter(User.username == username).one() except NoResultFound: print "No user found." return None @classmethod def add_new_user(cls, first_name, last_name, username, email, password, location=None, profile_image=None): """Add new user to the db.""" user = User(first_name=first_name, last_name=last_name, username=username, email=email, password=password, date_joined=datetime.today().date, location=location, profile_image=profile_image) db.session.add(user) db.session.commit() return user # WHERE DOES THIS ACTUALLY BELONG? def handle_signup_form_errors(cls, first_name, last_name, username, email, password, password_confirmed, location, profile_image): """Generates flash msgs depending on errors""" errors = [] if first_name or last_name or username or email or password: pass else: errors.append("Your profile is incomplete.") if password != password_confirmed: errors.append("The passwords you've entered don't match.") elif username in users: errors.append( "I'm sorry, it looks like that username is taken already. Please select a new one." ) return errors
class User(db.Model): """Users.""" __tablename__ = "users" user_id = db.Column(db.Integer, autoincrement=True, primary_key=True) email = db.Column(db.String(255), nullable=False, unique=True) password = db.Column(db.String(255), nullable=False) fname = db.Column(db.String(32), nullable=False) lname = db.Column(db.String(32), nullable=False) is_email_confirmed = db.Column(db.Boolean, nullable=False, default=False) def __repr__(self): """Provide helpful representation when printed.""" return "<user {}: {} {} email={}>".format( self.user_id, self.fname, self.lname, self.email, ) def user_outgoing(self): """Return all distinct programs that are outgoing in ratios table.""" User.query.options(db.joinedload('balances')) outgoing = db.session.query(Ratio)\ .distinct(Ratio.outgoing_program)\ .join(Balance, Balance.program_id == Ratio.outgoing_program)\ .filter(Balance.user_id == self.user_id).all() return outgoing def user_outgoing_collection(self, program_id): """Return all distinct programs that are outgoing in ratios table in collection of instances.""" balance = self.get_balance_first(program_id) optimize = {"display_program": {}, "outgoing": {}} if balance: optimize["display_program"]["balance"] = balance.current_balance optimize["display_program"][ "program_name"] = balance.program.program_name else: optimize["display_program"]["balance"] = 0 optimize["display_program"]["program_name"] = Program.query.get( program_id).program_name outgoing = self.user_outgoing() if self.user_outgoing(): for program in outgoing: optimize["outgoing"][program.outgoing_program] = { "program_name": program.outgoing.program_name, "balance": self.get_balance(program.outgoing_program).current_balance } return optimize def user_receiving(self): """Return all distinct programs that are receiving in ratios table.""" receiving = db.session.query(Ratio)\ .distinct(Ratio.receiving_program)\ .join(Balance, Balance.program_id == Ratio.receiving_program)\ .filter(Balance.user_id == self.user_id).all() return receiving def user_receiving_for(self, outgoing_id): """Given an outgoing program, return all distinct programs that are receiving in ratios table.""" receiving = Ratio.query.filter(Ratio.outgoing_program == outgoing_id)\ .distinct(Ratio.receiving_program)\ .join(Balance, Balance.program_id == Ratio.receiving_program)\ .filter(Balance.user_id == self.user_id).all() return receiving def user_outgoing_for(self, receiving_id): """Given a receiving program, return all programs that are outgoing in ratios table.""" outgoing = db.session.query(Ratio)\ .join(Balance, Balance.program_id == Ratio.outgoing_program)\ .filter((Balance.user_id == self.user_id) & (Ratio.receiving_program == receiving_id))\ .all() return outgoing def get_balance(self, program_id): """Given a program id, return the balance instance""" balance = Balance.query.filter((Balance.user_id == self.user_id) & ( Balance.program_id == program_id)).one() return balance def add_transfer(self, outgoing_id, receiving_id, transfer_amount): """ Convenient transfer wrapper """ transfer = Transfer(user_id=self.user_id, outgoing_program=outgoing_id, receiving_program=receiving_id, outgoing_amount=transfer_amount) db.session.add(transfer) outgoing_program = self.get_balance(outgoing_id) receiving_program = self.get_balance(receiving_id) transfer_ratio = ratio_instance(outgoing_id, receiving_id).ratio_to() # Update balance for outgoing & receiving program in balances table outgoing_program.transferred_from(transfer_amount) receiving_program.transferred_to(transfer_amount, transfer_ratio) return transfer def delete_balance(self, program_id): """Given a program id, delete the balance instance""" balance = self.get_balance(program_id) db.session.delete(balance) db.session.commit() def program_balances(self): balances = db.session.query(Balance.program_id, Vendor.vendor_name, Program.program_name, Balance.updated_at, Balance.current_balance, Vendor.vendor_name)\ .join(Program)\ .join(Vendor)\ .filter(Balance.user_id == self.user_id).all() return balances def get_balances(self): base = Balance.query.filter_by(user_id=self.user_id).options( db.joinedload('program')) balances = base.all() return balances def get_balances_count(self): count = Balance.query.filter_by(user_id=self.user_id).options( db.joinedload('program')).count() return count def get_balance_first(self, program_id): """Given a program id, return the balance instance""" balance = Balance.query.filter((Balance.user_id == self.user_id) & ( Balance.program_id == program_id)).first() return balance def get_transactions(self): """ Return all transactions for a given user *activity.html """ transactions = TransactionHistory.query.options(db.joinedload('program'))\ .filter_by(user_id=self.user_id)\ .order_by('created_at DESC')\ .all() return transactions def get_transfers(self): """ Return all transactions for a given user *activity.html """ transfers = Transfer.query.filter_by(user_id=self.user_id)\ .join(Ratio, Ratio.outgoing_program == Transfer.outgoing_program)\ .order_by('transferred_at DESC')\ .all() return transfers def add_balance(self, program_id, current_balance): """ Convenient add_balance wrapper """ action_id = Action.query.filter( Action.action_type == 'New').one().action_id balance = Balance(user_id=self.user_id, program_id=program_id, current_balance=current_balance, action_id=action_id) db.session.add(balance) return balance @staticmethod def confirm_user(email): user = User.query.filter_by(email=email).first() user.is_email_confirmed = True db.session.add(user) db.session.commit()
class Coupon(db.Model): id = db.Column(db.Integer, primary_key=True) coupon_code = db.Column(db.String(28), unique=True, nullable=False) coupon_status = db.Column(db.String(20), nullable=False) bind_user_id = db.Column(db.String(20), nullable=True) expire_date = db.Column(db.String(8), nullable=False)
class Chat(db.Model): """Almacén clave/valor para un chat concreto Note: Si se quiere guardar un valor para todos los chats, usar el valor Id=0 El objetivo es poder guardar variables de estado de un chat (privado o grupo).Se almacena también la fecha de guardado o actualización. """ __tablename__ = 'chat' id = db.Column(db.Integer, primary_key=True) chat = db.Column(db.BigInteger, nullable=False) key = db.Column(db.String(255), nullable=False) value = db.Column(db.Text, nullable=False) created_at = db.Column(db.DateTime, nullable=False) @staticmethod def set_config(chat, key, value): """Guarda un valor Args: :param chat: Id. del chat :param key: Clave del dato :param value: Valor del dato Returns: :return: Instancia de Chat con el valor almacenado """ record = db.session.query(Chat).filter_by(chat=chat, key=key).first() if record is None: record = Chat(chat=chat, key=key, value=value, created_at=datetime.now()) db.session.add(record) else: record.value = value record.created_at = datetime.now() db.session.commit() db.session.close() return record @staticmethod def get_config(chat, key): """ Recupera un valor Args: :param chat: Id. del chat :param key: Clave del valor a recuperar Returns: :return: Instancia de Chat que coincide con la clave o None si no existe """ record = db.session.query(Chat).filter_by(chat=chat, key=key).first() db.session.close() return record @staticmethod def del_config(chat, key): """ Elimina un valor Args: :param chat: Id. del chat :param key: Clave del valor a eliminar Returns: :return: Nada """ record = db.session.query(Chat).filter_by(chat=chat, key=key).first() if record is not None: db.session.query(Chat).filter_by(chat=chat, key=key).delete() db.session.commit() db.session.close()
class Grado(db.Model): id = db.Column(db.Integer, primary_key=True) nombre = db.Column(db.String(50), unique=True, nullable=False) def __init__(self, nombre): self.nombre = nombre
class Notebook(db.Model): id = db.Column(db.Integer, primary_key=True) title = db.Column(db.String(100), nullable=False) notes = db.relationship("Note", cascade="all,delete", back_populates="notebook")