Add day_begins config option
This commit is contained in:
parent
fc1f4343b0
commit
2e84888c59
|
@ -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
|
||||||
|
|
19
elodie.py
19
elodie.py
|
@ -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()
|
||||||
|
|
|
@ -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,8 +349,9 @@ 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:
|
||||||
config_directory = config['Directory']
|
if 'full_path' in 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.
|
||||||
# I.e. %foo/%bar => ['foo', 'bar']
|
# I.e. %foo/%bar => ['foo', 'bar']
|
||||||
|
@ -502,7 +516,8 @@ 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):
|
||||||
config_directory = config['Directory']
|
if 'full_path' in config['Directory']:
|
||||||
|
config_directory = config['Directory']
|
||||||
# Get date mask from config
|
# Get date mask from config
|
||||||
mask = ''
|
mask = ''
|
||||||
if 'date' in config_directory:
|
if 'date' in config_directory:
|
||||||
|
@ -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.' % (
|
||||||
|
|
|
@ -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()
|
||||||
|
|
Loading…
Reference in New Issue