trac#687: Add unit tests for `redirect` and `redirect_obj`.
[larjonas-mediagoblin.git] / mediagoblin / gmg_commands / reprocess.py
blob85cae6df0301c65c4ac94acc2ffb851bbfc29501
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/>.
17 from __future__ import print_function
19 import argparse
20 import os
22 from mediagoblin import mg_globals
23 from mediagoblin.db.models import MediaEntry
24 from mediagoblin.gmg_commands import util as commands_util
25 from mediagoblin.submit.lib import run_process_media
26 from mediagoblin.tools.translate import lazy_pass_to_ugettext as _
27 from mediagoblin.tools.pluginapi import hook_handle
28 from mediagoblin.processing import (
29 ProcessorDoesNotExist, ProcessorNotEligible,
30 get_entry_and_processing_manager, get_processing_manager_for_type,
31 ProcessingManagerDoesNotExist)
34 def reprocess_parser_setup(subparser):
35 subparser.add_argument(
36 '--celery',
37 action='store_true',
38 help="Don't process eagerly, pass off to celery")
40 subparsers = subparser.add_subparsers(dest="reprocess_subcommand")
42 ###################
43 # available command
44 ###################
45 available_parser = subparsers.add_parser(
46 "available",
47 help="Find out what actions are available for this media")
49 available_parser.add_argument(
50 "id_or_type",
51 help="Media id or media type to check")
53 available_parser.add_argument(
54 "--action-help",
55 action="store_true",
56 help="List argument help for each action available")
58 available_parser.add_argument(
59 "--state",
60 help="The state of media you would like to reprocess")
63 #############
64 # run command
65 #############
67 run_parser = subparsers.add_parser(
68 "run",
69 help="Run a reprocessing on one or more media")
71 run_parser.add_argument(
72 'media_id',
73 help="The media_entry id(s) you wish to reprocess.")
75 run_parser.add_argument(
76 'reprocess_command',
77 help="The reprocess command you intend to run")
79 run_parser.add_argument(
80 'reprocess_args',
81 nargs=argparse.REMAINDER,
82 help="rest of arguments to the reprocessing tool")
85 ################
86 # thumbs command
87 ################
88 thumbs = subparsers.add_parser(
89 'thumbs',
90 help='Regenerate thumbs for all processed media')
92 thumbs.add_argument(
93 '--size',
94 nargs=2,
95 type=int,
96 metavar=('max_width', 'max_height'))
98 #################
99 # initial command
100 #################
101 subparsers.add_parser(
102 'initial',
103 help='Reprocess all failed media')
105 ##################
106 # bulk_run command
107 ##################
108 bulk_run_parser = subparsers.add_parser(
109 'bulk_run',
110 help='Run reprocessing on a given media type or state')
112 bulk_run_parser.add_argument(
113 'type',
114 help='The type of media you would like to process')
116 bulk_run_parser.add_argument(
117 '--state',
118 default='processed',
119 nargs='?',
120 help='The state of the media you would like to process. Defaults to' \
121 " 'processed'")
123 bulk_run_parser.add_argument(
124 'reprocess_command',
125 help='The reprocess command you intend to run')
127 bulk_run_parser.add_argument(
128 'reprocess_args',
129 nargs=argparse.REMAINDER,
130 help='The rest of the arguments to the reprocessing tool')
132 ###############
133 # help command?
134 ###############
137 def available(args):
138 # Get the media type, either by looking up media id, or by specific type
139 try:
140 media_id = int(args.id_or_type)
141 media_entry, manager = get_entry_and_processing_manager(media_id)
142 media_type = media_entry.media_type
143 except ValueError:
144 media_type = args.id_or_type
145 media_entry = None
146 manager = get_processing_manager_for_type(media_type)
147 except ProcessingManagerDoesNotExist:
148 entry = MediaEntry.query.filter_by(id=args.id_or_type).first()
149 print('No such processing manager for {0}'.format(entry.media_type))
151 if args.state:
152 processors = manager.list_all_processors_by_state(args.state)
153 elif media_entry is None:
154 processors = manager.list_all_processors()
155 else:
156 processors = manager.list_eligible_processors(media_entry)
158 print("Available processors:")
159 print("=====================")
160 print("")
162 if args.action_help:
163 for processor in processors:
164 print(processor.name)
165 print("-" * len(processor.name))
167 parser = processor.generate_parser()
168 parser.print_help()
169 print("")
171 else:
172 for processor in processors:
173 if processor.description:
174 print(" - %s: %s" % (processor.name, processor.description))
175 else:
176 print(" - %s" % processor.name)
179 def run(args, media_id=None):
180 if not media_id:
181 media_id = args.media_id
182 try:
183 media_entry, manager = get_entry_and_processing_manager(media_id)
185 # TODO: (maybe?) This could probably be handled entirely by the
186 # processor class...
187 try:
188 processor_class = manager.get_processor(
189 args.reprocess_command, media_entry)
190 except ProcessorDoesNotExist:
191 print('No such processor "%s" for media with id "%s"' % (
192 args.reprocess_command, media_entry.id))
193 return
194 except ProcessorNotEligible:
195 print('Processor "%s" exists but media "%s" is not eligible' % (
196 args.reprocess_command, media_entry.id))
197 return
199 reprocess_parser = processor_class.generate_parser()
200 reprocess_args = reprocess_parser.parse_args(args.reprocess_args)
201 reprocess_request = processor_class.args_to_request(reprocess_args)
202 run_process_media(
203 media_entry,
204 reprocess_action=args.reprocess_command,
205 reprocess_info=reprocess_request)
207 except ProcessingManagerDoesNotExist:
208 entry = MediaEntry.query.filter_by(id=media_id).first()
209 print('No such processing manager for {0}'.format(entry.media_type))
212 def bulk_run(args):
214 Bulk reprocessing of a given media_type
216 query = MediaEntry.query.filter_by(media_type=args.type,
217 state=args.state)
219 for entry in query:
220 run(args, entry.id)
223 def thumbs(args):
225 Regenerate thumbs for all processed media
227 query = MediaEntry.query.filter_by(state='processed')
229 for entry in query:
230 try:
231 media_entry, manager = get_entry_and_processing_manager(entry.id)
233 # TODO: (maybe?) This could probably be handled entirely by the
234 # processor class...
235 try:
236 processor_class = manager.get_processor(
237 'resize', media_entry)
238 except ProcessorDoesNotExist:
239 print('No such processor "%s" for media with id "%s"' % (
240 'resize', media_entry.id))
241 return
242 except ProcessorNotEligible:
243 print('Processor "%s" exists but media "%s" is not eligible' % (
244 'resize', media_entry.id))
245 return
247 reprocess_parser = processor_class.generate_parser()
249 # prepare filetype and size to be passed into reprocess_parser
250 if args.size:
251 extra_args = 'thumb --{0} {1} {2}'.format(
252 processor_class.thumb_size,
253 args.size[0],
254 args.size[1])
255 else:
256 extra_args = 'thumb'
258 reprocess_args = reprocess_parser.parse_args(extra_args.split())
259 reprocess_request = processor_class.args_to_request(reprocess_args)
260 run_process_media(
261 media_entry,
262 reprocess_action='resize',
263 reprocess_info=reprocess_request)
265 except ProcessingManagerDoesNotExist:
266 print('No such processing manager for {0}'.format(entry.media_type))
269 def initial(args):
271 Reprocess all failed media
273 query = MediaEntry.query.filter_by(state='failed')
275 for entry in query:
276 try:
277 media_entry, manager = get_entry_and_processing_manager(entry.id)
278 run_process_media(
279 media_entry,
280 reprocess_action='initial')
281 except ProcessingManagerDoesNotExist:
282 print('No such processing manager for {0}'.format(entry.media_type))
285 def reprocess(args):
286 # Run eagerly unless explicetly set not to
287 if not args.celery:
288 os.environ['CELERY_ALWAYS_EAGER'] = 'true'
290 commands_util.setup_app(args)
292 if args.reprocess_subcommand == "run":
293 run(args)
295 elif args.reprocess_subcommand == "available":
296 available(args)
298 elif args.reprocess_subcommand == "bulk_run":
299 bulk_run(args)
301 elif args.reprocess_subcommand == "thumbs":
302 thumbs(args)
304 elif args.reprocess_subcommand == "initial":
305 initial(args)