imgrate/cli.py

71 lines
2.5 KiB
Python
Executable File

#!/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()()