From 58a947578cde02244c08268205e6855bee408c94 Mon Sep 17 00:00:00 2001 From: Rodney Ewing Date: Mon, 1 Jul 2013 17:19:22 -0700 Subject: [PATCH 01/14] modified gmg to use plugin media_types and converted image media_type to new plugin style --- mediagoblin.ini | 5 --- mediagoblin/config_spec.ini | 3 -- mediagoblin/db/mixin.py | 15 +++---- mediagoblin/db/open.py | 4 -- mediagoblin/gmg_commands/dbupdate.py | 10 +---- mediagoblin/media_types/__init__.py | 49 +++++---------------- mediagoblin/media_types/image/__init__.py | 31 +++++++++++-- mediagoblin/media_types/image/processing.py | 7 ++- mediagoblin/user_pages/views.py | 2 +- 9 files changed, 52 insertions(+), 74 deletions(-) diff --git a/mediagoblin.ini b/mediagoblin.ini index e878a478..951e0d8a 100644 --- a/mediagoblin.ini +++ b/mediagoblin.ini @@ -19,11 +19,6 @@ email_debug_mode = true # Set to false to disable registrations allow_registration = true -## Uncomment this to turn on video or enable other media types -## You may have to install dependencies, and will have to run ./bin/gmg dbupdate -## See http://docs.mediagoblin.org/siteadmin/media-types.html for details. -# media_types = mediagoblin.media_types.image, mediagoblin.media_types.video - ## Uncomment this to put some user-overriding templates here # local_templates = %(here)s/user_dev/templates/ diff --git a/mediagoblin/config_spec.ini b/mediagoblin/config_spec.ini index 4547ea54..93643ee1 100644 --- a/mediagoblin/config_spec.ini +++ b/mediagoblin/config_spec.ini @@ -5,9 +5,6 @@ html_title = string(default="GNU MediaGoblin") # link to source for this MediaGoblin site source_link = string(default="https://gitorious.org/mediagoblin/mediagoblin") -# Enabled media types -media_types = string_list(default=list("mediagoblin.media_types.image")) - # database stuff sql_engine = string(default="sqlite:///%(here)s/mediagoblin.db") diff --git a/mediagoblin/db/mixin.py b/mediagoblin/db/mixin.py index 1b32d838..2d878c80 100644 --- a/mediagoblin/db/mixin.py +++ b/mediagoblin/db/mixin.py @@ -29,15 +29,14 @@ real objects. import uuid import re -import datetime - from datetime import datetime from werkzeug.utils import cached_property from mediagoblin import mg_globals -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 @@ -204,14 +203,12 @@ class MediaEntryMixin(GenerateSlugMixin): 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(self) + manager = hook_handle('get_media_manager', self.media_type) + if manager: + return manager # 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_types in config?") def get_fail_exception(self): """ diff --git a/mediagoblin/db/open.py b/mediagoblin/db/open.py index 0b1679fb..4ff0945f 100644 --- a/mediagoblin/db/open.py +++ b/mediagoblin/db/open.py @@ -52,10 +52,6 @@ class DatabaseMaster(object): def load_models(app_config): import mediagoblin.db.models - for media_type in app_config['media_types']: - _log.debug("Loading %s.models", media_type) - __import__(media_type + ".models") - for plugin in mg_globals.global_config.get('plugins', {}).keys(): _log.debug("Loading %s.models", plugin) try: diff --git a/mediagoblin/gmg_commands/dbupdate.py b/mediagoblin/gmg_commands/dbupdate.py index fa25ecb2..4dfd7e92 100644 --- a/mediagoblin/gmg_commands/dbupdate.py +++ b/mediagoblin/gmg_commands/dbupdate.py @@ -42,7 +42,7 @@ class DatabaseData(object): self.name, self.models, self.migrations, session) -def gather_database_data(media_types, plugins): +def gather_database_data(plugins): """ Gather all database data relevant to the extensions we have installed so we can do migrations and table initialization. @@ -59,13 +59,6 @@ def gather_database_data(media_types, plugins): DatabaseData( u'__main__', MAIN_MODELS, MAIN_MIGRATIONS)) - # Then get all registered media managers (eventually, plugins) - for media_type in media_types: - models = import_component('%s.models:MODELS' % media_type) - migrations = import_component('%s.migrations:MIGRATIONS' % media_type) - managed_dbdata.append( - DatabaseData(media_type, models, migrations)) - for plugin in plugins: try: models = import_component('{0}.models:MODELS'.format(plugin)) @@ -112,7 +105,6 @@ def run_dbupdate(app_config, global_config): # Gather information from all media managers / projects dbdatas = gather_database_data( - app_config['media_types'], global_config.get('plugins', {}).keys()) # Set up the database diff --git a/mediagoblin/media_types/__init__.py b/mediagoblin/media_types/__init__.py index 20e1918e..2ce66f2a 100644 --- a/mediagoblin/media_types/__init__.py +++ b/mediagoblin/media_types/__init__.py @@ -15,12 +15,10 @@ # along with this program. If not, see . import os -import sys import logging import tempfile -from mediagoblin import mg_globals -from mediagoblin.tools.common import import_component +from mediagoblin.tools.pluginapi import hook_handle from mediagoblin.tools.translate import lazy_pass_to_ugettext as _ _log = logging.getLogger(__name__) @@ -56,7 +54,7 @@ class CompatMediaManager(object): def __init__(self, mm_dict, entry=None): self.mm_dict = mm_dict self.entry = entry - + def __call__(self, entry): "So this object can look like a class too, somehow" assert self.entry is None @@ -98,40 +96,18 @@ def sniff_media(media): media_file.write(media.stream.read()) media.stream.seek(0) - for media_type, manager in get_media_managers(): - _log.info('Sniffing {0}'.format(media_type)) - if manager.sniff_handler(media_file, media=media): - _log.info('{0} accepts the file'.format(media_type)) - return media_type, manager - else: - _log.debug('{0} did not accept the file'.format(media_type)) + media_type = hook_handle('sniff_handler', media_file, media=media) + if media_type: + _log.info('{0} accepts the file'.format(media_type)) + return media_type, hook_handle('get_media_managers', media_type) + else: + _log.debug('{0} did not accept the file'.format(media_type)) raise FileTypeNotSupported( # TODO: Provide information on which file types are supported _(u'Sorry, I don\'t support that file type :(')) -def get_media_types(): - """ - Generator, yields the available media types - """ - for media_type in mg_globals.app_config['media_types']: - yield media_type - - -def get_media_managers(): - ''' - Generator, yields all enabled media managers - ''' - for media_type in get_media_types(): - mm = import_component(media_type + ":MEDIA_MANAGER") - - if isinstance(mm, dict): - mm = CompatMediaManager(mm) - - yield media_type, mm - - def get_media_type_and_manager(filename): ''' Try to find the media type based on the file name, extension @@ -142,11 +118,10 @@ def get_media_type_and_manager(filename): # Get the file extension ext = os.path.splitext(filename)[1].lower() - for media_type, manager in get_media_managers(): - # Omit the dot from the extension and match it against - # the media manager - if ext[1:] in manager.accepted_extensions: - return media_type, manager + # Omit the dot from the extension and match it against + # the media manager + if hook_handle('get_media_type_and_manager', ext[1:]): + return hook_handle('get_media_type_and_manager', ext[1:]) else: _log.info('File {0} has no file extension, let\'s hope the sniffers get it.'.format( filename)) diff --git a/mediagoblin/media_types/image/__init__.py b/mediagoblin/media_types/image/__init__.py index 5130ef48..b43dcb05 100644 --- a/mediagoblin/media_types/image/__init__.py +++ b/mediagoblin/media_types/image/__init__.py @@ -13,12 +13,20 @@ # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . - import datetime from mediagoblin.media_types import MediaManagerBase from mediagoblin.media_types.image.processing import process_image, \ sniff_handler +from mediagoblin.tools import pluginapi + + +ACCEPTED_EXTENSIONS = ["jpg", "jpeg", "png", "gif", "tiff"] +MEDIA_TYPE = 'mediagoblin.media_types.image' + + +def setup_plugin(): + config = pluginapi.get_config('mediagoblin.pluginapi.media_types.image') class ImageMediaManager(MediaManagerBase): @@ -27,9 +35,9 @@ class ImageMediaManager(MediaManagerBase): sniff_handler = staticmethod(sniff_handler) display_template = "mediagoblin/media_displays/image.html" default_thumb = "images/media_thumbs/image.png" - accepted_extensions = ["jpg", "jpeg", "png", "gif", "tiff"] + media_fetch_order = [u'medium', u'original', u'thumb'] - + def get_original_date(self): """ Get the original date and time from the EXIF information. Returns @@ -52,4 +60,19 @@ class ImageMediaManager(MediaManagerBase): return None -MEDIA_MANAGER = ImageMediaManager +def get_media_manager(media_type): + if media_type == MEDIA_TYPE: + return ImageMediaManager + + +def get_media_type_and_manager(ext): + if ext in ACCEPTED_EXTENSIONS: + return ImageMediaManager + + +hooks = { + 'setup': setup_plugin, + 'extensions': get_media_type_and_manager, + 'sniff_handler': sniff_handler, + 'get_media_manager': get_media_manager, +} diff --git a/mediagoblin/media_types/image/processing.py b/mediagoblin/media_types/image/processing.py index bc0ce3f8..55f38ed5 100644 --- a/mediagoblin/media_types/image/processing.py +++ b/mediagoblin/media_types/image/processing.py @@ -35,6 +35,8 @@ PIL_FILTERS = { 'BICUBIC': Image.BICUBIC, 'ANTIALIAS': Image.ANTIALIAS} +MEDIA_TYPE = 'mediagoblin.media_types.image' + def resize_image(proc_state, resized, keyname, target_name, new_size, exif_tags, workdir): @@ -99,13 +101,14 @@ SUPPORTED_FILETYPES = ['png', 'gif', 'jpg', 'jpeg'] def sniff_handler(media_file, **kw): + _log.info('Sniffing {0}'.format(MEDIA_TYPE)) if kw.get('media') is not None: # That's a double negative! name, ext = os.path.splitext(kw['media'].filename) clean_ext = ext[1:].lower() # Strip the . from ext and make lowercase if clean_ext in SUPPORTED_FILETYPES: _log.info('Found file extension in supported filetypes') - return True + return MEDIA_TYPE else: _log.debug('Media present, extension not found in {0}'.format( SUPPORTED_FILETYPES)) @@ -113,7 +116,7 @@ def sniff_handler(media_file, **kw): _log.warning('Need additional information (keyword argument \'media\')' ' to be able to handle sniffing') - return False + return None def process_image(proc_state): diff --git a/mediagoblin/user_pages/views.py b/mediagoblin/user_pages/views.py index 83a524ec..596d4c20 100644 --- a/mediagoblin/user_pages/views.py +++ b/mediagoblin/user_pages/views.py @@ -142,7 +142,7 @@ def media_home(request, media, page, **kwargs): comment_form = user_forms.MediaCommentForm(request.form) - media_template_name = media.media_manager['display_template'] + media_template_name = media.media_manager.display_template return render_to_response( request, From 90b7b6e878772061e416fc462273b8cc2e8dea5d Mon Sep 17 00:00:00 2001 From: Rodney Ewing Date: Mon, 1 Jul 2013 17:23:47 -0700 Subject: [PATCH 02/14] removed CompatMediaManager() since all core media_types are classes --- mediagoblin/media_types/__init__.py | 30 ----------------------------- 1 file changed, 30 deletions(-) diff --git a/mediagoblin/media_types/__init__.py b/mediagoblin/media_types/__init__.py index 2ce66f2a..395ba17a 100644 --- a/mediagoblin/media_types/__init__.py +++ b/mediagoblin/media_types/__init__.py @@ -50,36 +50,6 @@ class MediaManagerBase(object): return hasattr(self, i) -class CompatMediaManager(object): - def __init__(self, mm_dict, entry=None): - self.mm_dict = mm_dict - self.entry = entry - - def __call__(self, entry): - "So this object can look like a class too, somehow" - assert self.entry is None - return self.__class__(self.mm_dict, entry) - - def __getitem__(self, i): - return self.mm_dict[i] - - def __contains__(self, i): - return (i in self.mm_dict) - - @property - def media_fetch_order(self): - return self.mm_dict.get('media_fetch_order') - - def sniff_handler(self, *args, **kwargs): - func = self.mm_dict.get("sniff_handler", None) - if func is not None: - return func(*args, **kwargs) - return False - - def __getattr__(self, i): - return self.mm_dict[i] - - def sniff_media(media): ''' Iterate through the enabled media types and find those suited From 2d9a452c3af11f54bb2bde628a06cec2f78b2309 Mon Sep 17 00:00:00 2001 From: Rodney Ewing Date: Tue, 2 Jul 2013 07:20:20 -0700 Subject: [PATCH 03/14] removed sniff_handler from Imange Media Manager class --- mediagoblin/media_types/image/__init__.py | 1 - 1 file changed, 1 deletion(-) diff --git a/mediagoblin/media_types/image/__init__.py b/mediagoblin/media_types/image/__init__.py index b43dcb05..6303bbe0 100644 --- a/mediagoblin/media_types/image/__init__.py +++ b/mediagoblin/media_types/image/__init__.py @@ -32,7 +32,6 @@ def setup_plugin(): class ImageMediaManager(MediaManagerBase): human_readable = "Image" processor = staticmethod(process_image) - sniff_handler = staticmethod(sniff_handler) display_template = "mediagoblin/media_displays/image.html" default_thumb = "images/media_thumbs/image.png" From e699197258d5e1b5495e60cb2c238b3ff4f50ed4 Mon Sep 17 00:00:00 2001 From: Rodney Ewing Date: Tue, 2 Jul 2013 07:54:38 -0700 Subject: [PATCH 04/14] fixed some typos and enabled media_type plugins in tests --- mediagoblin.ini | 1 + mediagoblin/db/mixin.py | 3 ++- mediagoblin/media_types/image/__init__.py | 6 +++--- mediagoblin/tests/test_mgoblin_app.ini | 4 ++-- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/mediagoblin.ini b/mediagoblin.ini index 951e0d8a..035e7bcf 100644 --- a/mediagoblin.ini +++ b/mediagoblin.ini @@ -43,3 +43,4 @@ base_url = /mgoblin_media/ [plugins] [[mediagoblin.plugins.geolocation]] [[mediagoblin.plugins.basic_auth]] +[[mediagoblin.media_types.image]] diff --git a/mediagoblin/db/mixin.py b/mediagoblin/db/mixin.py index 2d878c80..26e41a3b 100644 --- a/mediagoblin/db/mixin.py +++ b/mediagoblin/db/mixin.py @@ -208,7 +208,8 @@ class MediaEntryMixin(GenerateSlugMixin): return manager # 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): """ diff --git a/mediagoblin/media_types/image/__init__.py b/mediagoblin/media_types/image/__init__.py index 6303bbe0..4b991588 100644 --- a/mediagoblin/media_types/image/__init__.py +++ b/mediagoblin/media_types/image/__init__.py @@ -26,7 +26,7 @@ MEDIA_TYPE = 'mediagoblin.media_types.image' def setup_plugin(): - config = pluginapi.get_config('mediagoblin.pluginapi.media_types.image') + config = pluginapi.get_config('mediagoblin.media_types.image') class ImageMediaManager(MediaManagerBase): @@ -66,12 +66,12 @@ def get_media_manager(media_type): def get_media_type_and_manager(ext): if ext in ACCEPTED_EXTENSIONS: - return ImageMediaManager + return MEDIA_TYPE, ImageMediaManager hooks = { 'setup': setup_plugin, - 'extensions': get_media_type_and_manager, + 'get_media_type_and_manager': get_media_type_and_manager, 'sniff_handler': sniff_handler, 'get_media_manager': get_media_manager, } diff --git a/mediagoblin/tests/test_mgoblin_app.ini b/mediagoblin/tests/test_mgoblin_app.ini index 5b060d36..ecd6c9d2 100644 --- a/mediagoblin/tests/test_mgoblin_app.ini +++ b/mediagoblin/tests/test_mgoblin_app.ini @@ -12,8 +12,6 @@ tags_max_length = 50 # So we can start to test attachments: allow_attachments = True -media_types = mediagoblin.media_types.image, mediagoblin.media_types.pdf - [storage:publicstore] base_dir = %(here)s/user_dev/media/public base_url = /mgoblin_media/ @@ -32,3 +30,5 @@ BROKER_HOST = "sqlite:///%(here)s/user_dev/kombu.db" [[mediagoblin.plugins.httpapiauth]] [[mediagoblin.plugins.piwigo]] [[mediagoblin.plugins.basic_auth]] +[[mediagoblin.media_types.image]] +[[mediagoblin.media_types.pdf]] From 229308123196cbc7b3ba131da31eefb4c14d767e Mon Sep 17 00:00:00 2001 From: Rodney Ewing Date: Tue, 2 Jul 2013 08:09:37 -0700 Subject: [PATCH 05/14] converted ascii media_type to plugin --- mediagoblin/media_types/ascii/__init__.py | 29 ++++++++++++++++++--- mediagoblin/media_types/ascii/processing.py | 6 +++-- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/mediagoblin/media_types/ascii/__init__.py b/mediagoblin/media_types/ascii/__init__.py index 0931e83a..bcba237c 100644 --- a/mediagoblin/media_types/ascii/__init__.py +++ b/mediagoblin/media_types/ascii/__init__.py @@ -17,15 +17,36 @@ from mediagoblin.media_types import MediaManagerBase from mediagoblin.media_types.ascii.processing import process_ascii, \ sniff_handler +from mediagoblin.tools import pluginapi + +ACCEPTED_EXTENSIONS = ["txt", "asc", "nfo"] +MEDIA_TYPE = 'mediagoblin.media_types.ascii' + + +def setup_plugin(): + config = pluginapi.get_config(MEDIA_TYPE) class ASCIIMediaManager(MediaManagerBase): human_readable = "ASCII" processor = staticmethod(process_ascii) - sniff_handler = staticmethod(sniff_handler) display_template = "mediagoblin/media_displays/ascii.html" default_thumb = "images/media_thumbs/ascii.jpg" - accepted_extensions = ["txt", "asc", "nfo"] - -MEDIA_MANAGER = ASCIIMediaManager + +def get_media_manager(media_type): + if media_type == MEDIA_TYPE: + return ASCIIMediaManager + + +def get_media_type_and_manager(ext): + if ext in ACCEPTED_EXTENSIONS: + return MEDIA_TYPE, ASCIIMediaManager + + +hooks = { + 'setup': setup_plugin, + 'get_media_type_and_manager': get_media_type_and_manager, + 'sniff_handler': sniff_handler, + 'get_media_manager': get_media_manager, +} diff --git a/mediagoblin/media_types/ascii/processing.py b/mediagoblin/media_types/ascii/processing.py index 2f6079be..aca784e8 100644 --- a/mediagoblin/media_types/ascii/processing.py +++ b/mediagoblin/media_types/ascii/processing.py @@ -28,17 +28,19 @@ from mediagoblin.media_types.ascii import asciitoimage _log = logging.getLogger(__name__) SUPPORTED_EXTENSIONS = ['txt', 'asc', 'nfo'] +MEDIA_TYPE = 'mediagoblin.media_types.ascii' def sniff_handler(media_file, **kw): + _log.info('Sniffing {0}'.format(MEDIA_TYPE)) if kw.get('media') is not None: name, ext = os.path.splitext(kw['media'].filename) clean_ext = ext[1:].lower() if clean_ext in SUPPORTED_EXTENSIONS: - return True + return MEDIA_TYPE - return False + return None def process_ascii(proc_state): From b1a763f61e8a848d2d5a8cfd68e2c45d31582b8f Mon Sep 17 00:00:00 2001 From: Rodney Ewing Date: Tue, 2 Jul 2013 08:14:40 -0700 Subject: [PATCH 06/14] typo in image supported_filetypes --- mediagoblin/media_types/image/processing.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mediagoblin/media_types/image/processing.py b/mediagoblin/media_types/image/processing.py index 55f38ed5..baf2ac7e 100644 --- a/mediagoblin/media_types/image/processing.py +++ b/mediagoblin/media_types/image/processing.py @@ -97,7 +97,7 @@ def resize_tool(proc_state, force, keyname, target_name, exif_tags, conversions_subdir) -SUPPORTED_FILETYPES = ['png', 'gif', 'jpg', 'jpeg'] +SUPPORTED_FILETYPES = ['png', 'gif', 'jpg', 'jpeg', 'tiff'] def sniff_handler(media_file, **kw): From df68438a34d3e913b78540216e1d9cc66ffbc401 Mon Sep 17 00:00:00 2001 From: Rodney Ewing Date: Tue, 2 Jul 2013 08:43:14 -0700 Subject: [PATCH 07/14] converted audio media_type to plugin --- mediagoblin/media_types/audio/__init__.py | 26 ++++++++++++++++++--- mediagoblin/media_types/audio/processing.py | 9 ++++--- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/mediagoblin/media_types/audio/__init__.py b/mediagoblin/media_types/audio/__init__.py index 2eb7300e..dfe68660 100644 --- a/mediagoblin/media_types/audio/__init__.py +++ b/mediagoblin/media_types/audio/__init__.py @@ -17,14 +17,34 @@ from mediagoblin.media_types import MediaManagerBase from mediagoblin.media_types.audio.processing import process_audio, \ sniff_handler +from mediagoblin.tools import pluginapi + +ACCEPTED_EXTENSIONS = ["mp3", "flac", "wav", "m4a"] +MEDIA_TYPE = 'mediagoblin.media_types.audio' + + +def setup_plugin(): + config = pluginapi.get_config(MEDIA_TYPE) class AudioMediaManager(MediaManagerBase): human_readable = "Audio" processor = staticmethod(process_audio) - sniff_handler = staticmethod(sniff_handler) display_template = "mediagoblin/media_displays/audio.html" - accepted_extensions = ["mp3", "flac", "wav", "m4a"] -MEDIA_MANAGER = AudioMediaManager +def get_media_manager(media_type): + if media_type == MEDIA_TYPE: + return AudioMediaManager + + +def get_media_type_and_manager(ext): + if ext in ACCEPTED_EXTENSIONS: + return MEDIA_TYPE, AudioMediaManager + +hooks = { + 'setup': setup_plugin, + 'get_media_type_and_manager': get_media_type_and_manager, + 'sniff_handler': sniff_handler, + 'get_media_manager': get_media_manager, +} diff --git a/mediagoblin/media_types/audio/processing.py b/mediagoblin/media_types/audio/processing.py index 101b83e5..22383bc1 100644 --- a/mediagoblin/media_types/audio/processing.py +++ b/mediagoblin/media_types/audio/processing.py @@ -27,19 +27,22 @@ from mediagoblin.media_types.audio.transcoders import (AudioTranscoder, _log = logging.getLogger(__name__) +MEDIA_TYPE = 'mediagoblin.media_types.audio' + def sniff_handler(media_file, **kw): + _log.info('Sniffing {0}'.format(MEDIA_TYPE)) try: transcoder = AudioTranscoder() data = transcoder.discover(media_file.name) except BadMediaFail: _log.debug('Audio discovery raised BadMediaFail') - return False + return None if data.is_audio == True and data.is_video == False: - return True + return MEDIA_TYPE - return False + return None def process_audio(proc_state): From 51e4e435046d043fd26da9ae5160a6ec3b7313f2 Mon Sep 17 00:00:00 2001 From: Rodney Ewing Date: Tue, 2 Jul 2013 08:48:47 -0700 Subject: [PATCH 08/14] converted pdf media_type to plugin --- mediagoblin/media_types/pdf/__init__.py | 26 ++++++++++++++++++++--- mediagoblin/media_types/pdf/processing.py | 9 +++++--- 2 files changed, 29 insertions(+), 6 deletions(-) diff --git a/mediagoblin/media_types/pdf/__init__.py b/mediagoblin/media_types/pdf/__init__.py index f0ba7867..c180507c 100644 --- a/mediagoblin/media_types/pdf/__init__.py +++ b/mediagoblin/media_types/pdf/__init__.py @@ -17,15 +17,35 @@ from mediagoblin.media_types import MediaManagerBase from mediagoblin.media_types.pdf.processing import process_pdf, \ sniff_handler +from mediagoblin.tools import pluginapi + +ACCEPTED_EXTENSIONS = ['pdf'] +MEDIA_TYPE = 'mediagoblin.media_types.pdf' + + +def setup_plugin(): + config = pluginapi.get_config(MEDIA_TYPE) class PDFMediaManager(MediaManagerBase): human_readable = "PDF" processor = staticmethod(process_pdf) - sniff_handler = staticmethod(sniff_handler) display_template = "mediagoblin/media_displays/pdf.html" default_thumb = "images/media_thumbs/pdf.jpg" - accepted_extensions = ["pdf"] -MEDIA_MANAGER = PDFMediaManager +def get_media_manager(media_type): + if media_type == MEDIA_TYPE: + return PDFMediaManager + + +def get_media_type_and_manager(ext): + if ext in ACCEPTED_EXTENSIONS: + return MEDIA_TYPE, PDFMediaManager + +hooks = { + 'setup': setup_plugin, + 'get_media_type_and_manager': get_media_type_and_manager, + 'sniff_handler': sniff_handler, + 'get_media_manager': get_media_manager, +} diff --git a/mediagoblin/media_types/pdf/processing.py b/mediagoblin/media_types/pdf/processing.py index 49742fd7..a1eeb307 100644 --- a/mediagoblin/media_types/pdf/processing.py +++ b/mediagoblin/media_types/pdf/processing.py @@ -25,6 +25,8 @@ from mediagoblin.tools.translate import fake_ugettext_passthrough as _ _log = logging.getLogger(__name__) +MEDIA_TYPE = 'mediagoblin.media_types.pdf' + # TODO - cache (memoize) util # This is a list created via uniconv --show and hand removing some types that @@ -163,16 +165,17 @@ def check_prerequisites(): return True def sniff_handler(media_file, **kw): + _log.info('Sniffing {0}'.format(MEDIA_TYPE)) if not check_prerequisites(): - return False + return None if kw.get('media') is not None: name, ext = os.path.splitext(kw['media'].filename) clean_ext = ext[1:].lower() if clean_ext in supported_extensions(): - return True + return MEDIA_TYPE - return False + return None def create_pdf_thumb(original, thumb_filename, width, height): # Note: pdftocairo adds '.png', remove it From 239296b004483034373e645b3614d376a188f9b4 Mon Sep 17 00:00:00 2001 From: Rodney Ewing Date: Tue, 2 Jul 2013 08:52:33 -0700 Subject: [PATCH 09/14] converted stl media_type to plugin --- mediagoblin/media_types/stl/__init__.py | 26 ++++++++++++++++++++--- mediagoblin/media_types/stl/processing.py | 6 ++++-- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/mediagoblin/media_types/stl/__init__.py b/mediagoblin/media_types/stl/__init__.py index 6ae8a8b9..192b5761 100644 --- a/mediagoblin/media_types/stl/__init__.py +++ b/mediagoblin/media_types/stl/__init__.py @@ -17,15 +17,35 @@ from mediagoblin.media_types import MediaManagerBase from mediagoblin.media_types.stl.processing import process_stl, \ sniff_handler +from mediagoblin.tools import pluginapi + +MEDIA_TYPE = 'mediagoblin.media_types.stl' +ACCEPTED_EXTENSIONS = ["obj", "stl"] + + +def setup_plugin(): + config = pluginapi.get_config(MEDIA_TYPE) class STLMediaManager(MediaManagerBase): human_readable = "stereo lithographics" processor = staticmethod(process_stl) - sniff_handler = staticmethod(sniff_handler) display_template = "mediagoblin/media_displays/stl.html" default_thumb = "images/media_thumbs/video.jpg" - accepted_extensions = ["obj", "stl"] -MEDIA_MANAGER = STLMediaManager +def get_media_manager(media_type): + if media_type == MEDIA_TYPE: + return STLMediaManager + + +def get_media_type_and_manager(ext): + if ext in ACCEPTED_EXTENSIONS: + return MEDIA_TYPE, STLMediaManager + +hooks = { + 'setup': setup_plugin, + 'get_media_type_and_manager': get_media_type_and_manager, + 'sniff_handler': sniff_handler, + 'get_media_manager': get_media_manager, +} diff --git a/mediagoblin/media_types/stl/processing.py b/mediagoblin/media_types/stl/processing.py index ce7a5d37..53751416 100644 --- a/mediagoblin/media_types/stl/processing.py +++ b/mediagoblin/media_types/stl/processing.py @@ -29,6 +29,7 @@ from mediagoblin.media_types.stl import model_loader _log = logging.getLogger(__name__) SUPPORTED_FILETYPES = ['stl', 'obj'] +MEDIA_TYPE = 'mediagoblin.media_types.stl' BLEND_FILE = pkg_resources.resource_filename( 'mediagoblin.media_types.stl', @@ -43,13 +44,14 @@ BLEND_SCRIPT = pkg_resources.resource_filename( def sniff_handler(media_file, **kw): + _log.info('Sniffing {0}'.format(MEDIA_TYPE)) if kw.get('media') is not None: name, ext = os.path.splitext(kw['media'].filename) clean_ext = ext[1:].lower() if clean_ext in SUPPORTED_FILETYPES: _log.info('Found file extension in supported filetypes') - return True + return MEDIA_TYPE else: _log.debug('Media present, extension not found in {0}'.format( SUPPORTED_FILETYPES)) @@ -57,7 +59,7 @@ def sniff_handler(media_file, **kw): _log.warning('Need additional information (keyword argument \'media\')' ' to be able to handle sniffing') - return False + return None def blender_render(config): From cbac4a7fc93fa44d669e36700c68019a19bd091d Mon Sep 17 00:00:00 2001 From: Rodney Ewing Date: Tue, 2 Jul 2013 08:57:10 -0700 Subject: [PATCH 10/14] converted video media_type to plugin --- mediagoblin/media_types/video/__init__.py | 30 +++++++++++++++++---- mediagoblin/media_types/video/processing.py | 13 +++++---- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/mediagoblin/media_types/video/__init__.py b/mediagoblin/media_types/video/__init__.py index 569cf11a..aa4cdb93 100644 --- a/mediagoblin/media_types/video/__init__.py +++ b/mediagoblin/media_types/video/__init__.py @@ -17,20 +17,40 @@ from mediagoblin.media_types import MediaManagerBase from mediagoblin.media_types.video.processing import process_video, \ sniff_handler +from mediagoblin.tools import pluginapi + +MEDIA_TYPE = 'mediagoblin.media_types.video' +ACCEPTED_EXTENSIONS = [ + "mp4", "mov", "webm", "avi", "3gp", "3gpp", "mkv", "ogv", "m4v"] + + +def setup_plugin(): + config = pluginapi.get_config(MEDIA_TYPE) class VideoMediaManager(MediaManagerBase): human_readable = "Video" processor = staticmethod(process_video) - sniff_handler = staticmethod(sniff_handler) display_template = "mediagoblin/media_displays/video.html" default_thumb = "images/media_thumbs/video.jpg" - accepted_extensions = [ - "mp4", "mov", "webm", "avi", "3gp", "3gpp", "mkv", "ogv", "m4v"] - + # Used by the media_entry.get_display_media method media_fetch_order = [u'webm_640', u'original'] default_webm_type = 'video/webm; codecs="vp8, vorbis"' -MEDIA_MANAGER = VideoMediaManager +def get_media_manager(media_type): + if media_type == MEDIA_TYPE: + return VideoMediaManager + + +def get_media_type_and_manager(ext): + if ext in ACCEPTED_EXTENSIONS: + return MEDIA_TYPE, VideoMediaManager + +hooks = { + 'setup': setup_plugin, + 'get_media_type_and_manager': get_media_type_and_manager, + 'sniff_handler': sniff_handler, + 'get_media_manager': get_media_manager, +} diff --git a/mediagoblin/media_types/video/processing.py b/mediagoblin/media_types/video/processing.py index ff2c94a0..5386ba60 100644 --- a/mediagoblin/media_types/video/processing.py +++ b/mediagoblin/media_types/video/processing.py @@ -29,6 +29,8 @@ from .util import skip_transcode _log = logging.getLogger(__name__) _log.setLevel(logging.DEBUG) +MEDIA_TYPE = 'mediagoblin.media_types.video' + class VideoTranscodingFail(BaseProcessingFail): ''' @@ -41,17 +43,18 @@ def sniff_handler(media_file, **kw): transcoder = transcoders.VideoTranscoder() data = transcoder.discover(media_file.name) + _log.info('Sniffing {0}'.format(MEDIA_TYPE)) _log.debug('Discovered: {0}'.format(data)) if not data: _log.error('Could not discover {0}'.format( kw.get('media'))) - return False + return None if data['is_video'] == True: - return True + return MEDIA_TYPE - return False + return None def process_video(proc_state): @@ -186,7 +189,7 @@ def store_metadata(media_entry, metadata): [(key, tags_metadata[key]) for key in [ "application-name", "artist", "audio-codec", "bitrate", - "container-format", "copyright", "encoder", + "container-format", "copyright", "encoder", "encoder-version", "license", "nominal-bitrate", "title", "video-codec"] if key in tags_metadata]) @@ -203,7 +206,7 @@ def store_metadata(media_entry, metadata): dt.get_year(), dt.get_month(), dt.get_day(), dt.get_hour(), dt.get_minute(), dt.get_second(), dt.get_microsecond()).isoformat() - + metadata['tags'] = tags # Only save this field if there's something to save From c81186dd2e300664d36583e9003736213d5aa7e9 Mon Sep 17 00:00:00 2001 From: Rodney Ewing Date: Tue, 2 Jul 2013 09:26:12 -0700 Subject: [PATCH 11/14] added a warning for old media types --- mediagoblin/app.py | 3 +++ mediagoblin/media_types/tools.py | 27 +++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 mediagoblin/media_types/tools.py diff --git a/mediagoblin/app.py b/mediagoblin/app.py index 96461711..11464a1f 100644 --- a/mediagoblin/app.py +++ b/mediagoblin/app.py @@ -29,6 +29,7 @@ from mediagoblin.tools import common, session, translate, template from mediagoblin.tools.response import render_http_exception from mediagoblin.tools.theme import register_themes from mediagoblin.tools import request as mg_request +from mediagoblin.media_types.tools import media_type_warning from mediagoblin.mg_globals import setup_globals from mediagoblin.init.celery import setup_celery_from_config from mediagoblin.init.plugins import setup_plugins @@ -69,6 +70,8 @@ class MediaGoblinApp(object): # Open and setup the config global_config, app_config = setup_global_and_app_config(config_path) + media_type_warning() + setup_crypto() ########################################## diff --git a/mediagoblin/media_types/tools.py b/mediagoblin/media_types/tools.py new file mode 100644 index 00000000..fe7b3772 --- /dev/null +++ b/mediagoblin/media_types/tools.py @@ -0,0 +1,27 @@ +# GNU MediaGoblin -- federated, autonomous media hosting +# Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS. +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +import logging + +from mediagoblin import mg_globals + +_log = logging.getLogger(__name__) + + +def media_type_warning(): + if mg_globals.app_config.get('media_types'): + _log.warning('Media_types have been converted to plugins. Old' + ' media_types will no longer work. Please convert them' + ' to plugins to continue using them.') From 003ea47499a3f4ed0be2d5ad49e7a0ce8bb62278 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Fri, 12 Jul 2013 14:16:47 -0500 Subject: [PATCH 12/14] Changing the information spat out while printing from media types->plugins Previously it called even plugins media types. Ha! This commit sponsored by Jon Merkley. Thank you! --- mediagoblin/db/migration_tools.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/mediagoblin/db/migration_tools.py b/mediagoblin/db/migration_tools.py index c0c7e998..aa22ef94 100644 --- a/mediagoblin/db/migration_tools.py +++ b/mediagoblin/db/migration_tools.py @@ -175,8 +175,7 @@ class MigrationManager(object): if self.name == u'__main__': return u"main mediagoblin tables" else: - # TODO: Use the friendlier media manager "human readable" name - return u'media type "%s"' % self.name + return u'plugin "%s"' % self.name def init_or_migrate(self): """ From 60eeb4566457a127c7783e9ac7953daebf3e4592 Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Fri, 12 Jul 2013 14:53:10 -0500 Subject: [PATCH 13/14] Switch the import of the image media manager over to the new class This helps resolve one of the remaining issues with the tests for the media type pluginification. This commit sponsored by Jeffrey Moe. Thanks Jeff! Lulzbot rocks! --- mediagoblin/tests/test_submission.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mediagoblin/tests/test_submission.py b/mediagoblin/tests/test_submission.py index 162b2d19..dd7db12a 100644 --- a/mediagoblin/tests/test_submission.py +++ b/mediagoblin/tests/test_submission.py @@ -26,7 +26,7 @@ from mediagoblin.tests.tools import fixture_add_user from mediagoblin import mg_globals from mediagoblin.db.models import MediaEntry from mediagoblin.tools import template -from mediagoblin.media_types.image import MEDIA_MANAGER as img_MEDIA_MANAGER +from mediagoblin.media_types.image import ImageMediaManager from mediagoblin.media_types.pdf.processing import check_prerequisites as pdf_check_prerequisites from .resources import GOOD_JPG, GOOD_PNG, EVIL_FILE, EVIL_JPG, EVIL_PNG, \ @@ -219,7 +219,7 @@ class TestSubmission: media = self.check_media(request, {'title': u'Balanced Goblin'}, 1) assert media.media_type == u'mediagoblin.media_types.image' - assert isinstance(media.media_manager, img_MEDIA_MANAGER) + assert isinstance(media.media_manager, ImageMediaManager) assert media.media_manager.entry == media From 4259ad5bf1680896090290e7327b49a053a8447b Mon Sep 17 00:00:00 2001 From: Christopher Allan Webber Date: Fri, 12 Jul 2013 15:52:20 -0500 Subject: [PATCH 14/14] Fix the last bit preventing all the unit tests from passing in media types->plugins The last commit was also small, so Jeff Moe gets... two! Two sponsored commits! Ah ah ah. --- mediagoblin/db/mixin.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mediagoblin/db/mixin.py b/mediagoblin/db/mixin.py index 26e41a3b..ee8525c2 100644 --- a/mediagoblin/db/mixin.py +++ b/mediagoblin/db/mixin.py @@ -205,7 +205,8 @@ class MediaEntryMixin(GenerateSlugMixin): """ manager = hook_handle('get_media_manager', self.media_type) if manager: - return manager + return manager(self) + # Not found? Then raise an error raise FileTypeNotSupported( "MediaManager not in enabled types. Check media_type plugins are"