Base = declarative_base(cls=GMGTableBase)
+
+
+class DictReadAttrProxy(object):
+ """
+ Maps read accesses to obj['key'] to obj.key
+ and hides all the rest of the obj
+ """
+ def __init__(self, proxied_obj):
+ self.proxied_obj = proxied_obj
+
+ def __getitem__(self, key):
+ try:
+ return getattr(self.proxied_obj, key)
+ except AttributeError:
+ raise KeyError("%r is not an attribute on %r"
+ % (key, self.proxied_obj))
from sqlalchemy.ext.associationproxy import association_proxy
from mediagoblin.db.sql.extratypes import PathTupleWithSlashes
-from mediagoblin.db.sql.base import Base
+from mediagoblin.db.sql.base import Base, DictReadAttrProxy
from mediagoblin.db.mixin import UserMixin, MediaEntryMixin
creator=lambda k, v: MediaFile(name=k, file_path=v)
)
+ tags_helper = relationship("MediaTag",
+ cascade="all, delete-orphan"
+ )
+ tags = association_proxy("tags_helper", "dict_view",
+ creator=lambda v: MediaTag(name=v["name"], slug=v["slug"])
+ )
+
## TODO
# media_data
# attachment_files
id = Column(Integer, primary_key=True)
slug = Column(Unicode, nullable=False, unique=True)
+ def __repr__(self):
+ return "<Tag %r: %r>" % (self.id, self.slug)
+
+ @classmethod
+ def find_or_new(cls, slug):
+ t = cls.query.filter_by(slug=slug).first()
+ if t is not None:
+ return t
+ return cls(slug=slug)
+
class MediaTag(Base):
__tablename__ = "media_tags"
id = Column(Integer, primary_key=True)
- tag = Column(Integer, ForeignKey('tags.id'), nullable=False)
- name = Column(Unicode)
media_entry = Column(
- Integer, ForeignKey('media_entries.id'),
+ Integer, ForeignKey(MediaEntry.id),
nullable=False)
+ tag = Column(Integer, ForeignKey('tags.id'), nullable=False)
+ name = Column(Unicode)
# created = Column(DateTime, nullable=False, default=datetime.datetime.now)
__table_args__ = (
UniqueConstraint('tag', 'media_entry'),
{})
+ tag_helper = relationship(Tag)
+ slug = association_proxy('tag_helper', 'slug',
+ creator=Tag.find_or_new
+ )
+
+ def __init__(self, name, slug):
+ Base.__init__(self)
+ self.name = name
+ self.tag_helper = Tag.find_or_new(slug)
+
+ @property
+ def dict_view(self):
+ """A dict like view on this object"""
+ return DictReadAttrProxy(self)
+
class MediaComment(Base):
__tablename__ = "media_comments"