Add option to configure folder

This commit is contained in:
Antonio J. Delgado 2022-09-05 15:14:03 +03:00
parent d9fd9255cc
commit 1c8c6a7991
2 changed files with 18 additions and 13 deletions

View file

@ -4,4 +4,5 @@ Classifies images by their EXIF date (e.g. /path/YYYY.MM.DD/image.jpg).
= Install = Install
apt install exiv2 cmake libexiv2-dev libboost-python-dev
python3 setup.py install python3 setup.py install

View file

@ -17,6 +17,7 @@ from logging.handlers import SysLogHandler
import face_recognition import face_recognition
import pyexiv2 import pyexiv2
import PIL import PIL
import datetime
class CustomFormatter(logging.Formatter): class CustomFormatter(logging.Formatter):
@ -49,7 +50,7 @@ class CustomFormatter(logging.Formatter):
class image_classifier: class image_classifier:
def __init__(self, debug_level, log_file, faces_directory, directory, no_move, def __init__(self, debug_level, log_file, faces_directory, directory, no_move,
people_folder, recursive): people_folder, recursive, folder_date_format):
''' Initial function called when object is created ''' ''' Initial function called when object is created '''
self.debug_level = debug_level self.debug_level = debug_level
if log_file is None: if log_file is None:
@ -66,6 +67,7 @@ class image_classifier:
self.no_move = no_move self.no_move = no_move
self.people_folder = people_folder self.people_folder = people_folder
self.recursive = recursive self.recursive = recursive
self.folder_date_format = folder_date_format
if self.recursive: if self.recursive:
entries = self.recursive_scandir(directory) entries = self.recursive_scandir(directory)
@ -122,32 +124,32 @@ class image_classifier:
if not os.access(file, os.R_OK): if not os.access(file, os.R_OK):
self._log.error(f"The file '{file}' is not readable.") self._log.error(f"The file '{file}' is not readable.")
else: else:
file_date = "unknown-time"
if self.is_image(file): if self.is_image(file):
if 'Exif.Photo.DateTimeOriginal' in self.metadata.exif_keys: if 'Exif.Photo.DateTimeOriginal' in self.metadata.exif_keys:
original_date = self.metadata['Exif.Photo.DateTimeOriginal'].value original_date = self.metadata['Exif.Photo.DateTimeOriginal'].value
self._log.debug(f"File creation time: {original_date} \ self._log.debug(f"File creation time in EXIF: {original_date} \
(type: {type(original_date)})") (type: {type(original_date)})")
try: try:
file_date = original_date.strftime('%Y.%m.%d') #file_date = original_date.strftime('%Y/%Y.%m.%d')
file_date = original_date
except Exception as error: except Exception as error:
self._log.error(f"Failed to convert EXIF information about date '{original_date}'.") self._log.error(f"Failed to convert EXIF information about date '{original_date}'.")
file_date = 'unknown-time' file_date = None
if file_date == 'unknown-time': if file_date is None:
self._log.debug('Date not stored in EXIF metadata') self._log.debug('Date not stored in EXIF metadata')
match = re.search( match = re.search(
r'(?P<year>20[0-9]{2})[\-/\._]?(?P<month>[0-1]?[0-9])[\-/\._]?(?P<day>[0-3]?[0-9])', r'(?P<year>20[0-9]{2})[\-/\._]?(?P<month>[0-1]?[0-9])[\-/\._]?(?P<day>[0-3]?[0-9])',
filename filename
) )
if match: if match:
file_date = f"{match.group('year')}.{match.group('month')}.\ file_date = datetime.strptime(f"{match.group('year')}.{match.group('month')}.\
{match.group('day')}" {match.group('day')}", '%Y.%m.%d')
else: else:
match = re.search(r'(?P<day>[0-3]?[0-9])[\-/\._]?\ match = re.search(r'(?P<day>[0-3]?[0-9])[\-/\._]?\
(?P<month>[0-1]?[0-9])[\-/\._]?(?P<year>20[0-9]{2})', filename) (?P<month>[0-1]?[0-9])[\-/\._]?(?P<year>20[0-9]{2})', filename)
if match: if match:
file_date = f"{match.group('year')}.{match.group('month')}.\ file_date = datetime.strptime(f"{match.group('year')}.{match.group('month')}.\
{match.group('day')}" {match.group('day')}", '%Y.%m.%d')
else: else:
self._log.warning(f"Date not found in file's name '{filename}'.") self._log.warning(f"Date not found in file's name '{filename}'.")
else: else:
@ -166,7 +168,8 @@ class image_classifier:
people = list() people = list()
if self.is_image(file): if self.is_image(file):
self.process_metadata(file) self.process_metadata(file)
folder_date = self.get_file_date(file) folder_date_time = self.get_file_date(file)
folder_date = folder_date_time.strftime(self.folder_date_format)
if folder_date: if folder_date:
if self.is_image(file): if self.is_image(file):
people = self.find_faces(file) people = self.find_faces(file)
@ -340,11 +343,12 @@ identify people. Filename would be used as the name for the person. Just one per
pictures to each person's folder. Be sure to have deduplication in the filesystem to avoid using \ pictures to each person's folder. Be sure to have deduplication in the filesystem to avoid using \
too much storage.") too much storage.")
@click.option('--recursive', '-r', is_flag=True, help='Recursively search for files in the provided --directory') @click.option('--recursive', '-r', is_flag=True, help='Recursively search for files in the provided --directory')
@click.option('--folder-date-format', '-F', default='%Y/%Y.%m.%d', help='Format for the folder with the file date according to https://docs.python.org/3/library/datetime.html#strftime-strptime-behavior')
@click_config_file.configuration_option() @click_config_file.configuration_option()
def __main__(debug_level, log_file, faces_directory, directory, no_move, def __main__(debug_level, log_file, faces_directory, directory, no_move,
people_folder, recursive): people_folder, recursive, folder_date_format):
return image_classifier(debug_level, log_file, faces_directory, directory, no_move, return image_classifier(debug_level, log_file, faces_directory, directory, no_move,
people_folder, recursive) people_folder, recursive, folder_date_format)
if __name__ == "__main__": if __name__ == "__main__":