import uuid import re from sqlalchemy import Column, PickleType, Unicode, ForeignKey, Boolean, Table, UniqueConstraint, LargeBinary from sqlalchemy.ext.hybrid import hybrid_property from sqlalchemy.orm import relationship from soter.models import Base, DBSession from soter.models.guidtype import GUID def semantic_name(name): p = re.compile('([!\*’\(\);:@&=\+\$,/\?#\[\] ])') return p.sub('-', name) class DbSetting(Base): __tablename__ = 'settings' id = Column('id', GUID(), primary_key=True, default=uuid.uuid4) name = Column('name', Unicode(255), unique=True, nullable=False) data = Column('data', PickleType) def __init__(self, id=None, name=None, data=None): self.id = id self.name = name self.data = data @classmethod def by_id(cls, id): if not isinstance(id, uuid.UUID): id = uuid.UUID(id) return DBSession.query(cls).filter(cls.id == id).first() @classmethod def by_name(cls, name): return DBSession.query(cls).filter(cls.name == name).first() @classmethod def list(cls): return DBSession.query(cls).order_by(cls.name).all() picture_tag = Table( 'picture_tags', Base.metadata, Column('id', GUID(), primary_key=True, default=uuid.uuid4), Column('picture_id', GUID(), ForeignKey('pictures.id'), nullable=False), Column('tag_id', GUID(), ForeignKey('tags.id'), nullable=False), UniqueConstraint('picture_id', 'tag_id') ) picture_album = Table( 'picture_albums', Base.metadata, Column('id', GUID(), primary_key=True, default=uuid.uuid4), Column('picture_id', GUID(), ForeignKey('pictures.id'), nullable=False), Column('album_id', GUID(), ForeignKey('albums.id'), nullable=False), UniqueConstraint('picture_id', 'album_id') ) class Album(Base): __tablename__ = 'albums' id = Column('id', GUID(), primary_key=True, default=uuid.uuid4) _name = Column('name', Unicode(255), unique=True, nullable=False) semantic = Column('semantic', Unicode(255), unique=True, nullable=False) description = Column('description', Unicode(255)) user_id = Column('user_id', GUID(), ForeignKey('users.id'), nullable=False) is_fixture = Column('is_fixture', Boolean, nullable=False) is_public = Column('is_public', Boolean, nullable=False) user = relationship('User', primaryjoin="User.id==Album.user_id", cascade=None) @hybrid_property def name(self): return self._name @name.setter def name(self, name): self._name = name self.semantic = semantic_name(name) def __init__(self, name, description, user_id, is_public, id=None, is_fixture=False): self.name = name self.description = description self.user_id = user_id self.is_public = is_public self.id = id self.is_fixture = is_fixture @classmethod def list(cls): return DBSession.query(cls).order_by(cls.name) @classmethod def by_id(cls, id): if not isinstance(id, uuid.UUID): id = uuid.UUID(id) return DBSession.query(cls).filter(cls.id == id).first() @classmethod def by_name(cls, name): if not name: return None return DBSession.query(cls).filter(cls.name.ilike(name)).first() @classmethod def by_semantic(cls, semantic): if not semantic: return None return DBSession.query(cls).filter(cls.semantic.ilike(semantic)).first() @classmethod def no_album(cls): return uuid.UUID('1b209cd4-e04e-48ac-a1b0-ec5fdc85b492') @classmethod def semi(cls): return uuid.UUID('e6bf81b9-1e9b-499f-81d5-ab5662e9d9b1') class Picture(Base): __tablename__ = 'pictures' id = Column('id', GUID(), primary_key=True, default=uuid.uuid4) name = Column('name', Unicode(255), nullable=False) hash = Column('hash', LargeBinary(512), unique=True, nullable=False) user_id = Column('user_id', GUID(), ForeignKey('users.id'), nullable=False) is_public = Column('is_public', Boolean, nullable=False) tags = relationship("Tag", secondary=picture_tag) albums = relationship("Album", secondary=picture_album, backref='pictures') user = relationship('User', primaryjoin="User.id==Picture.user_id", cascade=None) def __init__(self, name, hash, user_id, is_public, id=None, is_fixture=False): self.name = name self.hash = hash self.user_id = user_id self.is_public = is_public self.id = id self.is_fixture = is_fixture @classmethod def list(cls): return DBSession.query(cls).order_by(cls.name) @classmethod def by_id(cls, id): if not isinstance(id, uuid.UUID): id = uuid.UUID(id) return DBSession.query(cls).filter(cls.id == id).first() @classmethod def menu_item(cls): return uuid.UUID('dad46805-f577-4e5b-8073-9b788e0173fc') @classmethod def semi(cls): return uuid.UUID('e6bf81b9-1e9b-499f-81d5-ab5662e9d9b1') class Tag(Base): __tablename__ = 'tags' id = Column('id', GUID(), primary_key=True, default=uuid.uuid4) name = Column('name', Unicode(100), unique=True, nullable=False) def __init__(self, name=None): self.name = name @classmethod def by_id(cls, id): return DBSession.query(cls).filter(cls.id == id).first() @classmethod def by_name(cls, name): return DBSession.query(cls).filter(cls.name == name).first() @classmethod def list(cls): return DBSession.query(cls).all() class Property(Base): __tablename__ = 'pic_properties' id = Column('id', GUID(), primary_key=True, default=uuid.uuid4) name = Column('name', Unicode(100), unique=True, nullable=False) def __init__(self, name=None): self.name = name @classmethod def by_id(cls, id): return DBSession.query(cls).filter(cls.id == id).first() @classmethod def by_name(cls, name): prop = DBSession.query(cls).filter(cls.name == name).first() if prop is None: prop = Property(name) DBSession.add(prop) return prop @classmethod def list(cls): return DBSession.query(cls).all() class PictureProperty(Base): __tablename__ = 'picture_properties' __table_args__ = (UniqueConstraint('picture_id', 'property_id'),) id = Column('id', GUID(), primary_key=True, default=uuid.uuid4) picture_id = Column('picture_id', GUID(), ForeignKey('pictures.id'), nullable=False) property_id = Column('property_id', GUID(), ForeignKey('pic_properties.id'), nullable=False) data = Column('data', PickleType, nullable=False) picture = relationship(Picture, backref="properties") property = relationship(Property, backref="pictures") def __init__(self, picture_id=None, property_id=None, picture=None, property=None, data=None): if picture_id is not None: self.picture_id = picture_id if property_id is not None: self.property_id = property_id if picture is not None: self.picture = picture if property is not None: self.property = property self.data = data