Code improvements
This commit is contained in:
parent
7688d0e7c4
commit
da4a388697
109
ordigi/cli.py
109
ordigi/cli.py
|
@ -1,8 +1,6 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
import os
|
||||
from pathlib import Path
|
||||
import re
|
||||
import sys
|
||||
|
||||
import click
|
||||
|
@ -94,7 +92,7 @@ _sort_options = [
|
|||
help="Use filename date for media original date.",
|
||||
),
|
||||
click.option(
|
||||
'--use-file-dates',
|
||||
'--use-file-dates',
|
||||
'-F',
|
||||
default=False,
|
||||
is_flag=True,
|
||||
|
@ -102,6 +100,7 @@ _sort_options = [
|
|||
),
|
||||
]
|
||||
|
||||
|
||||
def print_help(command):
|
||||
click.echo(command.get_help(click.Context(command)))
|
||||
|
||||
|
@ -127,7 +126,33 @@ def _get_paths(paths, root):
|
|||
return paths, root
|
||||
|
||||
|
||||
@click.command('check')
|
||||
def _cli_get_location(collection):
|
||||
gopt = collection.opt['Geolocation']
|
||||
return GeoLocation(
|
||||
{
|
||||
'geocoder': gopt['geocoder'],
|
||||
'prefer_english_names': gopt['prefer_english_names'],
|
||||
'timeout': gopt['timeout'],
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
def _cli_sort(collection, src_paths, import_mode, remove_duplicates):
|
||||
loc = _cli_get_location(collection)
|
||||
|
||||
path_format = collection.opt['Path']['path_format']
|
||||
|
||||
return collection.sort_files(
|
||||
src_paths, path_format, loc, import_mode, remove_duplicates
|
||||
)
|
||||
|
||||
|
||||
@click.group()
|
||||
def cli(**kwargs):
|
||||
pass
|
||||
|
||||
|
||||
@cli.command('check')
|
||||
@add_options(_logger_options)
|
||||
@click.argument('path', required=True, nargs=1, type=click.Path())
|
||||
def _check(**kwargs):
|
||||
|
@ -152,7 +177,7 @@ def _check(**kwargs):
|
|||
sys.exit(1)
|
||||
|
||||
|
||||
@click.command('clean')
|
||||
@cli.command('clean')
|
||||
@add_options(_logger_options)
|
||||
@add_options(_dry_run_options)
|
||||
@add_options(_filter_options)
|
||||
|
@ -202,9 +227,11 @@ def _clean(**kwargs):
|
|||
},
|
||||
)
|
||||
|
||||
# TODO
|
||||
# os.path.join(
|
||||
# TODO make function to remove duplicates
|
||||
# path_format = collection.opt['Path']['path_format']
|
||||
# summary = collection.sort_files(
|
||||
# paths, remove_duplicates=kwargs['remove_duplicates']
|
||||
# paths, path_format, None, remove_duplicates=kwargs['remove_duplicates']
|
||||
# )
|
||||
|
||||
if kwargs['path_string']:
|
||||
|
@ -229,7 +256,7 @@ def _clean(**kwargs):
|
|||
sys.exit(1)
|
||||
|
||||
|
||||
@click.command('compare')
|
||||
@cli.command('compare')
|
||||
@add_options(_logger_options)
|
||||
@add_options(_dry_run_options)
|
||||
@add_options(_filter_options)
|
||||
|
@ -283,7 +310,7 @@ def _compare(**kwargs):
|
|||
sys.exit(1)
|
||||
|
||||
|
||||
@click.command('init')
|
||||
@cli.command('init')
|
||||
@add_options(_logger_options)
|
||||
@click.argument('path', required=True, nargs=1, type=click.Path())
|
||||
def _init(**kwargs):
|
||||
|
@ -296,11 +323,7 @@ def _init(**kwargs):
|
|||
|
||||
collection = Collection(root)
|
||||
|
||||
# TODO retrieve collection.opt
|
||||
geocoder='Nominatim'
|
||||
prefer_english_names=False
|
||||
timeout=1
|
||||
loc = GeoLocation(geocoder, prefer_english_names, timeout)
|
||||
loc = _cli_get_location(collection)
|
||||
|
||||
summary = collection.init(loc)
|
||||
|
||||
|
@ -308,7 +331,7 @@ def _init(**kwargs):
|
|||
summary.print()
|
||||
|
||||
|
||||
@click.command('import')
|
||||
@cli.command('import')
|
||||
@add_options(_logger_options)
|
||||
@add_options(_input_options)
|
||||
@add_options(_dry_run_options)
|
||||
|
@ -333,11 +356,6 @@ def _import(**kwargs):
|
|||
|
||||
src_paths, root = _get_paths(kwargs['src'], kwargs['dest'])
|
||||
|
||||
if kwargs['copy']:
|
||||
import_mode = 'copy'
|
||||
else:
|
||||
import_mode = 'move'
|
||||
|
||||
collection = Collection(
|
||||
root,
|
||||
{
|
||||
|
@ -351,19 +369,16 @@ def _import(**kwargs):
|
|||
'glob': kwargs['glob'],
|
||||
'dry_run': kwargs['dry_run'],
|
||||
'interactive': kwargs['interactive'],
|
||||
'path_format': kwargs['path_format'],
|
||||
|
||||
}
|
||||
)
|
||||
|
||||
# TODO retrieve collection.opt
|
||||
# Use loc function
|
||||
geocoder='Nominatim'
|
||||
prefer_english_names=False
|
||||
timeout=1
|
||||
loc = GeoLocation(geocoder, prefer_english_names, timeout)
|
||||
|
||||
summary = collection.sort_files(
|
||||
src_paths, kwargs['path_format'], loc, import_mode, kwargs['remove_duplicates']
|
||||
)
|
||||
if kwargs['copy']:
|
||||
import_mode = 'copy'
|
||||
else:
|
||||
import_mode = 'move'
|
||||
summary = _cli_sort(collection, src_paths, import_mode, kwargs['remove_duplicates'])
|
||||
|
||||
if log_level < 30:
|
||||
summary.print()
|
||||
|
@ -371,7 +386,8 @@ def _import(**kwargs):
|
|||
if summary.errors:
|
||||
sys.exit(1)
|
||||
|
||||
@click.command('sort')
|
||||
|
||||
@cli.command('sort')
|
||||
@add_options(_logger_options)
|
||||
@add_options(_input_options)
|
||||
@add_options(_dry_run_options)
|
||||
|
@ -414,15 +430,7 @@ def _sort(**kwargs):
|
|||
}
|
||||
)
|
||||
|
||||
# TODO retrieve collection.opt
|
||||
geocoder='Nominatim'
|
||||
prefer_english_names=False
|
||||
timeout=1
|
||||
loc = GeoLocation(geocoder, prefer_english_names, timeout)
|
||||
|
||||
summary = collection.sort_files(
|
||||
paths, kwargs['path_format'], loc, kwargs['remove_duplicates']
|
||||
)
|
||||
summary = _cli_sort(collection, paths, False, kwargs['remove_duplicates'])
|
||||
|
||||
if kwargs['clean']:
|
||||
collection.remove_empty_folders(root)
|
||||
|
@ -434,7 +442,7 @@ def _sort(**kwargs):
|
|||
sys.exit(1)
|
||||
|
||||
|
||||
@click.command('update')
|
||||
@cli.command('update')
|
||||
@add_options(_logger_options)
|
||||
@click.argument('path', required=True, nargs=1, type=click.Path())
|
||||
def _update(**kwargs):
|
||||
|
@ -445,26 +453,13 @@ def _update(**kwargs):
|
|||
log_level = log.get_level(kwargs['verbose'])
|
||||
log.console(LOG, level=log_level)
|
||||
|
||||
geocoder='Nominatim'
|
||||
prefer_english_names=False
|
||||
timeout=1
|
||||
loc = GeoLocation(geocoder, prefer_english_names, timeout)
|
||||
collection = Collection(root)
|
||||
loc = _cli_get_location(collection)
|
||||
summary = collection.update(loc)
|
||||
|
||||
if log_level < 30:
|
||||
summary.print()
|
||||
|
||||
|
||||
@click.group()
|
||||
def main(**kwargs):
|
||||
pass
|
||||
|
||||
|
||||
main.add_command(_clean)
|
||||
main.add_command(_check)
|
||||
main.add_command(_compare)
|
||||
main.add_command(_init)
|
||||
main.add_command(_import)
|
||||
main.add_command(_sort)
|
||||
main.add_command(_update)
|
||||
if __name__ == '__main__':
|
||||
cli()
|
||||
|
|
|
@ -58,9 +58,9 @@ class FPath:
|
|||
def get_early_morning_photos_date(self, date, mask):
|
||||
"""check for early hour photos to be grouped with previous day"""
|
||||
|
||||
for i in '%H', '%M', '%S','%I', '%p', '%f':
|
||||
for i in '%H', '%M', '%S', '%I', '%p', '%f':
|
||||
# D'ont change date format if datestring contain hour, minutes or seconds.
|
||||
if i in mask:
|
||||
# D'ont change date format if datestring contain hour, minutes or seconds...
|
||||
return date.strftime(mask)
|
||||
|
||||
if date.hour < self.day_begins:
|
||||
|
@ -127,6 +127,7 @@ class FPath:
|
|||
# Each item has its own custom logic and we evaluate a single item and return
|
||||
# the evaluated string.
|
||||
part = ''
|
||||
|
||||
filename = metadata['filename']
|
||||
stem = os.path.splitext(filename)[0]
|
||||
if item == 'stem':
|
||||
|
@ -515,7 +516,6 @@ class SortMedias:
|
|||
else:
|
||||
self.summary.append('sort', False, src_path, dest_path)
|
||||
|
||||
|
||||
def sort_file(self, src_path, dest_path, metadata, imp=False):
|
||||
"""Sort file and register it to db"""
|
||||
if imp == 'copy':
|
||||
|
@ -545,7 +545,7 @@ class SortMedias:
|
|||
directory_path = self.root / relpath
|
||||
parts = directory_path.relative_to(self.root).parts
|
||||
for i, _ in enumerate(parts):
|
||||
dir_path = self.root / Path(*parts[0 : i + 1])
|
||||
dir_path = self.root / Path(*parts[0: i + 1])
|
||||
if dir_path.is_file():
|
||||
self.log.warning(f'Target directory {dir_path} is a file')
|
||||
# Rename the src_file
|
||||
|
@ -664,8 +664,9 @@ class SortMedias:
|
|||
pass
|
||||
|
||||
if conflicts != []:
|
||||
for files_data, conflict in self._solve_conflicts(conflicts,
|
||||
remove_duplicates):
|
||||
for files_data, conflict in self._solve_conflicts(
|
||||
conflicts, remove_duplicates
|
||||
):
|
||||
|
||||
src_path, dest_path, metadata = files_data
|
||||
if not conflict:
|
||||
|
@ -746,7 +747,7 @@ class Collection(SortMedias):
|
|||
|
||||
def get_config_options(self):
|
||||
"""Get collection config"""
|
||||
config = Config(self.root.joinpath('.ordigi', 'ordigi.conf'))
|
||||
config = Config(self.root.joinpath('.ordigi', 'ordigi.conf'))
|
||||
|
||||
return config.get_config_options()
|
||||
|
||||
|
@ -760,7 +761,7 @@ class Collection(SortMedias):
|
|||
exclude = self.exclude
|
||||
|
||||
paths = Paths(
|
||||
filters = {
|
||||
filters={
|
||||
'exclude': exclude,
|
||||
'extensions': None,
|
||||
'glob': '**/*',
|
||||
|
@ -839,7 +840,7 @@ class Collection(SortMedias):
|
|||
metadata['src_path'] = row['SrcPath']
|
||||
# Check if row FilePath is a subpath of relpath
|
||||
if relpath.startswith(row['FilePath']):
|
||||
path = os.path.relpath(relpath, row['FilePath'])
|
||||
path = os.path.relpath(rlpath, row['FilePath'])
|
||||
metadata['subdirs'] = row['Subdirs'] + path
|
||||
metadata['Filename'] = row['Filename']
|
||||
break
|
||||
|
@ -859,7 +860,7 @@ class Collection(SortMedias):
|
|||
checksum = utils.checksum(file_path)
|
||||
relpath = file_path.relative_to(self.root)
|
||||
if checksum == self.db.sqlite.get_checksum(relpath):
|
||||
self.summary.append('check',True, file_path)
|
||||
self.summary.append('check', True, file_path)
|
||||
else:
|
||||
self.log.error('{file_path} is corrupted')
|
||||
self.summary.append('check', False, file_path)
|
||||
|
@ -933,9 +934,9 @@ class Collection(SortMedias):
|
|||
return self.summary
|
||||
|
||||
def sort_files(
|
||||
self, src_dirs, path_format, loc,
|
||||
imp=False, remove_duplicates=False
|
||||
):
|
||||
self, src_dirs, path_format, loc,
|
||||
imp=False, remove_duplicates=False
|
||||
):
|
||||
"""
|
||||
Sort files into appropriate folder
|
||||
"""
|
||||
|
|
|
@ -2,12 +2,10 @@ import json
|
|||
import re
|
||||
|
||||
from configparser import RawConfigParser
|
||||
from os import path
|
||||
from ordigi import constants
|
||||
from geopy.geocoders import options as gopt
|
||||
|
||||
|
||||
# TODO make one method???
|
||||
def check_option(getoption):
|
||||
"""Check option type int or boolean"""
|
||||
try:
|
||||
|
@ -18,6 +16,7 @@ def check_option(getoption):
|
|||
else:
|
||||
return getoption
|
||||
|
||||
|
||||
def check_json(getoption):
|
||||
"""Check if json string is valid"""
|
||||
try:
|
||||
|
@ -28,6 +27,7 @@ def check_json(getoption):
|
|||
else:
|
||||
return getoption
|
||||
|
||||
|
||||
def check_re(getoption):
|
||||
"""Check if regex string is valid"""
|
||||
try:
|
||||
|
@ -165,9 +165,9 @@ class Config:
|
|||
if option == 'geocoder' and value in ('Nominatim',):
|
||||
return self.conf[section][option]
|
||||
if option == 'glob':
|
||||
return self.conf[section][option]
|
||||
if option == 'path_format':
|
||||
return self.getre(section, option)
|
||||
if option == 'path_format':
|
||||
return self.conf[section][option]
|
||||
if option in multi_options:
|
||||
return set(self.getjson(section, option))
|
||||
|
||||
|
|
|
@ -8,6 +8,7 @@ from pathlib import Path
|
|||
#: If True, debug messages will be printed.
|
||||
debug = False
|
||||
|
||||
|
||||
# Ordigi settings directory.
|
||||
def get_config_dir(name):
|
||||
if 'XDG_CONFIG_HOME' in environ:
|
||||
|
@ -19,6 +20,7 @@ def get_config_dir(name):
|
|||
|
||||
return confighome / name
|
||||
|
||||
|
||||
APPLICATION_DIRECTORY = get_config_dir('ordigi')
|
||||
|
||||
DEFAULT_PATH = '{%Y-%m-%b}/{album}|{city}'
|
||||
|
|
|
@ -30,4 +30,10 @@ exclude =
|
|||
|
||||
[options.entry_points]
|
||||
console_scripts =
|
||||
ordigi = ordigi.cli:main
|
||||
ordigi = ordigi.cli:cli
|
||||
|
||||
[flake8]
|
||||
|
||||
[pycodestyle]
|
||||
max-line-length = 88
|
||||
|
||||
|
|
|
@ -217,7 +217,7 @@ class TestCollection:
|
|||
src_checksum = utils.checksum(src_path)
|
||||
summary = collection.sort_file(
|
||||
src_path, dest_path, media.metadata, imp=imp
|
||||
)
|
||||
)
|
||||
assert not summary.errors
|
||||
# Ensure files remain the same
|
||||
assert collection._checkcomp(dest_path, src_checksum)
|
||||
|
|
Loading…
Reference in New Issue