1 # GNU MediaGoblin -- federated, autonomous media hosting
2 # Copyright (C) 2011, 2012 MediaGoblin contributors. See AUTHORS.
4 # This program is free software: you can redistribute it and/or modify
5 # it under the terms of the GNU Affero General Public License as published by
6 # the Free Software Foundation, either version 3 of the License, or
7 # (at your option) any later version.
9 # This program is distributed in the hope that it will be useful,
10 # but WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 # GNU Affero General Public License for more details.
14 # You should have received a copy of the GNU Affero General Public License
15 # along with this program. If not, see <http://www.gnu.org/licenses/>.
22 from mediagoblin
import mg_globals
23 from mediagoblin
.tools
.common
import import_component
24 from mediagoblin
.tools
.translate
import lazy_pass_to_ugettext
as _
26 _log
= logging
.getLogger(__name__
)
28 class FileTypeNotSupported(Exception):
31 class InvalidFileType(Exception):
35 class CompatMediaManager(object):
36 def __init__(self
, mm_dict
, entry
=None):
37 self
.mm_dict
= mm_dict
40 def __call__(self
, entry
):
41 "So this object can look like a class too, somehow"
42 assert self
.entry
is None
43 return self
.__class
__(self
.mm_dict
, entry
)
45 def __getitem__(self
, i
):
46 return self
.mm_dict
[i
]
48 def __contains__(self
, i
):
49 return (i
in self
.mm_dict
)
51 def get(self
, *args
, **kwargs
):
52 return self
.mm_dict
.get(*args
, **kwargs
)
54 def __getattr__(self
, i
):
55 return self
.mm_dict
[i
]
58 def sniff_media(media
):
60 Iterate through the enabled media types and find those suited
65 return get_media_type_and_manager(media
.filename
)
66 except FileTypeNotSupported
:
67 _log
.info('No media handler found by file extension. Doing it the expensive way...')
68 # Create a temporary file for sniffers suchs as GStreamer-based
70 media_file
= tempfile
.NamedTemporaryFile()
71 media_file
.write(media
.stream
.read())
74 for media_type
, manager
in get_media_managers():
75 _log
.info('Sniffing {0}'.format(media_type
))
76 if 'sniff_handler' in manager
and \
77 manager
['sniff_handler'](media_file
, media
=media
):
78 _log
.info('{0} accepts the file'.format(media_type
))
79 return media_type
, manager
81 _log
.debug('{0} did not accept the file'.format(media_type
))
83 raise FileTypeNotSupported(
84 # TODO: Provide information on which file types are supported
85 _(u
'Sorry, I don\'t support that file type :('))
88 def get_media_types():
90 Generator, yields the available media types
92 for media_type
in mg_globals
.app_config
['media_types']:
96 def get_media_managers():
98 Generator, yields all enabled media managers
100 for media_type
in get_media_types():
101 mm
= import_component(media_type
+ ":MEDIA_MANAGER")
103 if isinstance(mm
, dict):
104 mm
= CompatMediaManager(mm
)
109 def get_media_type_and_manager(filename
):
111 Try to find the media type based on the file name, extension
112 specifically. This is used as a speedup, the sniffing functionality
113 then falls back on more in-depth bitsniffing of the source file.
115 if filename
.find('.') > 0:
116 # Get the file extension
117 ext
= os
.path
.splitext(filename
)[1].lower()
119 for media_type
, manager
in get_media_managers():
120 # Omit the dot from the extension and match it against
122 if ext
[1:] in manager
['accepted_extensions']:
123 return media_type
, manager
125 _log
.info('File {0} has no file extension, let\'s hope the sniffers get it.'.format(
128 raise FileTypeNotSupported(
129 _(u
'Sorry, I don\'t support that file type :('))