X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=mediagoblin%2Fmedia_types%2F__init__.py;h=134157dcb0ca7054fdf5043bef82548137ef7373;hb=35d6a95008ac63a00cc2e4d7fac8187bc58eea9a;hp=61786562f7a0043e7983cd309812dcbcafe9665a;hpb=cfa96da734e633856282fcefb04e1fb231d85053;p=mediagoblin.git diff --git a/mediagoblin/media_types/__init__.py b/mediagoblin/media_types/__init__.py index 61786562..134157dc 100644 --- a/mediagoblin/media_types/__init__.py +++ b/mediagoblin/media_types/__init__.py @@ -1,5 +1,5 @@ # GNU MediaGoblin -- federated, autonomous media hosting -# Copyright (C) 2011 MediaGoblin contributors. See AUTHORS. +# 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 @@ -15,11 +15,13 @@ # along with this program. If not, see . import os -import sys +import logging +import tempfile -from mediagoblin import mg_globals +from mediagoblin.tools.pluginapi import hook_handle from mediagoblin.tools.translate import lazy_pass_to_ugettext as _ +_log = logging.getLogger(__name__) class FileTypeNotSupported(Exception): pass @@ -28,38 +30,71 @@ class InvalidFileType(Exception): pass -def get_media_types(): - """ - Generator that returns the available media types - """ - for media_type in mg_globals.app_config['media_types']: - yield media_type +class MediaManagerBase(object): + "Base class for all media managers" + # Please override in actual media managers + media_fetch_order = None -def get_media_managers(): + @staticmethod + def sniff_handler(*args, **kwargs): + return False + + def __init__(self, entry): + self.entry = entry + + def __getitem__(self, i): + return getattr(self, i) + + def __contains__(self, i): + return hasattr(self, i) + + +def sniff_media(media): ''' - Generator that returns all available media managers + Iterate through the enabled media types and find those suited + for a certain file. ''' - for media_type in get_media_types(): - __import__(media_type) - - yield media_type, sys.modules[media_type].MEDIA_MANAGER + try: + return get_media_type_and_manager(media.filename) + except FileTypeNotSupported: + _log.info('No media handler found by file extension. Doing it the expensive way...') + # Create a temporary file for sniffers suchs as GStreamer-based + # Audio video + media_file = tempfile.NamedTemporaryFile() + media_file.write(media.stream.read()) + media.stream.seek(0) -def get_media_manager(_media_type = None): - for media_type, manager in get_media_managers(): - if media_type in _media_type: - return manager + 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(('media_manager', 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_type_and_manager(filename): - for media_type, manager in get_media_managers(): - if filename.find('.') > 0: - ext = os.path.splitext(filename)[1].lower() - else: - raise InvalidFileType( - _('Could not find any file extension in "{filename}"').format( - filename=filename)) + ''' + Try to find the media type based on the file name, extension + specifically. This is used as a speedup, the sniffing functionality + then falls back on more in-depth bitsniffing of the source file. + ''' + if filename.find('.') > 0: + # Get the file extension + ext = os.path.splitext(filename)[1].lower() + + # 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)) - if ext[1:] in manager['accepted_extensions']: - return media_type, manager + raise FileTypeNotSupported( + _(u'Sorry, I don\'t support that file type :('))