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/>.
19 from mediagoblin
import mg_globals
20 from mediagoblin
.db
.models
import MediaEntry
21 from mediagoblin
.gmg_commands
import util
as commands_util
22 from mediagoblin
.tools
.translate
import lazy_pass_to_ugettext
as _
23 from mediagoblin
.tools
.pluginapi
import hook_handle
24 from mediagoblin
.processing
import ProcessorDoesNotExist
, ProcessorNotEligible
27 def reprocess_parser_setup(subparser
):
28 subparsers
= subparser
.add_subparsers(dest
="reprocess_subcommand")
33 available_parser
= subparsers
.add_parser(
35 help="Find out what actions are available for this media")
37 available_parser
.add_argument(
39 help="Media id or media type to check")
41 available_parser
.add_argument(
44 help="List argument help for each action available")
47 ############################################
48 # run command (TODO: and bulk_run command??)
49 ############################################
51 run_parser
= subparsers
.add_parser(
53 help="Run a reprocessing on one or more media")
55 run_parser
.add_argument(
57 help="Reprocess media entries in this state"
58 " such as 'failed' or 'processed'")
59 run_parser
.add_argument(
61 help="The type of media to be reprocessed such as 'video' or 'image'")
62 run_parser
.add_argument(
65 help="Regenerate thumbnails for all processed media")
66 run_parser
.add_argument(
69 help="Don't process eagerly, pass off to celery")
71 run_parser
.add_argument(
73 help="The media_entry id(s) you wish to reprocess.")
75 run_parser
.add_argument(
77 help="The reprocess command you intend to run")
79 run_parser
.add_argument(
81 nargs
=argparse
.REMAINDER
,
82 help="rest of arguments to the reprocessing tool")
91 def _set_media_type(args
):
93 This will verify that all media id's are of the same media_type. If the
94 --type flag is set, it will be replaced by the given media id's type.
96 If they are trying to process different media types, an Exception will be
100 if len(args
[0].media_id
) == 1:
101 args
[0].type = MediaEntry
.query
.filter_by(id=args
[0].media_id
[0])\
102 .first().media_type
.split('.')[-1]
104 elif len(args
[0].media_id
) > 1:
107 for id in args
[0].media_id
:
108 media_types
.append(MediaEntry
.query
.filter_by(id=id).first()
109 .media_type
.split('.')[-1])
110 for type in media_types
:
111 if media_types
[0] != type:
112 raise Exception((u
'You cannot reprocess different'
113 ' media_types at the same time.'))
115 args
[0].type = media_types
[0]
118 def _reprocess_all(args
):
120 This handles reprocessing if no media_id's are given.
123 # If no media type is given, we can either regenerate all thumbnails,
124 # or try to reprocess all failed media
126 if args
[0].thumbnails
:
127 if args
[0].available
:
128 print _('Available options for regenerating all processed'
129 ' media thumbnails: \n'
130 '\t --size: max_width max_height'
131 ' (defaults to config specs)')
133 #TODO regenerate all thumbnails
136 # Reprocess all failed media
137 elif args
[0].state
== 'failed':
138 if args
[0].available
:
139 print _('\n Available reprocess actions for all failed'
140 ' media_entries: \n \t --initial_processing')
142 #TODO reprocess all failed entries
145 # If here, they didn't set the --type flag and were trying to do
146 # something other the generating thumbnails or initial_processing
148 raise Exception(_('You must set --type when trying to reprocess'
149 ' all media_entries, unless you set --state'
153 _run_reprocessing(args
)
156 def _run_reprocessing(args
):
157 # Are they just asking for the available reprocessing options for the given
159 if args
[0].available
:
160 if args
[0].state
== 'failed':
161 print _('\n Available reprocess actions for all failed'
162 ' media_entries: \n \t --initial_processing')
164 result
= hook_handle(('reprocess_action', args
[0].type), args
)
166 print _('Sorry there is no available reprocessing for {}'
167 ' entries in the {} state'.format(args
[0].type,
170 # Run media reprocessing
171 return hook_handle(('media_reprocess', args
[0].type), args
)
174 def _set_media_state(args
):
176 This will verify that all media id's are in the same state. If the
177 --state flag is set, it will be replaced by the given media id's state.
179 If they are trying to process different media states, an Exception will be
183 # Only check if we are given media_ids
184 if len(args
[0].media_id
) == 1:
185 args
[0].state
= MediaEntry
.query
.filter_by(id=args
[0].media_id
[0])\
188 elif len(args
[0].media_id
) > 1:
191 for id in args
[0].media_id
:
192 media_states
.append(MediaEntry
.query
.filter_by(id=id).first()
195 # Make sure that all media are in the same state
196 for state
in media_states
:
197 if state
!= media_states
[0]:
198 raise Exception(_('You can only reprocess media that is in'
201 args
[0].state
= media_states
[0]
203 # If no state was set, then we will default to the processed state
204 if not args
[0].state
:
205 args
[0].state
= 'processed'
208 class MediaEntryNotFound(Exception): pass
210 def extract_entry_and_type(media_id
):
212 Fetch a media entry, as well as its media type
214 entry
= MediaEntry
.query
.filter_by(id=media_id
).first()
216 raise MediaEntryNotFound("Can't find media with id '%s'" % media_id
)
218 return entry
.media_type
, entry
222 # Get the media type, either by looking up media id, or by specific type
224 media_id
= int(args
.id_or_type
)
225 media_type
, media_entry
= extract_entry_and_type(media_id
)
227 media_type
= args
.id_or_type
230 manager_class
= hook_handle(('reprocess_manager', media_type
))
231 manager
= manager_class()
233 if media_entry
is None:
234 processors
= manager
.list_all_processors()
236 processors
= manager
.list_eligible_processors(media_entry
)
238 print "Available processors:"
239 print "====================="
243 for processor
in processors
:
245 print "-" * len(processor
.name
)
247 parser
= processor
.generate_parser()
252 for processor
in processors
:
253 if processor
.description
:
254 print " - %s: %s" % (processor
.name
, processor
.description
)
256 print " - %s" % processor
.name
260 media_type
, media_entry
= extract_entry_and_type(args
.media_id
)
262 manager_class
= hook_handle(('reprocess_manager', media_type
))
263 manager
= manager_class()
265 # TOOD: Specify in error
267 processor_class
= manager
.get_processor(
268 args
.reprocess_command
, media_entry
)
269 except ProcessorDoesNotExist
:
270 print 'No such processor "%s" for media with id "%s"' % (
271 args
.reprocess_command
, media_entry
.id)
273 except ProcessorNotEligible
:
274 print 'Processor "%s" exists but media "%s" is not eligible' % (
275 args
.reprocess_command
, media_entry
.id)
278 reprocess_parser
= processor_class
.generate_parser()
279 reprocess_args
= reprocess_parser
.parse_args(args
.reprocess_args
)
286 # Run eagerly unless explicetly set not to
288 os
.environ
['CELERY_ALWAYS_EAGER'] = 'true'
290 commands_util
.setup_app(args
)
292 if args
.reprocess_subcommand
== "run":
295 elif args
.reprocess_subcommand
== "available":