Merge remote-tracking branch 'refs/remotes/elrond/sql/media_data'

This commit is contained in:
Christopher Allan Webber 2013-02-09 15:33:06 -06:00
commit 591c116098
8 changed files with 48 additions and 29 deletions

View File

@ -20,7 +20,6 @@ TODO: indexes on foreignkeys, where useful.
import logging import logging
import datetime import datetime
import sys
from sqlalchemy import Column, Integer, Unicode, UnicodeText, DateTime, \ from sqlalchemy import Column, Integer, Unicode, UnicodeText, DateTime, \
Boolean, ForeignKey, UniqueConstraint, PrimaryKeyConstraint, \ Boolean, ForeignKey, UniqueConstraint, PrimaryKeyConstraint, \
@ -32,9 +31,10 @@ from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.util import memoized_property from sqlalchemy.util import memoized_property
from mediagoblin.db.extratypes import PathTupleWithSlashes, JSONEncoded from mediagoblin.db.extratypes import PathTupleWithSlashes, JSONEncoded
from mediagoblin.db.base import Base, DictReadAttrProxy, Session from mediagoblin.db.base import Base, DictReadAttrProxy
from mediagoblin.db.mixin import UserMixin, MediaEntryMixin, MediaCommentMixin, CollectionMixin, CollectionItemMixin from mediagoblin.db.mixin import UserMixin, MediaEntryMixin, MediaCommentMixin, CollectionMixin, CollectionItemMixin
from mediagoblin.tools.files import delete_media_files from mediagoblin.tools.files import delete_media_files
from mediagoblin.tools.common import import_component
# It's actually kind of annoying how sqlalchemy-migrate does this, if # It's actually kind of annoying how sqlalchemy-migrate does this, if
# I understand it right, but whatever. Anyway, don't remove this :P # I understand it right, but whatever. Anyway, don't remove this :P
@ -165,7 +165,6 @@ class MediaEntry(Base, MediaEntryMixin):
collections = association_proxy("collections_helper", "in_collection") collections = association_proxy("collections_helper", "in_collection")
## TODO ## TODO
# media_data
# fail_error # fail_error
def get_comments(self, ascending=False): def get_comments(self, ascending=False):
@ -195,40 +194,31 @@ class MediaEntry(Base, MediaEntryMixin):
if media is not None: if media is not None:
return media.url_for_self(urlgen) return media.url_for_self(urlgen)
#@memoized_property
@property @property
def media_data(self): def media_data(self):
session = Session() return getattr(self, self.media_data_ref)
return session.query(self.media_data_table).filter_by(
media_entry=self.id).first()
def media_data_init(self, **kwargs): def media_data_init(self, **kwargs):
""" """
Initialize or update the contents of a media entry's media_data row Initialize or update the contents of a media entry's media_data row
""" """
session = Session() media_data = self.media_data
media_data = session.query(self.media_data_table).filter_by(
media_entry=self.id).first()
# No media data, so actually add a new one
if media_data is None: if media_data is None:
media_data = self.media_data_table( # Get the correct table:
media_entry=self.id, table = import_component(self.media_type + '.models:DATA_MODEL')
**kwargs) # No media data, so actually add a new one
session.add(media_data) media_data = table(**kwargs)
# Update old media data # Get the relationship set up.
media_data.get_media_entry = self
else: else:
# Update old media data
for field, value in kwargs.iteritems(): for field, value in kwargs.iteritems():
setattr(media_data, field, value) setattr(media_data, field, value)
@memoized_property @memoized_property
def media_data_table(self): def media_data_ref(self):
# TODO: memoize this return import_component(self.media_type + '.models:BACKREF_NAME')
models_module = self.media_type + '.models'
__import__(models_module)
return sys.modules[models_module].DATA_MODEL
def __repr__(self): def __repr__(self):
safe_title = self.title.encode('ascii', 'replace') safe_title = self.title.encode('ascii', 'replace')

View File

@ -32,7 +32,8 @@ class AsciiData(Base):
media_entry = Column(Integer, ForeignKey('core__media_entries.id'), media_entry = Column(Integer, ForeignKey('core__media_entries.id'),
primary_key=True) primary_key=True)
get_media_entry = relationship("MediaEntry", get_media_entry = relationship("MediaEntry",
backref=backref(BACKREF_NAME, cascade="all, delete-orphan")) backref=backref(BACKREF_NAME, uselist=False,
cascade="all, delete-orphan"))
DATA_MODEL = AsciiData DATA_MODEL = AsciiData

View File

@ -32,7 +32,8 @@ class AudioData(Base):
media_entry = Column(Integer, ForeignKey('core__media_entries.id'), media_entry = Column(Integer, ForeignKey('core__media_entries.id'),
primary_key=True) primary_key=True)
get_media_entry = relationship("MediaEntry", get_media_entry = relationship("MediaEntry",
backref=backref(BACKREF_NAME, cascade="all, delete-orphan")) backref=backref(BACKREF_NAME, uselist=False,
cascade="all, delete-orphan"))
DATA_MODEL = AudioData DATA_MODEL = AudioData

View File

@ -33,7 +33,8 @@ class ImageData(Base):
media_entry = Column(Integer, ForeignKey('core__media_entries.id'), media_entry = Column(Integer, ForeignKey('core__media_entries.id'),
primary_key=True) primary_key=True)
get_media_entry = relationship("MediaEntry", get_media_entry = relationship("MediaEntry",
backref=backref(BACKREF_NAME, cascade="all, delete-orphan")) backref=backref(BACKREF_NAME, uselist=False,
cascade="all, delete-orphan"))
width = Column(Integer) width = Column(Integer)
height = Column(Integer) height = Column(Integer)

View File

@ -32,7 +32,8 @@ class StlData(Base):
media_entry = Column(Integer, ForeignKey('core__media_entries.id'), media_entry = Column(Integer, ForeignKey('core__media_entries.id'),
primary_key=True) primary_key=True)
get_media_entry = relationship("MediaEntry", get_media_entry = relationship("MediaEntry",
backref=backref(BACKREF_NAME, cascade="all, delete-orphan")) backref=backref(BACKREF_NAME, uselist=False,
cascade="all, delete-orphan"))
center_x = Column(Float) center_x = Column(Float)
center_y = Column(Float) center_y = Column(Float)

View File

@ -32,7 +32,8 @@ class VideoData(Base):
media_entry = Column(Integer, ForeignKey('core__media_entries.id'), media_entry = Column(Integer, ForeignKey('core__media_entries.id'),
primary_key=True) primary_key=True)
get_media_entry = relationship("MediaEntry", get_media_entry = relationship("MediaEntry",
backref=backref(BACKREF_NAME, cascade="all, delete-orphan")) backref=backref(BACKREF_NAME, uselist=False,
cascade="all, delete-orphan"))
width = Column(SmallInteger) width = Column(SmallInteger)
height = Column(SmallInteger) height = Column(SmallInteger)

View File

@ -17,7 +17,9 @@
# Maybe not every model needs a test, but some models have special # Maybe not every model needs a test, but some models have special
# methods, and so it makes sense to test them here. # methods, and so it makes sense to test them here.
from nose.tools import assert_equal
from mediagoblin.db.base import Session
from mediagoblin.db.models import MediaEntry from mediagoblin.db.models import MediaEntry
from mediagoblin.tests.tools import get_app, \ from mediagoblin.tests.tools import get_app, \
@ -128,3 +130,18 @@ class TestMediaEntrySlugs(object):
u"@!#?@!", save=False) u"@!#?@!", save=False)
qbert_entry.generate_slug() qbert_entry.generate_slug()
assert qbert_entry.slug is None assert qbert_entry.slug is None
def test_media_data_init():
Session.rollback()
Session.remove()
media = MediaEntry()
media.media_type = u"mediagoblin.media_types.image"
assert media.media_data is None
media.media_data_init()
assert media.media_data is not None
obj_in_session = 0
for obj in Session():
obj_in_session += 1
print repr(obj)
assert_equal(obj_in_session, 0)

View File

@ -27,6 +27,7 @@ from pkg_resources import resource_filename
from mediagoblin.tests.tools import get_app, \ from mediagoblin.tests.tools import get_app, \
fixture_add_user fixture_add_user
from mediagoblin import mg_globals from mediagoblin import mg_globals
from mediagoblin.db.models import MediaEntry
from mediagoblin.tools import template from mediagoblin.tools import template
from mediagoblin.media_types.image import MEDIA_MANAGER as img_MEDIA_MANAGER from mediagoblin.media_types.image import MEDIA_MANAGER as img_MEDIA_MANAGER
@ -40,6 +41,7 @@ EVIL_FILE = resource('evil')
EVIL_JPG = resource('evil.jpg') EVIL_JPG = resource('evil.jpg')
EVIL_PNG = resource('evil.png') EVIL_PNG = resource('evil.png')
BIG_BLUE = resource('bigblue.png') BIG_BLUE = resource('bigblue.png')
from .test_exif import GPS_JPG
GOOD_TAG_STRING = u'yin,yang' GOOD_TAG_STRING = u'yin,yang'
BAD_TAG_STRING = unicode('rage,' + 'f' * 26 + 'u' * 26) BAD_TAG_STRING = unicode('rage,' + 'f' * 26 + 'u' * 26)
@ -122,7 +124,7 @@ class TestSubmission:
self.check_normal_upload(u'Normal upload 2', GOOD_PNG) self.check_normal_upload(u'Normal upload 2', GOOD_PNG)
def check_media(self, request, find_data, count=None): def check_media(self, request, find_data, count=None):
media = request.db.MediaEntry.find(find_data) media = MediaEntry.find(find_data)
if count is not None: if count is not None:
assert_equal(media.count(), count) assert_equal(media.count(), count)
if count == 0: if count == 0:
@ -265,6 +267,11 @@ class TestSubmission:
# ------------------------------------------- # -------------------------------------------
self.check_false_image(u'Malicious Upload 3', EVIL_PNG) self.check_false_image(u'Malicious Upload 3', EVIL_PNG)
def test_media_data(self):
self.check_normal_upload(u"With GPS data", GPS_JPG)
media = self.check_media(None, {"title": u"With GPS data"}, 1)
assert_equal(media.media_data.gps_latitude, 59.336666666666666)
def test_processing(self): def test_processing(self):
data = {'title': u'Big Blue'} data = {'title': u'Big Blue'}
response, request = self.do_post(data, *REQUEST_CONTEXT, do_follow=True, response, request = self.do_post(data, *REQUEST_CONTEXT, do_follow=True,