Last active
January 5, 2016 22:21
-
-
Save maxmoriss/7a7a316130527a09aebc to your computer and use it in GitHub Desktop.
Script attempts to find images with equal dimensions and move it to another directory.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # -*- coding: utf-8 -*- | |
| import os | |
| import sys | |
| from PIL import Image | |
| from shutil import move | |
| from stat import S_IWRITE | |
| from argparse import ArgumentParser | |
| from abc import ABCMeta, abstractmethod | |
| class ProcessBase: | |
| """ Abstract base class for file processors. | |
| """ | |
| __metaclass__ = ABCMeta | |
| def __init__(self): | |
| self.extensions = [] | |
| @abstractmethod | |
| def processfile(self, filename): | |
| """ Abstract method which carries out the process on the specified file. | |
| Returns True if successful, False otherwise. | |
| """ | |
| pass | |
| def processdir(self, path): | |
| """ Recursively processes files in the specified directory matching | |
| the self.extensions list (case-insensitively). | |
| """ | |
| filecount = 0 # Number of files successfully updated | |
| for root, dirs, files in os.walk(path): | |
| for file in files: | |
| # Check file extensions against allowed list | |
| lowercasefile = file.lower() | |
| matches = False | |
| for ext in self.extensions: | |
| if lowercasefile.endswith('.' + ext): | |
| matches = True | |
| break | |
| if matches: | |
| # File has eligible extension, so process | |
| fullpath = os.path.join(root, file) | |
| if self.processfile(fullpath): | |
| filecount = filecount + 1 | |
| return filecount | |
| class ProcessImage(ProcessBase): | |
| """ Processor which attempts to find images with equal dimensions | |
| and move it to another directory | |
| """ | |
| def __init__(self, args): | |
| super(ProcessImage, self).__init__() | |
| self.extensions = ['jpg', 'jpeg', 'png'] | |
| self.path = args.path | |
| def processfile(self, filename): | |
| # Skip read-only files | |
| if (not os.stat(filename)[0] & S_IWRITE): | |
| print 'Ignoring read-only file "%s"' % filename | |
| return False | |
| ok = False | |
| try: | |
| # Open the image | |
| with open(filename, 'rb') as file: | |
| img = Image.open(file) | |
| # Check that it's a supported format | |
| format = str(img.format) | |
| if format != 'PNG' and format != 'JPEG': | |
| print 'Ignoring file "%s" with unsupported format %s' % \ | |
| (filename, format) | |
| return False | |
| width, height = img.size | |
| if width == height: | |
| destination = os.path.abspath( | |
| os.path.join(self.path, 'thumbnails') | |
| ) | |
| move(filename, destination) | |
| # Successful | |
| ok = True | |
| except Exception as e: | |
| sys.stderr.write('Failure whilst processing "%s": %s\n' % \ | |
| (filename, str(e))) | |
| return ok | |
| if __name__ == "__main__": | |
| # Argument parsing | |
| parser = ArgumentParser(description='Find images with equal dimensions') | |
| parser.add_argument( | |
| '--path', | |
| help='Directory name') | |
| args = parser.parse_args() | |
| # Construct processor requested mode | |
| processor = ProcessImage(args) | |
| # Run according to whether path is a file or a directory | |
| if os.path.isfile(args.path): | |
| sys.stderr.write('Supported directories only.\n') | |
| exit(1) | |
| elif os.path.isdir(args.path): | |
| filecount = processor.processdir(args.path) | |
| print '\nSuccessfully updated file count: %s' % str(filecount) | |
| else: | |
| sys.stderr.write('Invalid path "%s"\n' % args.path) | |
| exit(1) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment