class AppearanceTag(db.Model): """ This associates tags with Appearances of Things. Since a Thing already has tags, this also allows you to 'anti-tag' those things in specific appearances to prevent their usual tags from cascading in. """ __tablename__ = 'appearance_tag' appearance_id = db.Column('appearance_id', db.ForeignKey('appearance.id', ondelete='cascade'), primary_key=True) appearance = db.relationship('Appearance', backref=db.backref("taggings", passive_deletes='all')) tag_id = db.Column('tag_id', db.ForeignKey('tag.id', ondelete='cascade'), primary_key=True) tag = db.relationship('Tag', backref=db.backref("file_thing_relationships", passive_deletes='all')) negative = db.Column(db.Boolean, nullable=False, server_default='f')
class FileTag(db.Model): __tablename__ = 'file_tag' file_id = db.Column('file_id', db.ForeignKey('file.id', ondelete='cascade'), primary_key=True) file = db.relationship('File', backref=db.backref("tag_relationships", passive_deletes='all')) tag_id = db.Column('tag_id', db.ForeignKey('tag.id', ondelete='cascade'), primary_key=True) tag = db.relationship('Tag', backref=db.backref("file_relationships", passive_deletes='all'))
class FileThingRole(db.Model): __tablename__ = 'file_thing_role' file_id = db.Column('file_id', db.ForeignKey('file.id', ondelete='cascade'), primary_key=True) file = db.relationship('File', backref=db.backref("thing_roles", passive_deletes='all')) thing_id = db.Column('thing_id', db.ForeignKey('thing.id', ondelete='cascade'), primary_key=True) thing = db.relationship('Thing', backref=db.backref('file_roles', passive_deletes='all')) role_id = db.Column(db.ForeignKey('thing_role.id'), primary_key=True) role = db.relationship('ThingRole')
class Comment(db.Model): __tablename__ = 'comment' id = db.Column(db.Integer, primary_key=True) text = db.Column(db.String, nullable=False) parent_id = db.Column(db.ForeignKey('comment.id', ondelete='cascade')) # in reply to parent = db.relationship('Comment', remote_side=[id], backref=db.backref('replies', passive_deletes='all')) # what it's related to. Only one may be populated file_id = db.Column(db.ForeignKey('file.id', ondelete='cascade'), nullable=False) # nullability will change created_at = db.Column(ArrowType, nullable=False, server_default=db.text("timezone('utc',now())")) file = db.relationship('File', backref=db.backref('comments', passive_deletes='all', order_by=created_at.desc()))
class ThingTag(db.Model): __tablename__ = 'thing_tag' tag_id = db.Column('tag_id', db.ForeignKey('tag.id', ondelete='cascade'), primary_key=True) tag = db.relationship('Tag', backref=db.backref('thing_relationships', passive_deletes='all')) thing_id = db.Column('thing_id', db.ForeignKey('thing.id', ondelete='cascade'), primary_key=True) thing = db.relationship('Thing', backref=db.backref('tag_relationships', passive_deletes='all'))
class Appearance(db.Model): """ An appearance of a Thing in a File. The Thing doesn't have to be specified though. You can tag an appearance on its own, before the Thing it concerns is identified. """ __tablename__ = 'appearance' id = db.Column(db.Integer, primary_key=True) # required file_id = db.Column('file_id', db.ForeignKey('file.id', ondelete='cascade'), nullable=False) file = db.relationship('File', backref=db.backref('appearances', passive_deletes='all')) # optional thing_id = db.Column('thing_id', db.ForeignKey('thing.id', ondelete='cascade')) thing = db.relationship('Thing', backref=db.backref('appearances', passive_deletes='all')) # where is it position_x = db.Column(db.Integer, nullable=False) position_y = db.Column(db.Integer, nullable=False) size_x = db.Column(db.Integer, nullable=False) size_y = db.Column(db.Integer, nullable=False) @property def tag_names(self): return set([ tagging.tag.name for tagging in self.taggings if not tagging.negative ]) @property def negative_tag_names(self): return set([ tagging.tag.name for tagging in self.taggings if tagging.negative ]) @property def thing_name(self): if self.thing: return self.thing.name @property def position(self): return dict( x=self.position_x, y=self.position_y, ) @position.setter def position(self, value): self.position_x = value['x'] self.position_y = value['y'] @property def size(self): return dict( x=self.size_x, y=self.size_y, ) @size.setter def size(self, value): self.size_x = value['x'] self.size_y = value['y'] @property def dimensions(self): return dict( position=self.position, size=self.size, ) @dimensions.setter def dimensions(self, value): self.position = value['position'] self.size = value['size']