Merge remote-tracking branch 'refs/remotes/rodney757/reprocessing'
[mediagoblin.git] / mediagoblin / media_types / ascii / processing.py
index 4cf8081a9fd96126f4120a06447cca26d39e08f5..ef4727de243d242e64fca703d8d80d44cb62f584 100644 (file)
@@ -26,7 +26,7 @@ from mediagoblin import mg_globals as mgg
 from mediagoblin.processing import (
     create_pub_filepath, FilenameBuilder,
     MediaProcessor, ProcessingManager,
-    get_orig_filename, copy_original,
+    get_process_filename, copy_original,
     store_public, request_from_args)
 from mediagoblin.media_types.ascii import asciitoimage
 
@@ -52,25 +52,27 @@ class CommonAsciiProcessor(MediaProcessor):
     """
     Provides a base for various ascii processing steps
     """
+    acceptable_files = ['original', 'unicode']
+
     def common_setup(self):
-        self.ascii_config = mgg.global_config[
-            'media_type:mediagoblin.media_types.ascii']
+        self.ascii_config = mgg.global_config['plugins'][
+            'mediagoblin.media_types.ascii']
 
          # Conversions subdirectory to avoid collisions
         self.conversions_subdir = os.path.join(
-            self.workbench.dir, 'convirsions')
+            self.workbench.dir, 'conversions')
         os.mkdir(self.conversions_subdir)
 
-        # Pull down and set up the original file
-        self.orig_filename = get_orig_filename(
-            self.entry, self.workbench)
-        self.name_builder = FilenameBuilder(self.orig_filename)
+        # Pull down and set up the processing file
+        self.process_filename = get_process_filename(
+            self.entry, self.workbench, self.acceptable_files)
+        self.name_builder = FilenameBuilder(self.process_filename)
 
         self.charset = None
 
     def copy_original(self):
         copy_original(
-            self.entry, self.orig_filename,
+            self.entry, self.process_filename,
             self.name_builder.fill('{basename}{ext}'))
 
     def _detect_charset(self, orig_file):
@@ -87,8 +89,11 @@ class CommonAsciiProcessor(MediaProcessor):
                   d_charset,
                   self.charset))
 
+        # Rewind the file
+        orig_file.seek(0)
+
     def store_unicode_file(self):
-        with file(self.orig_filename, 'rb') as orig_file:
+        with file(self.process_filename, 'rb') as orig_file:
             self._detect_charset(orig_file)
             unicode_filepath = create_pub_filepath(self.entry,
                                                    'ascii-portable.txt')
@@ -107,7 +112,7 @@ class CommonAsciiProcessor(MediaProcessor):
         self.entry.media_files['unicode'] = unicode_filepath
 
     def generate_thumb(self, font=None, thumb_size=None):
-        with file(self.orig_filename, 'rb') as orig_file:
+        with file(self.process_filename, 'rb') as orig_file:
             # If no font kwarg, check config
             if not font:
                 font = self.ascii_config.get('thumbnail_font', None)
@@ -115,6 +120,9 @@ class CommonAsciiProcessor(MediaProcessor):
                 thumb_size = (mgg.global_config['media:thumb']['max_width'],
                               mgg.global_config['media:thumb']['max_height'])
 
+            if self._skip_resizing(font, thumb_size):
+                return
+
             tmp_thumb = os.path.join(
                 self.conversions_subdir,
                 self.name_builder.fill('{basename}.thumbnail.png'))
@@ -139,10 +147,33 @@ class CommonAsciiProcessor(MediaProcessor):
                     Image.ANTIALIAS)
                 thumb.save(thumb_file)
 
+            thumb_info = {'font': font,
+                          'width': thumb_size[0],
+                          'height': thumb_size[1]}
+
+            self.entry.set_file_metadata('thumb', **thumb_info)
+
             _log.debug('Copying local file to public storage')
             store_public(self.entry, 'thumb', tmp_thumb,
                          self.name_builder.fill('{basename}.thumbnail.jpg'))
 
+        def _skip_resizing(self, font, thumb_size):
+            thumb_info = self.entry.get_file_metadata('thumb')
+
+            if not thumb_info:
+                return False
+
+            skip = True
+
+            if thumb_info.get('font') != font:
+                skip = False
+            elif thumb_info.get('width') != thumb_size[0]:
+                skip = False
+            elif thumb_info.get('height') != thumb_size[1]:
+                skip = False
+
+            return skip
+
 
 class InitialProcessor(CommonAsciiProcessor):
     """
@@ -189,7 +220,56 @@ class InitialProcessor(CommonAsciiProcessor):
         self.delete_queue_file()
 
 
+class Resizer(CommonAsciiProcessor):
+    """
+    Resizing process steps for processed media
+    """
+    name = 'resize'
+    description = 'Resize thumbnail'
+    thumb_size = 'thumb_size'
+
+    @classmethod
+    def media_is_eligible(cls, entry=None, state=None):
+        """
+        Determine if this media type is eligible for processing
+        """
+        if not state:
+            state = entry.state
+        return state in 'processed'
+
+    @classmethod
+    def generate_parser(cls):
+        parser = argparse.ArgumentParser(
+            description=cls.description,
+            prog=cls.name)
+
+        parser.add_argument(
+            '--thumb_size',
+            nargs=2,
+            metavar=('max_width', 'max_height'),
+            type=int)
+
+        # Needed for gmg reprocess thumbs to work
+        parser.add_argument(
+            'file',
+            nargs='?',
+            default='thumb',
+            choices=['thumb'])
+
+        return parser
+
+    @classmethod
+    def args_to_request(cls, args):
+        return request_from_args(
+            args, ['thumb_size', 'file'])
+
+    def process(self, thumb_size=None, file=None):
+        self.common_setup()
+        self.generate_thumb(thumb_size=thumb_size)
+
+
 class AsciiProcessingManager(ProcessingManager):
     def __init__(self):
         super(self.__class__, self).__init__()
         self.add_processor(InitialProcessor)
+        self.add_processor(Resizer)