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]
; geocoder: Nominatim or MapQuest
# geocoder: Nominatim or MapQuest
geocoder=Nominatim
mapquest_key=None
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,
help='True if you want files to be copied over from src_dir to\
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,
help='Regular expression for directories or files to exclude.')
@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,
help='True if you want to see details of file processing')
@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):
"""Sort files or directories by reading their EXIF and organizing them
according to config.ini preferences.
@ -241,9 +236,17 @@ def _sort(debug, dry_run, destination, copy, day_begins, exclude_regex, filter_b
# Initialize Db
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:
summary.write()

View File

@ -12,7 +12,7 @@ import os
import re
import shutil
import time
from datetime import datetime
from datetime import datetime, timedelta
from elodie import geolocation
from elodie import log
@ -29,7 +29,7 @@ class FileSystem(object):
"""A class for interacting with the file system."""
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
self.default_file_name_definition = {
'date': '%Y-%m-%d_%H-%M-%S',
@ -56,6 +56,7 @@ class FileSystem(object):
self.mode = mode
self.logger = logger
self.summary = Summary()
self.day_begins = day_begins
# Instantiate a plugins object
self.plugins = Plugins()
@ -137,6 +138,18 @@ class FileSystem(object):
"""
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):
"""Generate file name for a photo or video using its metadata.
@ -336,8 +349,9 @@ class FileSystem(object):
# If Directory is in the config we assume full_path and its
# corresponding values (date, location) are also present
config_directory = self.default_folder_path_definition
if('Directory' in config):
config_directory = config['Directory']
if 'Directory' in config:
if 'full_path' in config['Directory']:
config_directory = config['Directory']
# Find all subpatterns of full_path that map to directories.
# I.e. %foo/%bar => ['foo', 'bar']
@ -502,7 +516,8 @@ class FileSystem(object):
config_directory = self.default_folder_path_definition
config = load_config(constants.CONFIG_FILE)
if('Directory' in config):
config_directory = config['Directory']
if 'full_path' in config['Directory']:
config_directory = config['Directory']
# Get date mask from config
mask = ''
if 'date' in config_directory:
@ -518,6 +533,8 @@ class FileSystem(object):
return folder
elif part in ('date', 'day', 'month', 'year'):
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:
return date.strftime(mask)
else:
@ -620,6 +637,7 @@ class FileSystem(object):
# 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.
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(os.path.isfile(checksum_file)):
log.info('%s already at %s.' % (

View File

@ -730,6 +730,14 @@ def test_checkcomp():
assert valid_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():
filesystem = FileSystem()
temporary_folder, folder = helper.create_working_folder()