"""
import uuid
+import re
+from datetime import datetime
from werkzeug.utils import cached_property
from mediagoblin import mg_globals
-from mediagoblin.auth import lib as auth_lib
-from mediagoblin.media_types import get_media_managers, FileTypeNotSupported
+from mediagoblin.media_types import FileTypeNotSupported
from mediagoblin.tools import common, licenses
+from mediagoblin.tools.pluginapi import hook_handle
from mediagoblin.tools.text import cleaned_markdown_conversion
from mediagoblin.tools.url import slugify
class UserMixin(object):
- def check_login(self, password):
- """
- See if a user can login with this password
- """
- return auth_lib.bcrypt_check_password(
- password, self.pw_hash)
-
@property
def bio_html(self):
return cleaned_markdown_conversion(self.bio)
+ def url_for_self(self, urlgen, **kwargs):
+ """Generate a URL for this User's home page."""
+ return urlgen('mediagoblin.user_pages.user_home',
+ user=self.username, **kwargs)
+
+
+class GenerateSlugMixin(object):
+ """
+ Mixin to add a generate_slug method to objects.
-class MediaEntryMixin(object):
+ Depends on:
+ - self.slug
+ - self.title
+ - self.check_slug_used(new_slug)
+ """
def generate_slug(self):
"""
- Generate a unique slug for this MediaEntry.
+ Generate a unique slug for this object.
This one does not *force* slugs, but usually it will probably result
in a niceish one.
generated bits until it's unique. That'll be a little bit of junk,
but at least it has the basis of a nice slug.
"""
- # import this here due to a cyclic import issue
- # (db.models -> db.mixin -> db.util -> db.models)
- from mediagoblin.db.util import check_media_slug_used
-
#Is already a slug assigned? Check if it is valid
if self.slug:
self.slug = slugify(self.slug)
return # giving up!
# Otherwise, let's see if this is unique.
- if check_media_slug_used(self.uploader, self.slug, self.id):
+ if self.check_slug_used(self.slug):
# It looks like it's being used... lame.
# Can we just append the object's id to the end?
if self.id:
slug_with_id = u"%s-%s" % (self.slug, self.id)
- if not check_media_slug_used(self.uploader,
- slug_with_id, self.id):
+ if not self.check_slug_used(slug_with_id):
self.slug = slug_with_id
return # success!
# let's whack junk on there till it's unique.
self.slug += '-' + uuid.uuid4().hex[:4]
# keep going if necessary!
- while check_media_slug_used(self.uploader, self.slug, self.id):
+ while self.check_slug_used(self.slug):
self.slug += uuid.uuid4().hex[:4]
+
+class MediaEntryMixin(GenerateSlugMixin):
+ def check_slug_used(self, slug):
+ # import this here due to a cyclic import issue
+ # (db.models -> db.mixin -> db.util -> db.models)
+ from mediagoblin.db.util import check_media_slug_used
+
+ return check_media_slug_used(self.uploader, slug, self.id)
+
@property
def description_html(self):
"""
or, if not found, None.
"""
- fetch_order = self.media_manager.get("media_fetch_order")
+ fetch_order = self.media_manager.media_fetch_order
# No fetching order found? well, give up!
if not fetch_order:
thumb_url = mg_globals.app.staticdirector(manager[u'default_thumb'])
return thumb_url
+ @property
+ def original_url(self):
+ """ Returns the URL for the original image
+ will return self.thumb_url if original url doesn't exist"""
+ if u"original" not in self.media_files:
+ return self.thumb_url
+
+ return mg_globals.app.public_store.file_url(
+ self.media_files[u"original"]
+ )
+
@cached_property
def media_manager(self):
"""Returns the MEDIA_MANAGER of the media's media_type
Raises FileTypeNotSupported in case no such manager is enabled
"""
- # TODO, we should be able to make this a simple lookup rather
- # than iterating through all media managers.
- for media_type, manager in get_media_managers():
- if media_type == self.media_type:
- return manager
+ manager = hook_handle(('media_manager', self.media_type))
+ if manager:
+ return manager(self)
+
# Not found? Then raise an error
raise FileTypeNotSupported(
- "MediaManager not in enabled types. Check media_types in config?")
+ "MediaManager not in enabled types. Check media_type plugins are"
+ " enabled in config?")
def get_fail_exception(self):
"""
return licenses.get_license_by_url(self.license or "")
def exif_display_iter(self):
- from mediagoblin.tools.exif import USEFUL_TAGS
+ if not self.media_data:
+ return
+ exif_all = self.media_data.get("exif_all")
+ for key in exif_all:
+ label = re.sub('(.)([A-Z][a-z]+)', r'\1 \2', key)
+ yield label.replace('EXIF', '').replace('Image', ''), exif_all[key]
+
+ def exif_display_data_short(self):
+ """Display a very short practical version of exif info"""
if not self.media_data:
return
+
exif_all = self.media_data.get("exif_all")
- for key in USEFUL_TAGS:
- if key in exif_all:
- yield key, exif_all[key]
+ exif_short = {}
+
+ if 'Image DateTimeOriginal' in exif_all:
+ # format date taken
+ takendate = datetime.strptime(
+ exif_all['Image DateTimeOriginal']['printable'],
+ '%Y:%m:%d %H:%M:%S').date()
+ taken = takendate.strftime('%B %d %Y')
+
+ exif_short.update({'Date Taken': taken})
+
+ aperture = None
+ if 'EXIF FNumber' in exif_all:
+ fnum = str(exif_all['EXIF FNumber']['printable']).split('/')
+
+ # calculate aperture
+ if len(fnum) == 2:
+ aperture = "f/%.1f" % (float(fnum[0])/float(fnum[1]))
+ elif fnum[0] != 'None':
+ aperture = "f/%s" % (fnum[0])
+
+ if aperture:
+ exif_short.update({'Aperture': aperture})
+
+ short_keys = [
+ ('Camera', 'Image Model', None),
+ ('Exposure', 'EXIF ExposureTime', lambda x: '%s sec' % x),
+ ('ISO Speed', 'EXIF ISOSpeedRatings', None),
+ ('Focal Length', 'EXIF FocalLength', lambda x: '%s mm' % x)]
+
+ for label, key, fmt_func in short_keys:
+ try:
+ val = fmt_func(exif_all[key]['printable']) if fmt_func \
+ else exif_all[key]['printable']
+ exif_short.update({label: val})
+ except KeyError:
+ pass
+
+ return exif_short
class MediaCommentMixin(object):
"""
return cleaned_markdown_conversion(self.content)
+ def __unicode__(self):
+ return u'<{klass} #{id} {author} "{comment}">'.format(
+ klass=self.__class__.__name__,
+ id=self.id,
+ author=self.get_author,
+ comment=self.content)
-class CollectionMixin(object):
- def generate_slug(self):
+ def __repr__(self):
+ return '<{klass} #{id} {author} "{comment}">'.format(
+ klass=self.__class__.__name__,
+ id=self.id,
+ author=self.get_author,
+ comment=self.content)
+
+
+class CollectionMixin(GenerateSlugMixin):
+ def check_slug_used(self, slug):
# import this here due to a cyclic import issue
# (db.models -> db.mixin -> db.util -> db.models)
from mediagoblin.db.util import check_collection_slug_used
- self.slug = slugify(self.title)
-
- duplicate = check_collection_slug_used(mg_globals.database,
- self.creator, self.slug, self.id)
-
- if duplicate:
- if self.id is not None:
- self.slug = u"%s-%s" % (self.id, self.slug)
- else:
- self.slug = None
+ return check_collection_slug_used(self.creator, slug, self.id)
@property
def description_html(self):