Make changes for displaying page listing all the blogs created by user.
[mediagoblin.git] / mediagoblin / gmg_commands / reprocess.py
index 4df0d5817607b24e8fa085b38d38d3160c00f949..e2f19ea3f99da81aa78575f9b905689d59f44cf0 100644 (file)
 #
 # 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 argparse
 import os
 
 from mediagoblin import mg_globals
 from mediagoblin.db.models import MediaEntry
 from mediagoblin.gmg_commands import util as commands_util
+from mediagoblin.submit.lib import run_process_media
 from mediagoblin.tools.translate import lazy_pass_to_ugettext as _
 from mediagoblin.tools.pluginapi import hook_handle
+from mediagoblin.processing import (
+    ProcessorDoesNotExist, ProcessorNotEligible,
+    get_entry_and_processing_manager, get_processing_manager_for_type,
+    ProcessingManagerDoesNotExist)
 
 
 def reprocess_parser_setup(subparser):
-    subparser.add_argument(
-        '--available', '-a',
-        action="store_true",
-        help="List available actions for a given media entry")
-    subparser.add_argument(
-        '--state', '-s',
-        help="Reprocess media entries in this state"
-             " such as 'failed' or 'processed'")
-    subparser.add_argument(
-        '--type', '-t',
-        help="The type of media to be reprocessed such as 'video' or 'image'")
-    subparser.add_argument(
-        '--media_id',
-        nargs='*',
-        help="The media_entry id(s) you wish to reprocess.")
-    subparser.add_argument(
-        '--thumbnails',
-        action="store_true",
-        help="Regenerate thumbnails for all processed media")
     subparser.add_argument(
         '--celery',
         action='store_true',
         help="Don't process eagerly, pass off to celery")
 
+    subparsers = subparser.add_subparsers(dest="reprocess_subcommand")
 
-def _set_media_type(args):
-    """
-    This will verify that all media id's are of the same media_type. If the
-    --type flag is set, it will be replaced by the given media id's type.
+    ###################
+    # available command
+    ###################
+    available_parser = subparsers.add_parser(
+        "available",
+        help="Find out what actions are available for this media")
 
-    If they are trying to process different media types, an Exception will be
-    raised.
-    """
-    if args[0].media_id:
-        if len(args[0].media_id) == 1:
-            args[0].type = MediaEntry.query.filter_by(id=args[0].media_id[0])\
-                .first().media_type.split('.')[-1]
+    available_parser.add_argument(
+        "id_or_type",
+        help="Media id or media type to check")
 
-        elif len(args[0].media_id) > 1:
-            media_types = []
+    available_parser.add_argument(
+        "--action-help",
+        action="store_true",
+        help="List argument help for each action available")
 
-            for id in args[0].media_id:
-                media_types.append(MediaEntry.query.filter_by(id=id).first()
-                                   .media_type.split('.')[-1])
-            for type in media_types:
-                if media_types[0] != type:
-                    raise Exception((u'You cannot reprocess different'
-                                     ' media_types at the same time.'))
+    available_parser.add_argument(
+        "--state",
+        help="The state of media you would like to reprocess")
 
-            args[0].type = media_types[0]
 
+    #############
+    # run command
+    #############
 
-def _reprocess_all(args):
-    """
-    This handles reprocessing if no media_id's are given.
-    """
-    if not args[0].type:
-        # If no media type is given, we can either regenerate all thumbnails,
-        # or try to reprocess all failed media
-
-        if args[0].thumbnails:
-            if args[0].available:
-                print _('Available options for regenerating all processed'
-                        ' media thumbnails: \n'
-                        '\t --size: max_width max_height'
-                        ' (defaults to config specs)')
-            else:
-                #TODO regenerate all thumbnails
-                pass
-
-        # Reprocess all failed media
-        elif args[0].state == 'failed':
-            if args[0].available:
-                print _('\n Available reprocess actions for all failed'
-                        ' media_entries: \n \t --initial_processing')
-            else:
-                #TODO reprocess all failed entries
-                pass
+    run_parser = subparsers.add_parser(
+        "run",
+        help="Run a reprocessing on one or more media")
+
+    run_parser.add_argument(
+        'media_id',
+        help="The media_entry id(s) you wish to reprocess.")
+
+    run_parser.add_argument(
+        'reprocess_command',
+        help="The reprocess command you intend to run")
+
+    run_parser.add_argument(
+        'reprocess_args',
+        nargs=argparse.REMAINDER,
+        help="rest of arguments to the reprocessing tool")
+
+
+    ################
+    # thumbs command
+    ################
+    thumbs = subparsers.add_parser(
+        'thumbs',
+        help='Regenerate thumbs for all processed media')
+
+    thumbs.add_argument(
+        '--size',
+        nargs=2,
+        type=int,
+        metavar=('max_width', 'max_height'))
+
+    #################
+    # initial command
+    #################
+    subparsers.add_parser(
+        'initial',
+        help='Reprocess all failed media')
+
+    ##################
+    # bulk_run command
+    ##################
+    bulk_run_parser = subparsers.add_parser(
+        'bulk_run',
+        help='Run reprocessing on a given media type or state')
+
+    bulk_run_parser.add_argument(
+        'type',
+        help='The type of media you would like to process')
+
+    bulk_run_parser.add_argument(
+        '--state',
+        default='processed',
+        nargs='?',
+        help='The state of the media you would like to process. Defaults to' \
+             " 'processed'")
+
+    bulk_run_parser.add_argument(
+        'reprocess_command',
+        help='The reprocess command you intend to run')
 
-        # If here, they didn't set the --type flag and were trying to do
-        # something other the generating thumbnails or initial_processing
-        else:
-            raise Exception(_('You must set --type when trying to reprocess'
-                              ' all media_entries, unless you set --state'
-                              ' to "failed".'))
+    bulk_run_parser.add_argument(
+        'reprocess_args',
+        nargs=argparse.REMAINDER,
+        help='The rest of the arguments to the reprocessing tool')
 
+    ###############
+    # help command?
+    ###############
+
+
+def available(args):
+    # Get the media type, either by looking up media id, or by specific type
+    try:
+        media_id = int(args.id_or_type)
+        media_entry, manager = get_entry_and_processing_manager(media_id)
+        media_type = media_entry.media_type
+    except ValueError:
+        media_type = args.id_or_type
+        media_entry = None
+        manager = get_processing_manager_for_type(media_type)
+    except ProcessingManagerDoesNotExist:
+        entry = MediaEntry.query.filter_by(id=args.id_or_type).first()
+        print 'No such processing manager for {0}'.format(entry.media_type)
+
+    if args.state:
+        processors = manager.list_all_processors_by_state(args.state)
+    elif media_entry is None:
+        processors = manager.list_all_processors()
     else:
-        _run_reprocessing(args)
-
-
-def _run_reprocessing(args):
-    # Are they just asking for the available reprocessing options for the given
-    # media?
-    if args[0].available:
-        if args[0].state == 'failed':
-            print _('\n Available reprocess actions for all failed'
-                    ' media_entries: \n \t --initial_processing')
-        else:
-            result = hook_handle(('reprocess_action', args[0].type), args)
-            if not result:
-                print _('Sorry there is no available reprocessing for {}'
-                        ' entries in the {} state'.format(args[0].type,
-                                                          args[0].state))
+        processors = manager.list_eligible_processors(media_entry)
+
+    print "Available processors:"
+    print "====================="
+    print ""
+
+    if args.action_help:
+        for processor in processors:
+            print processor.name
+            print "-" * len(processor.name)
+
+            parser = processor.generate_parser()
+            parser.print_help()
+            print ""
+
     else:
-        # Run media reprocessing
-        return hook_handle(('media_reprocess', args[0].type), args)
+        for processor in processors:
+            if processor.description:
+                print " - %s: %s" % (processor.name, processor.description)
+            else:
+                print " - %s" % processor.name
+
+
+def run(args, media_id=None):
+    if not media_id:
+        media_id = args.media_id
+    try:
+        media_entry, manager = get_entry_and_processing_manager(media_id)
+
+        # TODO: (maybe?) This could probably be handled entirely by the
+        # processor class...
+        try:
+            processor_class = manager.get_processor(
+                args.reprocess_command, media_entry)
+        except ProcessorDoesNotExist:
+            print 'No such processor "%s" for media with id "%s"' % (
+                args.reprocess_command, media_entry.id)
+            return
+        except ProcessorNotEligible:
+            print 'Processor "%s" exists but media "%s" is not eligible' % (
+                args.reprocess_command, media_entry.id)
+            return
 
+        reprocess_parser = processor_class.generate_parser()
+        reprocess_args = reprocess_parser.parse_args(args.reprocess_args)
+        reprocess_request = processor_class.args_to_request(reprocess_args)
+        run_process_media(
+            media_entry,
+            reprocess_action=args.reprocess_command,
+            reprocess_info=reprocess_request)
 
-def _set_media_state(args):
+    except ProcessingManagerDoesNotExist:
+        entry = MediaEntry.query.filter_by(id=media_id).first()
+        print 'No such processing manager for {0}'.format(entry.media_type)
+
+
+def bulk_run(args):
+    """
+    Bulk reprocessing of a given media_type
     """
-    This will verify that all media id's are in the same state. If the
-    --state flag is set, it will be replaced by the given media id's state.
+    query = MediaEntry.query.filter_by(media_type=args.type,
+                                       state=args.state)
 
-    If they are trying to process different media states, an Exception will be
-    raised.
+    for entry in query:
+        run(args, entry.id)
+
+
+def thumbs(args):
     """
-    if args[0].media_id:
-        # Only check if we are given media_ids
-        if len(args[0].media_id) == 1:
-            args[0].state = MediaEntry.query.filter_by(id=args[0].media_id[0])\
-                .first().state
+    Regenerate thumbs for all processed media
+    """
+    query = MediaEntry.query.filter_by(state='processed')
 
-        elif len(args[0].media_id) > 1:
-            media_states = []
+    for entry in query:
+        try:
+            media_entry, manager = get_entry_and_processing_manager(entry.id)
 
-            for id in args[0].media_id:
-                media_states.append(MediaEntry.query.filter_by(id=id).first()
-                                    .state)
+            # TODO: (maybe?) This could probably be handled entirely by the
+            # processor class...
+            try:
+                processor_class = manager.get_processor(
+                    'resize', media_entry)
+            except ProcessorDoesNotExist:
+                print 'No such processor "%s" for media with id "%s"' % (
+                    'resize', media_entry.id)
+                return
+            except ProcessorNotEligible:
+                print 'Processor "%s" exists but media "%s" is not eligible' % (
+                    'resize', media_entry.id)
+                return
 
-            # Make sure that all media are in the same state
-            for state in media_states:
-                if state != media_states[0]:
-                    raise Exception(_('You can only reprocess media that is in'
-                                      ' the same state.'))
+            reprocess_parser = processor_class.generate_parser()
 
-            args[0].state = media_states[0]
+            # prepare filetype and size to be passed into reprocess_parser
+            if args.size:
+                extra_args = 'thumb --{0} {1} {2}'.format(
+                    processor_class.thumb_size,
+                    args.size[0],
+                    args.size[1])
+            else:
+                extra_args = 'thumb'
 
-    # If no state was set, then we will default to the processed state
-    if not args[0].state:
-        args[0].state = 'processed'
+            reprocess_args = reprocess_parser.parse_args(extra_args.split())
+            reprocess_request = processor_class.args_to_request(reprocess_args)
+            run_process_media(
+                media_entry,
+                reprocess_action='resize',
+                reprocess_info=reprocess_request)
+
+        except ProcessingManagerDoesNotExist:
+            print 'No such processing manager for {0}'.format(entry.media_type)
+
+
+def initial(args):
+    """
+    Reprocess all failed media
+    """
+    query = MediaEntry.query.filter_by(state='failed')
+
+    for entry in query:
+        try:
+            media_entry, manager = get_entry_and_processing_manager(entry.id)
+            run_process_media(
+                media_entry,
+                reprocess_action='initial')
+        except ProcessingManagerDoesNotExist:
+            print 'No such processing manager for {0}'.format(entry.media_type)
 
 
 def reprocess(args):
     # Run eagerly unless explicetly set not to
-    if not args[0].celery:
+    if not args.celery:
         os.environ['CELERY_ALWAYS_EAGER'] = 'true'
-    commands_util.setup_app(args[0])
 
-    _set_media_state(args)
-    _set_media_type(args)
+    commands_util.setup_app(args)
+
+    if args.reprocess_subcommand == "run":
+        run(args)
+
+    elif args.reprocess_subcommand == "available":
+        available(args)
+
+    elif args.reprocess_subcommand == "bulk_run":
+        bulk_run(args)
 
-    # If no media_ids were given, then try to reprocess all entries
-    if not args[0].media_id:
-        return _reprocess_all(args)
+    elif args.reprocess_subcommand == "thumbs":
+        thumbs(args)
 
-    return _run_reprocessing(args)
+    elif args.reprocess_subcommand == "initial":
+        initial(args)