Script attempts to find images with equal dimensions and move it to another directory.
# -*- 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)