class LinkMetadata(db.Model): __tablename__ = "linkmetadata" id = db.Column(db.Integer(), index=True, unique=True, primary_key=True, autoincrement=True) created = db.Column(db.DateTime, nullable=False, default=datetime.utcnow) text = db.Column(db.Text(), nullable=False) uuid = db.Column( UUIDType(binary=False)) # Poor hack so we can group them properly version = db.relationship("Version", back_populates="linkmetadata") version_id = db.Column(db.Integer, db.ForeignKey("version.id")) def __repr__(self): return "<linkmetadata: {}>".format(self.id) @recurse def to_json(self): j = OrderedDict() j["id"] = self.id j["text"] = self.text j["date"] = self.created j["versions"] = self.version.to_json() return j
class Version(db.Model): __tablename__ = "version" id = db.Column(db.Integer(), index=True, unique=True, primary_key=True, autoincrement=True) created = db.Column(db.DateTime, nullable=False, default=datetime.utcnow) version = db.Column(db.String(64), nullable=False) buildinfo = db.relationship("Buildinfo", back_populates="version") linkmetadata = db.relationship("LinkMetadata", back_populates="version") package_id = db.Column(db.Integer, db.ForeignKey("package.id")) package = db.relationship("Package", back_populates="version") def __repr__(self): return "<Version: {}>".format(self.version) @recurse def to_json(self): j = OrderedDict() j["id"] = self.id j["date"] = self.created j["version"] = self.version j["linkmetadata"] = list(map(lambda x: x.to_json(), self.linkmetadata)) j["buildinfo"] = list(map(lambda x: x.to_json(), self.buildinfo)) j["package"] = self.package.to_json() return j
class Package(db.Model): __tablename__ = "package" id = db.Column(db.Integer(), index=True, unique=True, primary_key=True, autoincrement=True) created = db.Column(db.DateTime, nullable=False, default=datetime.utcnow) name = db.Column(db.String(96), index=True, nullable=False) version = db.relationship("Version", back_populates="package") def __repr__(self): return "<Package: {}>".format(self.name) @recurse def to_json(self): j = OrderedDict() j["id"] = self.id j["date"] = self.created j["name"] = self.name j["versions"] = list(map(lambda x: x.to_json(), self.version)) return j
class Node(db.Model): __tablename__ = "node" id = db.Column(db.Integer(), index=True, unique=True, primary_key=True, autoincrement=True) leaf_index = db.Column(db.Integer(), default=0) type = db.Column(db.String(10), nullable=False) hash = db.Column(db.String(128)) signature = db.Column(db.String(128)) created = db.Column(db.DateTime, nullable=False, default=datetime.utcnow) data = db.Column(JSONB) height = db.Column(db.Integer(), default=0) children_right_id = db.Column(db.Integer, db.ForeignKey("node.id")) children_left_id = db.Column(db.Integer, db.ForeignKey("node.id")) right = db.relationship("Node", foreign_keys='Node.children_right_id', uselist=False, backref=db.backref('children_right', remote_side=[id])) left = db.relationship("Node", foreign_keys='Node.children_left_id', uselist=False, backref=db.backref('children_left', remote_side=[id])) children_id = db.Column(db.Integer, db.ForeignKey("node.id")) def is_type(self, type): return self.type == type def __str__(self): return f"<Node: {self.type} ({self.get_hash()})>" def __repr__(self): return self.__str__() def get_name(self): """ Internal function to generate graphviz """ return self.get_hash()[:10].upper() def is_left(self): if self.children_left: return self.children_left.left == self return False def is_right(self): if self.children_right: return self.children_right.right == self return False def get_child(self): if self.children_right: return self.children_right if self.children_left: return self.children_left def get_hash(self, new=None): if not self.hash or new: h = hashlib.sha512() h.update(self.type.encode('utf-8')) if self.data: for k, v in sorted(self.data.items()): h.update((k + v).encode('utf-8')) self.append_parents(h) self.hash = h.hexdigest() return self.hash def append_parents(self, h): if self.left: h.update(self.left.get_hash().encode('utf-8')) if self.right: h.update(self.right.get_hash().encode('utf-8')) return h @recurse def to_json(self): j = OrderedDict() j["id"] = self.id j["type"] = self.type j["created"] = self.created j["hash"] = self.get_hash() j["signature"] = self.signature j["height"] = self.height j["right"] = "" j["left"] = "" j["parent"] = "" j["data"] = {} if self.get_child(): j["parent"] = self.get_child().get_hash() if self.right: j["right"] = self.right.get_hash() if self.left: j["left"] = self.left.get_hash() if self.data: try: j["data"] = json.loads(self.data) except: j["data"] = self.data return j