Change path format syntax

This commit is contained in:
Cédric Leporcq 2022-04-18 08:57:47 +02:00
parent a4746cbf60
commit 002404d82c
7 changed files with 59 additions and 56 deletions

View File

@ -93,8 +93,8 @@ pattern.
Default folder structure:
```
dirs_path={%Y}/{%m-%b}-{city}-{folder}
name={%Y%m%d-%H%M%S}-%u{original_name}.%l{ext}|{%Y%m%d-%H%M%S}-%u{basename}.%l{ext}
dirs_path=<%Y>/<%m-%b>-<city>-<folder>
name=<%Y%m%d-%H%M%S>-<%u<original_name>|%u<basename>>.%l<ext>
```
Example folder structure:
@ -115,7 +115,7 @@ Example folder structure:
│ └── 20150927_014138-_dsc8705.nef
```
The folder structure use standard unix path separator (`/`). Fallback folder part can be optionally specified using a pipe (`|`) separator.
The folder structure use standard unix path separator (`/`). Fallback folder part can be optionally specified using a pipe separator and brackets (`<.*|.*>`).
Valid keywords are:

View File

@ -14,5 +14,5 @@ timeout=1
day_begins=4
# Path format
dirs_path={%Y}/{%m-%b}-{city}-{folder}
name={%Y%m%d-%H%M%S}-(%u{original_name}|%u{name}).%l{ext}
dirs_path=<%Y>/<%m-%b>-<city>-<folder>
name=<%Y%m%d-%H%M%S>-<%u<original_name>|%u<name>>.%l<ext>

View File

@ -38,22 +38,22 @@ class FPath:
def get_items(self):
"""Return features items of Fpath class"""
return {
'album': '{album}',
'stem': '{stem}',
'camera_make': '{camera_make}',
'camera_model': '{camera_model}',
'city': '{city}',
'custom': r'{".*"}',
'country': '{country}',
'date': r'{(%[a-zA-Z][^a-zA-Z]*){1,8}}', # search for date format string
'ext': '{ext}',
'folder': '{folder}',
'folders': r'{folders(\[[0-9:]{0,3}\])?}',
'location': '{location}',
'name': '{name}',
'original_name': '{original_name}',
'state': '{state}',
'title': '{title}',
'album': '<album>',
'stem': '<stem>',
'camera_make': '<camera_make>',
'camera_model': '<camera_model>',
'city': '<city>',
'custom': r'<".*">',
'country': '<country>',
'date': r'<(%[a-zA-Z][^a-zA-Z]*){1,8}>', # search for date format string
'ext': '<ext>',
'folder': '<folder>',
'folders': r'<folders(\[[0-9:]{0,3}\])?>',
'location': '<location>',
'name': '<name>',
'original_name': '<original_name>',
'state': '<state>',
'title': '<title>',
}
def get_early_morning_photos_date(self, date, mask):
@ -140,6 +140,9 @@ class FPath:
part = stem
for regex in utils.get_date_regex().values():
part = re.sub(regex, '', part)
# Delete separator
if re.search('^[-_ .]', part):
part = part[1:]
elif item == 'date':
date = metadata['date_media']
# early morning photos can be grouped with previous day
@ -194,7 +197,7 @@ class FPath:
for item, regex in self.items.items():
matched = re.search(regex, this_part)
if matched:
self.log.debug(f'item: {item}, mask: {matched.group()[1:-1]}')
self.log.debug(f'item: {item}, mask: <matched.group()[1:-1]>')
part = self.get_part(item, matched.group()[1:-1], metadata)
self.log.debug(f'part: {part}')
@ -213,16 +216,16 @@ class FPath:
this_part = self._substitute(regex, part, this_part)
# remove alternate parts inside bracket separated by |
regex = r'[-_ .]?\(\|\)'
regex = r'[-_ .]?\<\|\>'
if re.search(regex, this_part):
# Delete substitute part and separator if empty
this_part = re.sub(regex, '', this_part)
elif re.search(r'\(.*\)', this_part):
regex = r'\(\|'
elif re.search(r'\<.*\>', this_part):
regex = r'\<\|'
this_part = re.sub(regex, '', this_part)
regex = r'\|.*\)'
regex = r'\|.*\>'
this_part = re.sub(regex, '', this_part)
regex = r'\)'
regex = r'\>'
this_part = re.sub(regex, '', this_part)
# Delete separator char at the begining of the string if any:
@ -238,7 +241,7 @@ class FPath:
def get_path(self, metadata: dict) -> list:
"""
path_format: {%Y-%d-%m}/%u{city}/{album}
path_format: <%Y-%d-%m>/%u<city>/<album>
Returns file path.
"""
path_format = self.path_format
@ -252,9 +255,9 @@ class FPath:
if part != '':
# Check if all masks are substituted
if True in [c in part for c in '{}']:
if True in [c in part for c in '<>']:
self.log.error(
f"Format path part invalid: {this_part}"
f"Format path part invalid: {part}"
)
sys.exit(1)

View File

@ -23,8 +23,8 @@ def get_config_dir(name):
APPLICATION_DIRECTORY = get_config_dir('ordigi')
DEFAULT_PATH = '{%Y-%m-%b}/{album}|{city}'
DEFAULT_NAME = '{%Y-%m-%d_%H-%M-%S}-{name}-{title}.%l{ext}'
DEFAULT_PATH = '<%Y-%m-%b>/<album>|<city>'
DEFAULT_NAME = '<%Y-%m-%d_%H-%M-%S>-<name>-<title>.%l<ext>'
DEFAULT_PATH_FORMAT = DEFAULT_PATH + '/' + DEFAULT_NAME
DEFAULT_GEOCODER = 'Nominatim'

View File

@ -60,8 +60,8 @@ def conf_path():
conf = RawConfigParser()
conf['Path'] = {
'day_begins': '4',
'dirs_path':'%u{%Y-%m}/{city}|{city}-{%Y}/{folders[:1]}/{folder}',
'name':'{%Y-%m-%b-%H-%M-%S}-{basename}.%l{ext}'
'dirs_path':'%u<%Y-%m>/<city>|<city>-<%Y>/<folders[:1]>/<folder>',
'name':'<%Y-%m-%b-%H-%M-%S>-<basename>.%l<ext>'
}
conf['Geolocation'] = {
'geocoder': 'Nominatium'

View File

@ -33,24 +33,24 @@ class TestFPath:
# Item to search for:
items = fpath.get_items()
masks = [
'{album}',
'{basename}',
'{camera_make}',
'{camera_model}',
'{city}',
'{"custom"}',
'{country}',
'{ext}',
'{folder}',
'{folders[1:3]}',
'{location}',
'{name}',
'{original_name}',
'{state}',
'{title}',
'{%Y-%m-%d}',
'{%Y-%m-%d_%H-%M-%S}',
'{%Y-%m-%b}'
'<album>',
'<basename>',
'<camera_make>',
'<camera_model>',
'<city>',
'<"custom">',
'<country>',
'<ext>',
'<folder>',
'<folders[1:3]>',
'<location>',
'<name>',
'<original_name>',
'<state>',
'<title>',
'<%Y-%m-%d>',
'<%Y-%m-%d_%H-%M-%S>',
'<%Y-%m-%b>'
]
for file_path in self.file_paths:
@ -165,7 +165,7 @@ class TestCollection:
collection = Collection(tmp_path, cli_options=cli_options)
# Try to change path format and sort files again
path_format = 'test_exif/{city}/{%Y}-{name}.%l{ext}'
path_format = 'test_exif/<city>/<%Y>-<name>.%l<ext>'
summary = collection.sort_files([tmp_path], path_format, loc)
self.assert_sort(summary, 27)

View File

@ -32,8 +32,8 @@ class TestConfig:
Read files from config and return variables
"""
# test valid config file
assert conf['Path']['dirs_path'] == '%u{%Y-%m}/{city}|{city}-{%Y}/{folders[:1]}/{folder}'
assert conf['Path']['name'] == '{%Y-%m-%b-%H-%M-%S}-{basename}.%l{ext}'
assert conf['Path']['dirs_path'] == '%u<%Y-%m>/<city>|<city>-<%Y>/<folders[:1]>/<folder>'
assert conf['Path']['name'] == '<%Y-%m-%b-%H-%M-%S>-<basename>.%l<ext>'
assert conf['Path']['day_begins'] == '4'
assert conf['Geolocation']['geocoder'] == 'Nominatium'
@ -56,7 +56,7 @@ class TestConfig:
# """
# config = Config(conf=conf)
# path = config.get_path_definition()
# assert path == '%u{%Y-%m}/{city}|{city}-{%Y}/{folders[:1]}/{folder}/{%Y-%m-%b-%H-%M-%S}-{basename}.%l{ext}'
# assert path == '%u<%Y-%m>/<city>|<city>-<%Y>/<folders[:1]>/<folder>/<%Y-%m-%b-%H-%M-%S>-<basename>.%l<ext>'
def test_get_config_options(self, conf):
config = Config(conf=conf)