diff --git a/main.py b/main.py index b4b20a2..a1b2012 100644 --- a/main.py +++ b/main.py @@ -1,11 +1,11 @@ import sys import os import logging -from package import app +from package import log, app os.environ["GOOGLE_APPLICATION_CREDENTIALS"] = os.path.join( sys.path[0], 'package', 'key', 'photo_tagging_service.json') if __name__ == "__main__": - logging.info('Executing package...') + log.info('Executing package...') sys.exit(app.run()) diff --git a/package/__init__.py b/package/__init__.py index c43ec7e..0bc0c82 100644 --- a/package/__init__.py +++ b/package/__init__.py @@ -1,8 +1,12 @@ import os import sys import logging +import progressbar +# Logging and Progressbar work +progressbar.streams.wrap_stderr() logging.basicConfig(level=logging.INFO) +log = logging.getLogger(__name__) # Path Constants ROOT = sys.path[0] @@ -10,7 +14,7 @@ PROCESSING_PATH = os.path.join(ROOT, 'package', 'processing') INPUT_PATH = os.path.join(PROCESSING_PATH, 'input') TEMP_PATH = os.path.join(PROCESSING_PATH, 'temp') OUTPUT_PATH = os.path.join(PROCESSING_PATH, 'output') -logging.info('Path Constants Built.') +log.info('Path Constants Built.') # Extension Constants RAW_EXTS = [ diff --git a/package/app.py b/package/app.py index 043194a..63572f8 100644 --- a/package/app.py +++ b/package/app.py @@ -42,9 +42,9 @@ def run(): _, ext = os.path.splitext(file) ext = ext[1:] if ext in LOSSY_EXTS or ext in RAW_EXTS: - file = FileProcessor(file) + process = FileProcessor(file) logging.info(f"Processing file '{file}'...") - file.run(client) + process.run(client) except Exception as error: logging.error(str(error)) logging.warning( diff --git a/package/process.py b/package/process.py index 599d164..746bd5c 100644 --- a/package/process.py +++ b/package/process.py @@ -9,21 +9,26 @@ from PIL import Image from google.cloud.vision import types from google.cloud import vision -from . import TEMP_PATH, INPUT_PATH, OUTPUT_PATH +from . import TEMP_PATH, INPUT_PATH, OUTPUT_PATH, RAW_EXTS, LOSSY_EXTS from .xmp import XMPParser class FileProcessor(object): def __init__(self, file_name: str): self.file_name = file_name - self.base, self.ext = os.path.splitext( - self.file_name) # fileNAME and fileEXTENSIOn + self.base, self.ext = os.path.splitext(self.file_name) + self.ext = self.ext[1:] # Path to temporary file that will be optimized for upload to Google self.temp_file_path = os.path.join(TEMP_PATH, self.base + '.jpeg') # Decide whether a XMP file is available - self.xmp = os.path.join(INPUT_PATH, base + '.xmp') - self.xmp = self.xmp if os.path.exists(self.xmp) else None - + self.xmp = None + if self.ext.lower() in RAW_EXTS: + self.xmp = self.base + '.xmp' + self.input_xmp = os.path.join(INPUT_PATH, self.xmp) + self.output_xmp = os.path.join(OUTPUT_PATH, self.xmp) + if not os.path.exists(self.input_xmp): + raise Exception('Sidecar file for \'{}\' does not exist.'.format(self.xmp)) + # Optimizes a file using JPEG thumbnailing and compression. def _optimize(self, file: str, size: tuple = (512, 512), quality : int = 85, copy : str = None): image = Image.open(file) @@ -34,7 +39,7 @@ class FileProcessor(object): image.save(file, format='jpeg', optimize=True, quality=quality) def optimize(self): - if self.hasXMP: + if self.xmp: # Long runn rgb = rawpy.imread(os.path.join(INPUT_PATH, self.file_name)) imageio.imsave(self.temp_file_path, rgb.postprocess()) @@ -46,7 +51,6 @@ class FileProcessor(object): def run(self, client: vision.ImageAnnotatorClient): try: - self.optimize() # Open the image, read as bytes, convert to types Image @@ -59,32 +63,30 @@ class FileProcessor(object): # Performs label detection on the image file response = client.label_detection(image=image) labels = [label.description for label in response.label_annotations] - print('\tLabels: {}'.format(', '.join(labels))) + logging.info('Keywords Identified: {}'.format(', '.join(labels))) # XMP sidecar file specified, write to it using XML module - if self.hasXMP: - logging.info( - '\tWriting {} tags to output XMP.'.format(len(labels))) - parser = XMPParser(os.path.join(INPUT_PATH, self.xmp_name)) + if self.xmp: + logging.info('Writing {} tags to output XMP.'.format(len(labels))) + parser = XMPParser(self.input_xmp) parser.add_keywords(labels) # Save the new XMP file - loggin.debug('Saving to new XMP file.') - parser.save(os.path.join(OUTPUT_PATH, self.xmp_name)) + logging.debug('Saving to new XMP file.') + parser.save(self.output_xmp) logging.debug('Removing old XMP file.') - os.remove(os.path.join(INPUT_PATH, self.xmp_name)) + os.remove(self.input_xmp) # No XMP file is specified, using IPTC tagging else: - logging.info( - '\tWriting {} tags to image IPTC'.format(len(labels))) - info = iptcinfo3.IPTCInfo( - os.path.join(INPUT_PATH, self.file_name)) + logging.info('Writing {} tags to image IPTC'.format(len(labels))) + info = iptcinfo3.IPTCInfo(os.path.join(INPUT_PATH, self.file_name)) info['keywords'].extend(labels) info.save() # Remove the weird ghsot file created by this iptc read/writer. os.remove(os.path.join(INPUT_PATH, self.file_name + '~')) + # Copy dry-run # shutil.copy2(os.path.join(INPUT_PATH, self.file_name), os.path.join(OUTPUT_PATH, self.file_name)) - # os.rename(os.path.join(INPUT_PATH, self.file_name), os.path.join(OUTPUT_PATH, self.file_name)) + os.rename(os.path.join(INPUT_PATH, self.file_name), os.path.join(OUTPUT_PATH, self.file_name)) except: self._cleanup() raise