class Article(CustomModelMixin, Model): __tablename__ = 'articles' title = Column(db.String(100), nullable=False) slug = Column(db.String(100), nullable=False, unique=True) summary = Column(db.Text(), nullable=False) image = Column(db.Text, nullable=True) content = Column(db.Text, nullable=False) is_published = Column(db.Boolean, default=True) view_count = Column(db.Integer, default=0) created_by_id = reference_col("user", nullable=True) date_created = Column(db.DateTime, nullable=False, default=dt.datetime.utcnow) tags = relationship("Tag", secondary=articles_tags, backref='posts') created_by = relationship("User") def __repr__(self): """Represent instance as a string.""" return self.title def publish(self): self.is_published = True return self.save() def archive(self): self.is_published = False return self.save()
class HoneymoonFund(CustomModelMixin, Model): __tablename__ = 'honeymoon_funds' registry_id = reference_col("registries", nullable=False) message = Column(db.Text, nullable=True) target_amount = Column(db.Float, nullable=True) has_achieved_target = Column(db.Boolean, default=False) date_target_achieved = Column(db.DateTime, nullable=True) has_been_paid = Column(db.Boolean, default=False) date_paid_status_updated = Column(db.DateTime, nullable=True) admin_updated_id = reference_col("user", nullable=True) admin_updated_by = relationship("User") registry = relationship("Registry", backref=backref('fund', uselist=False), uselist=False) def __str__(self): return self.registry.name @staticmethod def format_price(price): return "NGN{:,.2f}".format(price) @property def amount_donated(self): return 99800
class Product(CustomModelMixin, Model): __tablename__ = 'products' name = Column(db.String(100), nullable=False) slug = Column(db.String(100), nullable=False, unique=True) category_id = reference_col("categories", nullable=False) description = Column(db.Text, nullable=False) sku = Column(db.String(50), nullable=True) price = Column(db.Float, nullable=False) is_available = Column(db.Boolean, default=True) created_by_id = reference_col("user", nullable=True) date_created = Column(db.DateTime, nullable=False, default=dt.datetime.utcnow) created_by = relationship("User") category = relationship("Category") products_in_registry = relationship("Registry", secondary="registry_products") def __repr__(self): """Represent instance as a string.""" return self.name @property def display_price(self): return "NGN{:,.2f}".format(self.price) def total_price(self, quantity): return self.price * quantity def display_total_price(self, quantity): return "NGN{:,.2f}".format(self.total_price(quantity)) @property def main_image(self): if self.images: for i in self.images: if i.is_main_image: return i return self.images[0] return @property def available_text(self): if self.is_available: return "In stock" return "Out of stock" @property def to_json(self): return { 'name': self.name, 'slug': self.slug, 'description': self.description, 'image': self.main_image.get_url }
class Donation(CustomModelMixin, Model): __tablename__ = 'donations' transaction_id = reference_col("transactions", nullable=False) registry_id = reference_col("wedding_registries", nullable=False) amount = Column(db.Float, nullable=False) date_created = Column(db.DateTime, nullable=False, default=dt.datetime.utcnow) registry = relationship("WeddingRegistry", backref=backref("donations", uselist=True)) transaction = relationship("Transaction", backref=backref("donations", uselist=True))
class BirthdayRegistry(HasOrders, HasProducts, HasAddress, RegistryBase): __tablename__ = 'birthday_registries' first_name = Column(db.String(100), nullable=False) last_name = Column(db.String(100), nullable=False) hashtag = Column(db.String(50), nullable=True) message = Column(db.Text, nullable=True) image = Column(db.Text, nullable=True) admin_created_id = relationship("User") created_by = relationship("User", backref="birthdays", primaryjoin="BirthdayRegistry.created_by_id==User.id") @property def url(self): return "{}registry/birthdays/{}".format(request.url_root, self.slug) def __str__(self): return self.name @property def name(self): return f"{self.first_name}'s Birthday" @property def image_url(self): if self.image: return True return 'img/random/default_birthday.jpg' @classmethod def search(cls, term): return cls.query.filter(cls.is_active.is_(True)).\ filter((cls.first_name.ilike(term)) | (cls.last_name.ilike(term)) | (cls.hashtag.ilike(term)) | (cls.slug.ilike(term))) def unique_slug(self, slug): if self.query.filter_by(slug=slug).first(): return f"{slug}-{str(uuid.uuid4()).split('-')[0]}" return False def generate_hashtag(self): # check if hashtag has been provided if not self.hashtag: # if not self.hashtag = f'#{self.first_name.title()}{str(self.event_date.year)}' # check if first letter is hashtag if self.hashtag[0] != '#': self.hashtag = f'#{self.hashtag}' def generate_slug(self): # strip hashtag slug = self.hashtag[1:] # check if exists in database check = self.unique_slug(slug) # if it exists, add uuid self.slug = check.lower() if check else slug.lower()
class OrderItem(CustomModelMixin, Model): __tablename__ = 'order_items' order_id = reference_col("orders", nullable=False) reg_product_id = reference_col("registry_products", nullable=False) quantity = Column(db.Integer, default=1) unit_price = Column(db.Float, nullable=False) total_price = Column(db.Float, nullable=False) order = relationship("Order") registry_product = relationship("RegistryProducts")
class ProductBundleItem(CustomModelMixin, Model): __tablename__ = 'product_bundle_items' name = Column(db.Text, nullable=False) product_id = reference_col("products", nullable=False) product = relationship("Product", backref="items")
class Label(Model, CRUDMixin): __tablename__ = "labels" id = Column(Integer, primary_key=True) text = Column(String(250)) videoid = Column(Integer, ForeignKey(Video.id)) video = relationship(Video, backref=backref("labels", cascade="all,delete"))
class Quotation(db.Base): """ Class of a quotation object (security [e.g. stock or index] information on a given date) """ __tablename__ = 'quotations' id = db.Column(db.Integer, primary_key=True, autoincrement=True) date = db.Column(db.DateTime) open = db.Column(db.Numeric(10, 2)) high = db.Column(db.Numeric(10, 2)) low = db.Column(db.Numeric(10, 2)) close = db.Column(db.Numeric(10, 2)) adj_close = db.Column(db.Numeric(10, 2)) volume = db.Column(db.Numeric(10, 2)) created_date = db.Column(db.DateTime) last_updated = db.Column(db.DateTime) data_vendor_id = db.Column(db.Integer, db.ForeignKey('datavendor.id')) data_vendor = db.relationship('DataVendor', backref='datavendor') security_id = db.Column(db.Integer, db.ForeignKey('security.id')) security = db.relationship('Security', backref='security') @classmethod def get_dataframe(cls, symbol): """ Get Pandas Dataframe of quotations for given symbol Args: symbol (string): Symbol of security (e.g. "^DJI") Returns: Panadas dataframe with quotation data None in case of error """ return_df = None # Get security object for given symbol security = db_session.query(Security).filter_by(symbol=symbol).first() if security is not None: # Get quotation data for symbol as dataframe t = sa.Table(cls.__tablename__, sa.MetaData(), autoload_with=db_engine) return_df = pd.read_sql(t.select().where(t.c.security_id == security.id), db_engine) return return_df def __repr__(self): return (str(self.date) + ": " + str(self.adj_close) + "(" + str(self.volume) + ")" + " Created: " + str(self.created_date))
class User(UserMixin, Model, CRUDMixin): __tablename__ = "users" id = Column(db.Integer, primary_key = True) username = Column(db.String(250), index = True) password = Column(db.String(250)) # one to many videos = relationship('Video', backref='users') # one to many classifiers = relationship('Classifier', backref='users') def get_id(self): return self.id def check_password(self, password): return self.password == password
class RegistryProducts(CustomModelMixin, Model): __tablename__ = 'registry_products' registry_id = reference_col("registries", nullable=False) product_id = reference_col("products", nullable=False) has_been_purchased = Column(db.Boolean, default=False) # product = relationship("Product", backref="registry_products", uselist=False) registry = relationship("Registry", backref=backref("registry_products", cascade="all, delete-orphan")) product = relationship("Product", backref=backref("registry_products", cascade="all, delete-orphan")) def __str__(self): return self.product.name
class AttributeAnnotation(Model, CRUDMixin): __tablename__ = "attribute_annotations" id = Column(Integer, primary_key=True) pathid = Column(Integer, ForeignKey(Path.id)) path = relationship(Path, backref=backref("attributes", cascade="all,delete")) attributeid = Column(Integer, ForeignKey(Attribute.id)) attribute = relationship(Attribute) frame = Column(Integer) value = Column(Boolean, default=False) def __repr__(self): return ("AttributeAnnotation(pathid = {0}, " "attributeid = {1}, " "frame = {2}, " "value = {3})").format(self.pathid, self.attributeid, self.frame, self.value)
class Order(CustomModelMixin, Model): __tablename__ = 'orders' order_number = Column(db.String(255), unique=True) transaction_id = reference_col("transactions", nullable=False) registry_id = reference_col("registries", nullable=False) status = Column(ChoiceType(STATUS, impl=db.String())) date_created = Column(db.DateTime, nullable=False, default=dt.datetime.utcnow) registry = relationship("Registry", backref=backref("orders", uselist=True)) transaction = relationship("Transaction", backref=backref("orders", uselist=True)) def generate_order_number(self): self.order_number = f"ORD{dt.date.today().strftime('%Y%m%d')}00000{self.id}"
class Classifier(Model, CRUDMixin): __tablename__ = "classifiers" id = Column(db.Integer, primary_key = True) name = Column(db.String(250)) owner_id = Column(db.Integer, db.ForeignKey("users.id")) # many to many videos = relationship("Video", secondary=video_classifier_association_table, backref='classifiers') # it's stored as string array, since there is no reference need labels = Column(db.String(250)) # one to many children = relationship("Classifier") parent_id = Column(db.Integer, db.ForeignKey("classifiers.id")) # training images training_image_list_file_path = Column(db.String(550)) training_label_list_file_path = Column(db.String(550)) training_label_name_file_path = Column(db.String(550)) epoch = Column(db.Integer, default=0) # a string to indicate the network type: ['Fast_RCNN', 'mxnet'] network_type = Column(db.String(250)) # the name of model, specified by the user model_name = Column(db.String(250)) # training status: [(0, none), (1, waiting), (2, training), (3, finished)] task_id = Column(db.String(250)) # the type of the task: [train, test] task_type = Column(db.String(250)) training_status = Column(db.Integer, default=0) training_start_time = Column(db.BigInteger) training_end_time = Column(db.BigInteger) # many to many evaluation_sets = relationship("EvaluationSet", secondary=classifier_evaluation_association_table, back_populates='classifiers') container_id = Column(db.String(250)) image_id = Column(db.String(250))
class Allocation(db.BaseModel): __tablename__ = 'allocation' id = db.Column('allocation_id', db.Integer, primary_key=True) name = db.Column('name', db.String) target = db.Column('target', db.Float, nullable=False, default=0.0) assets = db.relationship('Asset', secondary='assetAllocationRelationship', lazy='joined')
class Asset(db.BaseModel): __tablename__ = 'assets' id = db.Column('ticker', db.String, primary_key=True) name = db.Column('name', db.String) shares = db.Column('shares', db.Float, default=0, nullable=False) is_active = db.Column('is_active', db.Boolean, default=True) allocation = db.relationship('Allocation', secondary='assetAllocationRelationship', uselist=False)
class Attribute(Model, CRUDMixin): __tablename__ = "attributes" id = Column(Integer, primary_key=True) text = Column(String(250)) labelid = Column(Integer, ForeignKey(Label.id)) label = relationship(Label, backref=backref("attributes", cascade="all,delete")) def __str__(self): return self.text
class Category(CustomModelMixin, Model): __tablename__ = 'categories' name = Column(db.String(100), nullable=False, unique=True) slug = Column(db.String(100), nullable=False, unique=True) created_by_id = reference_col("user", nullable=True) date_created = Column(db.DateTime, nullable=False, default=dt.datetime.utcnow) created_by = relationship("User") def __repr__(self): """Represent instance as a string.""" return self.name
class EvaluationSet(Model, CRUDMixin): __tablename__ = "evaluation_sets" id = Column(db.Integer, primary_key = True) name = Column(db.String(250), index = True) # many to many videos = relationship('Video', secondary=video_evaluation_association_table, back_populates='evaluation_sets') # classifier_id = Column(Integer, ForeignKey("classifiers.id")) classifiers = relationship('Classifier', secondary=classifier_evaluation_association_table, back_populates='evaluation_sets') prediction_result_file_path = Column(db.String(550)) roc_graph_file_path = Column(db.String(550)) @property def roc_dir(self): return os.path.join(config.IMG_PATH, str(self.id)) @property def eval_dir(self): return os.path.join(config.EVALUATION_PATH, str(self.id))
class User(db.Model): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) username = db.Column(db.String, unique=True, nullable=False) email = db.Column(db.String, unique=True, nullable=False) password_hash = db.Column(db.String, nullable=False) api_key = db.Column(db.String, nullable=False) corpus = relationship(Corpus, backref=db.backref('user')) def __repr__(self): # pragma: nocover return '<User({username!r})>'.format(username=self.username)
class RegistryDeliveryAddress(CustomModelMixin, Model): __tablename__ = 'registry_delivery_addresses' registry_id = reference_col("registries", nullable=False) name = Column(db.String(100), nullable=False) phone_number = db.Column(db.String(50), nullable=True) address = Column(db.Text, nullable=False) city = Column(db.String(50), nullable=False) state = Column(db.String(50), nullable=False) registry = relationship("Registry", backref=backref("delivery", uselist=False, cascade="all, delete-orphan"))
class Role(PkModel): """A role for a user.""" __tablename__ = "roles" name = Column(db.String(80), unique=True, nullable=False) user_id = reference_col("users", nullable=True) user = relationship("User", backref="roles") def __init__(self, name, **kwargs): """Create instance.""" super().__init__(name=name, **kwargs) def __repr__(self): """Represent instance as a unique string.""" return f"<Role({self.name})>"
class ProductImage(CustomModelMixin, Model): __tablename__ = 'product_images' name = Column(db.Text, nullable=False) product_id = reference_col("products", nullable=False) is_main_image = Column(db.Boolean, default=False) date_created = Column(db.DateTime, nullable=False, default=dt.datetime.utcnow) product = relationship("Product", backref="images") @property def get_url(self): return self.name def __repr__(self): """Represent instance as a string.""" return self.name
class Tag(CustomModelMixin, Model): __tablename__ = 'tags' name = Column(db.String(50), nullable=False, unique=True) slug = Column(db.String(50), nullable=False) created_by_id = reference_col("user", nullable=True) date_created = Column(db.DateTime, nullable=False, default=dt.datetime.utcnow) created_by = relationship("User") @classmethod def get_popular_tags(cls, limit=4): return cls.query.limit(limit) def __repr__(self): """Represent instance as a string.""" return self.name
class Transaction(CustomModelMixin, Model): __tablename__ = 'transactions' txn_no = Column(db.String(255), unique=True) first_name = db.Column(db.String(255)) last_name = db.Column(db.String(255)) phone_number = db.Column(db.String(50), nullable=True) email = db.Column(db.String(255)) message = Column(db.Text, nullable=True) # valid types are order and donation type = Column(db.String(255)) payment_status = Column(ChoiceType(PAYMENT_STATUS, impl=db.String())) total_amount = Column(db.Float, nullable=False) discounted_amount = Column(db.Float, nullable=True) discount_id = reference_col("discounts", nullable=True) date_created = Column(db.DateTime, nullable=False, default=dt.datetime.utcnow) date_paid = Column(db.DateTime, nullable=True) payment_txn_number = Column(db.String(255), nullable=True) discount = relationship("Discount") def generate_txn_number(self): self.txn_no = f"TXN{dt.date.today().strftime('%Y%m%d')}00000{self.id}" @property def get_amount_paid(self): return self.discounted_amount if self.discounted_amount else self.total_amount @property def full_name(self): return f'{self.first_name} {self.last_name}' @property def get_items(self): if self.type == 'order': return self.orders return self.donations def __str__(self): return self.txn_no
class Discount(CustomModelMixin, Model): __tablename__ = 'discounts' code = Column(db.String(50), nullable=False, unique=True) amount = Column(db.Float, nullable=True) percentage = Column(db.Float, nullable=True) is_active = Column(db.Boolean, default=True) created_by_id = reference_col("user", nullable=True) date_created = Column(db.DateTime, nullable=False, default=dt.datetime.utcnow) created_by = relationship("User") def __repr__(self): """Represent instance as a string.""" return self.code def get_discount_amount(self, price): if self.amount: return self.amount return (self.percentage/100) * price
class Box(Model, CRUDMixin): __tablename__ = "boxes" id = Column(Integer, primary_key=True) pathid = Column(Integer, ForeignKey(Path.id)) path = relationship(Path, backref=backref("boxes", cascade="all,delete")) xtl = Column(Integer) ytl = Column(Integer) xbr = Column(Integer) ybr = Column(Integer) frame = Column(Integer) occluded = Column(Boolean, default=False) outside = Column(Boolean, default=False) generated = Column(Boolean, default=False) def frombox(self, box): self.xtl = box.xtl self.xbr = box.xbr self.ytl = box.ytl self.ybr = box.ybr self.frame = box.frame self.occluded = box.occluded self.outside = box.lost self.generated = box.generated def getbox(self): vb = vision.Box(self.xtl, self.ytl, self.xbr, self.ybr, self.frame, self.outside, self.occluded, 0, generated=self.generated) # print 'frame id: {}, generated: {}'.format(vb.frame, vb.generated) return vb
class Segment(Model, CRUDMixin): __tablename__ = "segments" id = Column(Integer, primary_key=True) videoid = Column(Integer, ForeignKey(Video.id)) video = relationship(Video, backref=backref("segments", cascade="all,delete")) start = Column(Integer) stop = Column(Integer) @property def paths(self): paths = [] for job in self.jobs: if job.useful: paths.extend(job.paths) return paths @property def cost(self): cost = 0 for job in self.jobs: cost += job.cost return cost
class Video(Model, CRUDMixin): __tablename__ = "videos" id = Column(Integer, primary_key=True) slug = Column(String(250), index=True) width = Column(Integer) height = Column(Integer) totalframes = Column(Integer) location = Column(String(250)) skip = Column(Integer, default=0, nullable=False) perobjectbonus = Column(Float, default=0) completionbonus = Column(Float, default=0) trainwithid = Column(Integer, ForeignKey(id)) trainwith = relationship("Video", remote_side=id) isfortraining = Column(Boolean, default=False) blowradius = Column(Integer, default=5) homographylocation = Column(String(250), nullable=True, default=None) pointmode = Column(Boolean, default=False) orig_file_path = Column(String(550)) extract_path = Column(String(550)) # many to one owner_id = Column(Integer, ForeignKey("users.id")) # many to many # classifier_id = Column(Integer, ForeignKey("classifiers.id")) # many to many evaluation_sets = relationship( "EvaluationSet", secondary=video_evaluation_association_table, back_populates='videos') def __getitem__(self, frame): path = Video.getframepath(frame, self.location) return Image.open(path) @classmethod def getframepath(cls, frame, base=None): l1 = frame / 10000 l2 = frame / 100 path = "{0}/{1}/{2}.jpg".format(l1, l2, frame) if base is not None: path = "{0}/{1}".format(base, path) return path @property def cost(self): cost = 0 for segment in self.segments: cost += segment.cost return cost @property def numjobs(self): count = 0 for segment in self.segments: for job in segment.jobs: count += 1 return count @property def numcompleted(self): count = 0 for segment in self.segments: for job in segment.jobs: if job.completed: count += 1 return count def gethomography(self): if self.homographylocation is not None: path = os.path.join(self.homographylocation, "homography.npy") if os.path.exists(path): return np.load(path) return None def nextid(self): userids = [ path.userid for segment in self.segments for path in segment.paths ] if len(userids) == 0: return 0 return max(userids) + 1 def getsegmentneighbors(self, segment): start, stop = segment.start, segment.stop prevseg, nextseg = None, None for seg in self.segments: if start <= seg.stop < stop: prevseg = seg elif start < seg.start <= stop: nextseg = seg return prevseg, nextseg
class Path(Model, CRUDMixin): __tablename__ = "paths" id = Column(Integer, primary_key=True) jobid = Column(Integer, ForeignKey(Job.id)) job = relationship(Job, backref=backref("paths", cascade="all,delete")) labelid = Column(Integer, ForeignKey(Label.id)) label = relationship(Label, cascade="none", backref="paths") userid = Column(Integer, default=0) done = Column(Boolean, default=False) interpolatecache = None def getboxes(self, interpolate=False, bind=False, label=False, groundplane=False): result = [x.getbox() for x in self.boxes] result.sort(key=lambda x: x.frame) if groundplane: homography = None with open( os.path.join(self.job.segment.video.homographylocation, "homography.npy"), "r") as f: homography = np.load(f) for i in range(len(result)): t = homography.dot(np.array([result[i].xbr, result[i].ybr, 1])) result[i].xbr = float(t[0]) / t[2] result[i].ybr = float(t[1]) / t[2] result[i].xtl = result[i].xbr - 5 result[i].ytl = result[i].ybr - 5 if interpolate: if not self.interpolatecache: self.interpolatecache = LinearFill(result) result = self.interpolatecache if bind: result = Path.bindattributes(self.attributes, result) if label: for box in result: box.attributes.insert(0, self.label.text) return result @classmethod def bindattributes(cls, attributes, boxes): attributes = sorted(attributes, key=lambda x: x.frame) byid = {} for attribute in attributes: if attribute.attributeid not in byid: byid[attribute.attributeid] = [] byid[attribute.attributeid].append(attribute) for attributes in byid.values(): for prev, cur in zip(attributes, attributes[1:]): if prev.value: for box in boxes: if prev.frame <= box.frame < cur.frame: if prev.attribute not in box.attributes: box.attributes.append(prev.attribute) last = attributes[-1] if last.value: for box in boxes: if last.frame <= box.frame: if last.attribute not in box.attributes: box.attributes.append(last.attribute) return boxes def __repr__(self): return "<Path {0}>".format(self.id)