ordigi/tests/test_collection.py

233 lines
8.5 KiB
Python

# TODO to be removed later
from datetime import datetime
import inquirer
import os
import pytest
import shutil
import sqlite3
from pathlib import Path
import re
from sys import platform
from time import sleep
from .conftest import randomize_files, randomize_db
from ordigi import constants
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
from ordigi import log
from ordigi.media import Media
from ordigi import utils
class TestFPath:
@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 test_get_part(self, tmp_path):
"""
Test all parts
"""
fpath = FPath(self.path_format, 4, self.logger)
# 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}'
]
for file_path in self.file_paths:
media = Media(file_path, self.src_path, use_date_filename=True,
use_file_dates=True)
subdirs = file_path.relative_to(self.src_path).parent
exif_tags = {}
for key in ('album', 'camera_make', 'camera_model', 'latitude',
'longitude', 'original_name', 'title'):
exif_tags[key] = media.tags_keys[key]
exif_data = ExifToolCaching(str(file_path)).asdict()
loc = GeoLocation()
metadata = media.get_metadata(loc)
for item, regex in items.items():
for mask in masks:
matched = re.search(regex, mask)
if matched:
part = fpath.get_part(item, mask[1:-1], metadata)
# check if part is correct
assert isinstance(part, str), file_path
if item == 'basename':
assert part == file_path.stem, file_path
elif item == 'date':
if part == '':
media.get_date_media()
assert datetime.strptime(part, mask[1:-1])
elif item == 'folder':
assert part == subdirs.name, file_path
elif item == 'folders':
assert part in str(subdirs)
elif item == 'ext':
assert part == file_path.suffix[1:], file_path
elif item == 'name':
expected_part = file_path.stem
for i, rx in utils.get_date_regex(expected_part):
part = re.sub(rx, '', expected_part)
assert part == expected_part, file_path
elif item == 'custom':
assert part == mask[2:-2], file_path
elif item in ('city', 'country', 'location', 'state'):
pass
elif item in exif_tags.keys():
f = False
for key in exif_tags[item]:
if key in exif_data:
f = True
assert part == exif_data[key], file_path
break
if f == False:
assert part == '', file_path
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, album_from_folder=True,
logger=self.logger, mode='copy')
loc = GeoLocation()
summary, result = collection.sort_files([self.src_path],
self.path_format, loc)
# Summary is created and there is no errors
assert summary, summary
assert result, result
summary, result = collection.check_files()
assert summary, summary
assert result, result
for file_path in tmp_path.glob('**/*'):
if '.db' not in str(file_path):
media = Media(file_path, tmp_path, album_from_folder=True)
media.get_exif_metadata()
for value in media._get_key_values('album'):
assert value != '' or None
# test with populated dest dir
randomize_files(tmp_path)
summary, result = collection.check_files()
assert summary, summary
assert not result, result
collection = Collection(tmp_path, logger=self.logger)
summary = collection.update(loc)
assert summary, summary
collection = Collection(tmp_path, mode='copy', album_from_folder=True)
loc = GeoLocation()
summary, result = collection.sort_files([self.src_path], self.path_format, loc)
assert summary, summary
assert result, result
# TODO check if path follow path_format
def test_sort_files_invalid_db(self, tmp_path):
collection = Collection(tmp_path, mode='copy')
loc = GeoLocation()
randomize_db(tmp_path)
with pytest.raises(sqlite3.DatabaseError) as e:
summary, result = collection.sort_files([self.src_path],
self.path_format, loc)
def test_sort_file(self, tmp_path):
for mode in 'copy', 'move':
collection = Collection(tmp_path, mode=mode)
# copy mode
src_path = Path(self.src_path, 'test_exif', 'photo.png')
name = 'photo_' + mode + '.png'
dest_path = Path(tmp_path, name)
src_checksum = utils.checksum(src_path)
result_copy = collection.sort_file(src_path, dest_path)
assert result_copy
# Ensure files remain the same
assert collection._checkcomp(dest_path, src_checksum)
if mode == 'copy':
assert src_path.exists()
else:
assert not src_path.exists()
shutil.copyfile(dest_path, src_path)
# TODO check for conflicts
def test__get_files_in_path(self, tmp_path):
collection = Collection(tmp_path, exclude={'**/*.dng',}, max_deep=1,
use_date_filename=True, use_file_dates=True)
paths = [x for x in collection._get_files_in_path(self.src_path,
glob='**/photo*')]
assert len(paths) == 6
for path in paths:
assert isinstance(path, Path)
def test_sort_similar_images(self, tmp_path):
path = tmp_path / 'collection'
shutil.copytree(self.src_path, path)
collection = Collection(path, logger=self.logger)
loc = GeoLocation()
summary = collection.init(loc)
summary, result = collection.sort_similar_images(path, similarity=60)
# Summary is created and there is no errors
assert summary, summary
assert result, result
summary, result = collection.revert_compare(path)
# Summary is created and there is no errors
assert summary, summary
assert result, result