Merge branch 'rodney757-media_plugins'

Conflicts:
	mediagoblin.ini
	mediagoblin/tests/test_mgoblin_app.ini
This commit is contained in:
Christopher Allan Webber
2013-07-12 16:24:36 -05:00
24 changed files with 237 additions and 144 deletions

View File

@@ -15,12 +15,10 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.
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__)
@@ -52,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
@@ -98,40 +66,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 +88,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))

View File

@@ -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,
}

View File

@@ -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):

View File

@@ -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,
}

View File

@@ -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):

View File

@@ -13,23 +13,30 @@
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
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.media_types.image')
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"
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 +59,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 MEDIA_TYPE, ImageMediaManager
hooks = {
'setup': setup_plugin,
'get_media_type_and_manager': get_media_type_and_manager,
'sniff_handler': sniff_handler,
'get_media_manager': get_media_manager,
}

View File

@@ -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):
@@ -95,17 +97,18 @@ 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):
_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):

View File

@@ -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,
}

View File

@@ -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

View File

@@ -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,
}

View File

@@ -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):

View File

@@ -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 <http://www.gnu.org/licenses/>.
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.')

View File

@@ -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,
}

View File

@@ -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