Add FPath class
This commit is contained in:
parent
4442c18570
commit
5c255093e3
|
@ -24,69 +24,16 @@ from ordigi.summary import Summary
|
|||
from ordigi import utils
|
||||
|
||||
|
||||
class Collection:
|
||||
"""Class of the media collection."""
|
||||
class FPath:
|
||||
"""Featured path object"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
root,
|
||||
path_format,
|
||||
album_from_folder=False,
|
||||
cache=False,
|
||||
day_begins=0,
|
||||
dry_run=False,
|
||||
exclude=set(),
|
||||
filter_by_ext=set(),
|
||||
glob='**/*',
|
||||
interactive=False,
|
||||
logger=logging.getLogger(),
|
||||
max_deep=None,
|
||||
mode='copy',
|
||||
use_date_filename=False,
|
||||
use_file_dates=False,
|
||||
):
|
||||
|
||||
# Attributes
|
||||
self.root = Path(root).expanduser().absolute()
|
||||
if not self.root.exists():
|
||||
logger.error(f'Directory {self.root} does not exist')
|
||||
sys.exit(1)
|
||||
|
||||
self.path_format = path_format
|
||||
self.db = Sqlite(self.root)
|
||||
|
||||
# Options
|
||||
self.album_from_folder = album_from_folder
|
||||
self.cache = cache
|
||||
def __init__(self, path_format, day_begins=0, logger=logging.getLogger()):
|
||||
self.day_begins = day_begins
|
||||
self.dry_run = dry_run
|
||||
self.exclude = exclude
|
||||
|
||||
if '%media' in filter_by_ext:
|
||||
filter_by_ext.remove('%media')
|
||||
self.filter_by_ext = filter_by_ext.union(media.extensions)
|
||||
else:
|
||||
self.filter_by_ext = filter_by_ext
|
||||
|
||||
self.glob = glob
|
||||
self.items = self.get_items()
|
||||
self.interactive = interactive
|
||||
self.logger = logger.getChild(self.__class__.__name__)
|
||||
self.max_deep = max_deep
|
||||
self.mode = mode
|
||||
# List to store media metadata
|
||||
self.medias = []
|
||||
self.summary = Summary()
|
||||
self.use_date_filename = use_date_filename
|
||||
self.use_file_dates = use_file_dates
|
||||
self.logger = logger
|
||||
self.path_format = path_format
|
||||
self.whitespace_regex = '[ \t\n\r\f\v]+'
|
||||
|
||||
self.src_list = []
|
||||
self.dest_list = []
|
||||
|
||||
# Constants
|
||||
self.theme = request.load_theme()
|
||||
|
||||
def get_items(self):
|
||||
return {
|
||||
'album': '{album}',
|
||||
|
@ -96,7 +43,7 @@ class Collection:
|
|||
'city': '{city}',
|
||||
'custom': '{".*"}',
|
||||
'country': '{country}',
|
||||
# 'folder': '{folder[<>]?[-+]?[1-9]?}',
|
||||
'date': '{(%[a-zA-Z][^a-zA-Z]*){1,8}}', # search for date format string
|
||||
'ext': '{ext}',
|
||||
'folder': '{folder}',
|
||||
'folders': r'{folders(\[[0-9:]{0,3}\])?}',
|
||||
|
@ -105,19 +52,25 @@ class Collection:
|
|||
'original_name': '{original_name}',
|
||||
'state': '{state}',
|
||||
'title': '{title}',
|
||||
'date': '{(%[a-zA-Z][^a-zA-Z]*){1,8}}', # search for date format string
|
||||
}
|
||||
|
||||
def _check_for_early_morning_photos(self, date):
|
||||
def get_early_morning_photos_date(self, date, mask):
|
||||
"""check for early hour photos to be grouped with previous day"""
|
||||
|
||||
for m in '%H', '%M', '%S','%I', '%p', '%f':
|
||||
if m in mask:
|
||||
# D'ont change date format if datestring contain hour, minutes or seconds...
|
||||
return date.strftime(mask)
|
||||
|
||||
if date.hour < self.day_begins:
|
||||
self.logger.info(
|
||||
"moving this photo to the previous day for classification purposes"
|
||||
)
|
||||
|
||||
# push it to the day before for classification purposes
|
||||
date = date - timedelta(hours=date.hour + 1)
|
||||
|
||||
return date
|
||||
return date.strftime(mask)
|
||||
|
||||
def _get_folders(self, folders, mask):
|
||||
"""
|
||||
|
@ -186,8 +139,7 @@ class Collection:
|
|||
date = metadata['date_media']
|
||||
# early morning photos can be grouped with previous day
|
||||
if date is not None:
|
||||
date = self._check_for_early_morning_photos(date)
|
||||
part = date.strftime(mask)
|
||||
part = self.get_early_morning_photos_date(date, mask)
|
||||
elif item == 'folder':
|
||||
part = os.path.basename(metadata['subdirs'])
|
||||
|
||||
|
@ -295,6 +247,68 @@ class Collection:
|
|||
|
||||
return None
|
||||
|
||||
|
||||
class Collection:
|
||||
"""Class of the media collection."""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
root,
|
||||
path_format,
|
||||
album_from_folder=False,
|
||||
cache=False,
|
||||
day_begins=0,
|
||||
dry_run=False,
|
||||
exclude=set(),
|
||||
filter_by_ext=set(),
|
||||
glob='**/*',
|
||||
interactive=False,
|
||||
logger=logging.getLogger(),
|
||||
max_deep=None,
|
||||
mode='copy',
|
||||
use_date_filename=False,
|
||||
use_file_dates=False,
|
||||
):
|
||||
|
||||
# Attributes
|
||||
self.root = Path(root).expanduser().absolute()
|
||||
if not self.root.exists():
|
||||
logger.error(f'Directory {self.root} does not exist')
|
||||
sys.exit(1)
|
||||
|
||||
self.path_format = path_format
|
||||
self.db = Sqlite(self.root)
|
||||
|
||||
# Options
|
||||
self.album_from_folder = album_from_folder
|
||||
self.cache = cache
|
||||
self.day_begins = day_begins
|
||||
self.dry_run = dry_run
|
||||
self.exclude = exclude
|
||||
|
||||
if '%media' in filter_by_ext:
|
||||
filter_by_ext.remove('%media')
|
||||
self.filter_by_ext = filter_by_ext.union(media.extensions)
|
||||
else:
|
||||
self.filter_by_ext = filter_by_ext
|
||||
|
||||
self.glob = glob
|
||||
self.interactive = interactive
|
||||
self.logger = logger.getChild(self.__class__.__name__)
|
||||
self.max_deep = max_deep
|
||||
self.mode = mode
|
||||
# List to store media metadata
|
||||
self.medias = []
|
||||
self.summary = Summary()
|
||||
self.use_date_filename = use_date_filename
|
||||
self.use_file_dates = use_file_dates
|
||||
|
||||
self.src_list = []
|
||||
self.dest_list = []
|
||||
|
||||
# Constants
|
||||
self.theme = request.load_theme()
|
||||
|
||||
def _checkcomp(self, dest_path, src_checksum):
|
||||
"""Check file."""
|
||||
if self.dry_run:
|
||||
|
@ -845,7 +859,8 @@ class Collection:
|
|||
)
|
||||
metadata = media.get_metadata(self.root, loc, self.db, self.cache)
|
||||
# Get the destination path according to metadata
|
||||
relpath = Path(self.get_path(metadata))
|
||||
fpath = FPath(self.path_format, self.day_begins, self.logger)
|
||||
relpath = Path(fpath.get_path(metadata))
|
||||
|
||||
files_data.append((copy(media), relpath))
|
||||
|
||||
|
@ -1031,3 +1046,5 @@ class Collection:
|
|||
result = self.check_db()
|
||||
|
||||
return self.summary, result
|
||||
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@ from time import sleep
|
|||
|
||||
from .conftest import randomize_files, randomize_db
|
||||
from ordigi import constants
|
||||
from ordigi.collection import Collection
|
||||
from ordigi.collection import Collection, FPath
|
||||
from ordigi.database import Sqlite
|
||||
from ordigi.exiftool import ExifToolCaching, exiftool_is_running, terminate_exiftool
|
||||
from ordigi.geolocation import GeoLocation
|
||||
|
@ -20,7 +20,7 @@ from ordigi.media import Media
|
|||
from ordigi import utils
|
||||
|
||||
|
||||
class TestCollection:
|
||||
class TestFPath:
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def setup_class(cls, sample_files_paths):
|
||||
|
@ -28,18 +28,13 @@ class TestCollection:
|
|||
cls.path_format = constants.default_path + '/' + constants.default_name
|
||||
cls.logger = log.get_logger(level=10)
|
||||
|
||||
def teardown_class(self):
|
||||
terminate_exiftool()
|
||||
assert not exiftool_is_running()
|
||||
|
||||
def test_get_part(self, tmp_path):
|
||||
"""
|
||||
Test all parts
|
||||
"""
|
||||
fpath = FPath(self.path_format, 4, self.logger)
|
||||
# Item to search for:
|
||||
collection = Collection(tmp_path, self.path_format,
|
||||
use_date_filename=True, use_file_dates=True)
|
||||
items = collection.get_items()
|
||||
items = fpath.get_items()
|
||||
masks = [
|
||||
'{album}',
|
||||
'{basename}',
|
||||
|
@ -77,7 +72,7 @@ class TestCollection:
|
|||
for mask in masks:
|
||||
matched = re.search(regex, mask)
|
||||
if matched:
|
||||
part = collection.get_part(item, mask[1:-1], metadata)
|
||||
part = fpath.get_part(item, mask[1:-1], metadata)
|
||||
# check if part is correct
|
||||
assert isinstance(part, str), file_path
|
||||
if item == 'basename':
|
||||
|
@ -113,6 +108,28 @@ class TestCollection:
|
|||
else:
|
||||
assert part == '', file_path
|
||||
|
||||
def test_get_early_morning_photos_date(self):
|
||||
date = datetime(2021, 10, 16, 2, 20, 40)
|
||||
fpath = FPath(self.path_format, 4, self.logger)
|
||||
part = fpath.get_early_morning_photos_date(date, '%Y-%m-%d')
|
||||
assert part == '2021-10-15'
|
||||
|
||||
part = fpath.get_early_morning_photos_date(date, '%Y%m%d-%H%M%S')
|
||||
assert part == '20211016-022040'
|
||||
|
||||
|
||||
class TestCollection:
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def setup_class(cls, sample_files_paths):
|
||||
cls.src_path, cls.file_paths = sample_files_paths
|
||||
cls.path_format = constants.default_path + '/' + constants.default_name
|
||||
cls.logger = log.get_logger(level=10)
|
||||
|
||||
def teardown_class(self):
|
||||
terminate_exiftool()
|
||||
assert not exiftool_is_running()
|
||||
|
||||
def test_sort_files(self, tmp_path):
|
||||
collection = Collection(tmp_path, self.path_format,
|
||||
album_from_folder=True, logger=self.logger)
|
||||
|
@ -182,9 +199,6 @@ class TestCollection:
|
|||
|
||||
# TODO check for conflicts
|
||||
|
||||
|
||||
# TODO check date
|
||||
|
||||
def test__get_files_in_path(self, tmp_path):
|
||||
collection = Collection(tmp_path, self.path_format,
|
||||
exclude={'**/*.dng',},
|
||||
|
|
Loading…
Reference in New Issue