#!/usr/bin/env python3 from argparse import ArgumentParser from os import remove from sys import exit from signal import signal, SIGINT from multiprocessing import Pool, cpu_count from imgrate import imgrate class Cli: def __init__(self): self.args = None self.image_ratings = None self.best_image = None def __call__(self): self.parse_arguments() if not hasattr(imgrate, self.args.method): exit('Invalid --method option!') self.calculate_ratings() self.best_image = max(self.image_ratings, key=self.image_ratings.get) self.print_ratings() if self.args.delete: self.keep_best_quality_image_only() def parse_arguments(self): ap = ArgumentParser(description='Find the best quality one among similar images.' 'Note: image dimensions should match!') ap.add_argument('images', type=str, nargs='+', help='') ap.add_argument('-d', '--delete', action='store_true', help='Delete all but the best quality image.') ap.add_argument('-q', '--quiet', action='store_true', help='Print quality measurements only.') ap.add_argument('-m', '--method', type=str, default='quality', help='Select quality measurement to use.') self.args = ap.parse_args() def calculate_ratings(self): with Pool(processes=cpu_count()) as pool: ratings = [(image, pool.apply_async(self.rate_image, (image, self.args.method))) for image in self.args.images] self.image_ratings = {image: promise.get() for image, promise in ratings} @staticmethod def rate_image(image, method): return getattr(imgrate(image), method) def print_ratings(self): for image in self.image_ratings.keys(): if self.args.quiet: print(self.image_ratings[image]) else: max_marker = '*' if image == self.best_image and len(self.image_ratings) > 1 else ' ' print(f'{max_marker}imgrate("{image}") = {self.image_ratings[image]}') def keep_best_quality_image_only(self): for image in self.image_ratings.keys(): if image != self.best_image: remove(image) if __name__ == '__main__': signal(SIGINT, lambda a, b: exit('\nExiting!')) Cli()()