Add day_begins config option

This commit is contained in:
Cédric Leporcq 2021-07-17 09:27:14 +02:00
parent fc1f4343b0
commit 2e84888c59
4 changed files with 57 additions and 14 deletions

View File

@ -1,5 +1,19 @@
[Directory]
# day_begins: what hour of the day you want the day to begin (only for
# classification purposes). Defaults at 0 as midnight. Can be
# used to group early morning photos with the previous day. Must
# be a number between 0-23')
day_begins=4
location=%city, %state
year=%Y
month=%B
# date=%Y
# custom=%date %album
full_path=%year/%month/%location
[Geolocation] [Geolocation]
; geocoder: Nominatim or MapQuest # geocoder: Nominatim or MapQuest
geocoder=Nominatim geocoder=Nominatim
mapquest_key=None mapquest_key=None
prefer_english_names=False prefer_english_names=False

View File

@ -177,11 +177,6 @@ def _import(destination, source, file, album_from_folder, trash,
@click.option('--copy', '-c', default=False, is_flag=True, @click.option('--copy', '-c', default=False, is_flag=True,
help='True if you want files to be copied over from src_dir to\ help='True if you want files to be copied over from src_dir to\
dest_dir rather than moved') dest_dir rather than moved')
@click.option('--day-begins', '-b', default=0,
help='What hour of the day you want the day to begin (only for\
classification purposes). Defaults at 0 as midnight. Can be\
used to group early morning photos with the previous day. Must\
be a number between 0-23')
@click.option('--exclude-regex', '-e', default=set(), multiple=True, @click.option('--exclude-regex', '-e', default=set(), multiple=True,
help='Regular expression for directories or files to exclude.') help='Regular expression for directories or files to exclude.')
@click.option('--filter-by-ext', '-f', default=False, help='''Use filename @click.option('--filter-by-ext', '-f', default=False, help='''Use filename
@ -197,7 +192,7 @@ def _import(destination, source, file, album_from_folder, trash,
@click.option('--verbose', '-v', default=False, is_flag=True, @click.option('--verbose', '-v', default=False, is_flag=True,
help='True if you want to see details of file processing') help='True if you want to see details of file processing')
@click.argument('paths', required=True, nargs=-1, type=click.Path()) @click.argument('paths', required=True, nargs=-1, type=click.Path())
def _sort(debug, dry_run, destination, copy, day_begins, exclude_regex, filter_by_ext, ignore_tags, def _sort(debug, dry_run, destination, copy, exclude_regex, filter_by_ext, ignore_tags,
remove_duplicates, verbose, paths): remove_duplicates, verbose, paths):
"""Sort files or directories by reading their EXIF and organizing them """Sort files or directories by reading their EXIF and organizing them
according to config.ini preferences. according to config.ini preferences.
@ -241,9 +236,17 @@ def _sort(debug, dry_run, destination, copy, day_begins, exclude_regex, filter_b
# Initialize Db # Initialize Db
db = Db(destination) db = Db(destination)
filesystem = FileSystem(mode, dry_run, exclude_regex_list, logger)
summary, has_errors = filesystem.sort_files(paths, destination, db, remove_duplicates) if 'Directory' in config and 'day_begins' in config['Directory']:
config_directory = config['Directory']
day_begins = config_directory['day_begins']
else:
day_begins = 0
filesystem = FileSystem(mode, dry_run, exclude_regex_list, logger,
day_begins)
summary, has_errors = filesystem.sort_files(paths, destination, db,
remove_duplicates)
if verbose or debug: if verbose or debug:
summary.write() summary.write()

View File

@ -12,7 +12,7 @@ import os
import re import re
import shutil import shutil
import time import time
from datetime import datetime from datetime import datetime, timedelta
from elodie import geolocation from elodie import geolocation
from elodie import log from elodie import log
@ -29,7 +29,7 @@ class FileSystem(object):
"""A class for interacting with the file system.""" """A class for interacting with the file system."""
def __init__(self, mode='copy', dry_run=False, exclude_regex_list=set(), def __init__(self, mode='copy', dry_run=False, exclude_regex_list=set(),
logger=logging.getLogger()): logger=logging.getLogger(), day_begins=0):
# The default folder path is along the lines of 2017-06-17_01-04-14-dsc_1234-some-title.jpg # The default folder path is along the lines of 2017-06-17_01-04-14-dsc_1234-some-title.jpg
self.default_file_name_definition = { self.default_file_name_definition = {
'date': '%Y-%m-%d_%H-%M-%S', 'date': '%Y-%m-%d_%H-%M-%S',
@ -56,6 +56,7 @@ class FileSystem(object):
self.mode = mode self.mode = mode
self.logger = logger self.logger = logger
self.summary = Summary() self.summary = Summary()
self.day_begins = day_begins
# Instantiate a plugins object # Instantiate a plugins object
self.plugins = Plugins() self.plugins = Plugins()
@ -137,6 +138,18 @@ class FileSystem(object):
""" """
return os.getcwd() return os.getcwd()
def check_for_early_morning_photos(self, date):
"""check for early hour photos to be grouped with previous day"""
if date.hour < self.day_begins:
self.logger.info('moving this photo to the previous day for\
classification purposes (day_begins=' + str(self.day_begins) + ')')
date = date - timedelta(hours=date.hour+1) # push it to the day before for classificiation purposes
return date
def get_file_name(self, metadata): def get_file_name(self, metadata):
"""Generate file name for a photo or video using its metadata. """Generate file name for a photo or video using its metadata.
@ -336,7 +349,8 @@ class FileSystem(object):
# If Directory is in the config we assume full_path and its # If Directory is in the config we assume full_path and its
# corresponding values (date, location) are also present # corresponding values (date, location) are also present
config_directory = self.default_folder_path_definition config_directory = self.default_folder_path_definition
if('Directory' in config): if 'Directory' in config:
if 'full_path' in config['Directory']:
config_directory = config['Directory'] config_directory = config['Directory']
# Find all subpatterns of full_path that map to directories. # Find all subpatterns of full_path that map to directories.
@ -502,6 +516,7 @@ class FileSystem(object):
config_directory = self.default_folder_path_definition config_directory = self.default_folder_path_definition
config = load_config(constants.CONFIG_FILE) config = load_config(constants.CONFIG_FILE)
if('Directory' in config): if('Directory' in config):
if 'full_path' in config['Directory']:
config_directory = config['Directory'] config_directory = config['Directory']
# Get date mask from config # Get date mask from config
mask = '' mask = ''
@ -518,6 +533,8 @@ class FileSystem(object):
return folder return folder
elif part in ('date', 'day', 'month', 'year'): elif part in ('date', 'day', 'month', 'year'):
date = self.get_date_taken(metadata) date = self.get_date_taken(metadata)
# early morning photos can be grouped with previous day
date = self.check_for_early_morning_photos(date)
if date is not None: if date is not None:
return date.strftime(mask) return date.strftime(mask)
else: else:
@ -620,6 +637,7 @@ class FileSystem(object):
# If we find a checksum match but the file doesn't exist where we # If we find a checksum match but the file doesn't exist where we
# believe it to be then we write a debug log and proceed to import. # believe it to be then we write a debug log and proceed to import.
checksum_file = db.get_hash(checksum) checksum_file = db.get_hash(checksum)
# BUG: inconsistency if file removed manually without update db
if(allow_duplicate is False and checksum_file is not None): if(allow_duplicate is False and checksum_file is not None):
if(os.path.isfile(checksum_file)): if(os.path.isfile(checksum_file)):
log.info('%s already at %s.' % ( log.info('%s already at %s.' % (

View File

@ -730,6 +730,14 @@ def test_checkcomp():
assert valid_checksum assert valid_checksum
assert not invalid_checksum assert not invalid_checksum
def test_check_for_early_morning_photos():
date_origin = datetime(1985, 1, 1, 3, 5)
filesystem = FileSystem(day_begins=4)
date = filesystem.check_for_early_morning_photos(date_origin)
assert date.date() == datetime(1984, 12, 31).date()
def test_sort_file(): def test_sort_file():
filesystem = FileSystem() filesystem = FileSystem()
temporary_folder, folder = helper.create_working_folder() temporary_folder, folder = helper.create_working_folder()