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