aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--mediagoblin/db/sql/base.py16
-rw-r--r--mediagoblin/db/sql/models.py40
-rw-r--r--mediagoblin/edit/views.py2
-rw-r--r--mediagoblin/submit/views.py2
4 files changed, 54 insertions, 6 deletions
diff --git a/mediagoblin/db/sql/base.py b/mediagoblin/db/sql/base.py
index 1db53c56..f1affc83 100644
--- a/mediagoblin/db/sql/base.py
+++ b/mediagoblin/db/sql/base.py
@@ -77,3 +77,19 @@ class GMGTableBase(object):
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))
diff --git a/mediagoblin/db/sql/models.py b/mediagoblin/db/sql/models.py
index 6232fff8..9abd8ec7 100644
--- a/mediagoblin/db/sql/models.py
+++ b/mediagoblin/db/sql/models.py
@@ -26,7 +26,7 @@ from sqlalchemy.sql.expression import desc
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
@@ -101,6 +101,13 @@ class MediaEntry(Base, 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
@@ -153,22 +160,47 @@ class Tag(Base):
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"
diff --git a/mediagoblin/edit/views.py b/mediagoblin/edit/views.py
index cf7182e5..a637d699 100644
--- a/mediagoblin/edit/views.py
+++ b/mediagoblin/edit/views.py
@@ -69,7 +69,7 @@ def edit_media(request, media):
else:
media.title = unicode(request.POST['title'])
media.description = unicode(request.POST.get('description'))
- media['tags'] = convert_to_tag_list_of_dicts(
+ media.tags = convert_to_tag_list_of_dicts(
request.POST.get('tags'))
media.description_html = cleaned_markdown_conversion(
diff --git a/mediagoblin/submit/views.py b/mediagoblin/submit/views.py
index f70e4ba5..0efee803 100644
--- a/mediagoblin/submit/views.py
+++ b/mediagoblin/submit/views.py
@@ -74,7 +74,7 @@ def submit_start(request):
entry.uploader = request.user._id
# Process the user's folksonomy "tags"
- entry['tags'] = convert_to_tag_list_of_dicts(
+ entry.tags = convert_to_tag_list_of_dicts(
request.POST.get('tags'))
# Generate a slug from the title