206 lines
7.3 KiB
Python
206 lines
7.3 KiB
Python
|
# TODO to be removed later
|
||
|
from datetime import datetime
|
||
|
import os
|
||
|
import pytest
|
||
|
from pathlib import Path
|
||
|
import re
|
||
|
import shutil
|
||
|
from sys import platform
|
||
|
import tempfile
|
||
|
from time import sleep
|
||
|
|
||
|
from dozo import constants
|
||
|
from dozo.database import Db
|
||
|
from dozo.filesystem import FileSystem
|
||
|
from dozo.media.media import Media
|
||
|
from dozo.exiftool import ExifToolCaching, exiftool_is_running, terminate_exiftool
|
||
|
|
||
|
|
||
|
DOZO_PATH = Path(__file__).parent.parent
|
||
|
|
||
|
|
||
|
@pytest.mark.skip()
|
||
|
class TestDb:
|
||
|
pass
|
||
|
|
||
|
class TestFilesystem:
|
||
|
def setup_class(cls):
|
||
|
cls.SRCPATH = tempfile.mkdtemp(prefix='dozo-src')
|
||
|
filenames = ['photo.png', 'plain.jpg', 'text.txt', 'withoutextension',
|
||
|
'no-exif.jpg']
|
||
|
cls.FILE_PATHS = set()
|
||
|
for filename in filenames:
|
||
|
source_path = Path(cls.SRCPATH, filename)
|
||
|
file_path = Path(DOZO_PATH, 'samples', filename)
|
||
|
shutil.copyfile(file_path, source_path)
|
||
|
cls.FILE_PATHS.add(source_path)
|
||
|
cls.path_format = constants.default_path + '/' + constants.default_name
|
||
|
|
||
|
def teardown_class(self):
|
||
|
terminate_exiftool()
|
||
|
assert not exiftool_is_running()
|
||
|
|
||
|
def test_get_part(self):
|
||
|
"""
|
||
|
Test all parts
|
||
|
"""
|
||
|
# Item to search for:
|
||
|
filesystem = FileSystem()
|
||
|
|
||
|
items = filesystem.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}'
|
||
|
]
|
||
|
|
||
|
media = Media()
|
||
|
exif_tags = {
|
||
|
'album': media.album_keys,
|
||
|
'camera_make': media.camera_make_keys,
|
||
|
'camera_model': media.camera_model_keys,
|
||
|
# 'date_original': media.date_original,
|
||
|
# 'date_created': media.date_created,
|
||
|
# 'date_modified': media.date_modified,
|
||
|
'latitude': media.latitude_keys,
|
||
|
'longitude': media.longitude_keys,
|
||
|
'original_name': [media.original_name_key],
|
||
|
'title': media.title_keys
|
||
|
}
|
||
|
|
||
|
subdirs = Path('a', 'b', 'c', 'd')
|
||
|
|
||
|
for file_path in self.FILE_PATHS:
|
||
|
media = Media(str(file_path))
|
||
|
exif_data = ExifToolCaching(str(file_path)).asdict()
|
||
|
metadata = media.get_metadata()
|
||
|
|
||
|
for item, regex in items.items():
|
||
|
for mask in masks:
|
||
|
matched = re.search(regex, mask)
|
||
|
if matched:
|
||
|
part = filesystem.get_part(item, mask[1:-1], metadata,
|
||
|
{}, subdirs)
|
||
|
# check if part is correct
|
||
|
assert isinstance(part, str)
|
||
|
expected_part = ''
|
||
|
if item == 'basename':
|
||
|
expected_part = file_path.stem
|
||
|
elif item == 'date':
|
||
|
assert datetime.strptime(part, mask[1:-1])
|
||
|
expected_part = part
|
||
|
elif item == 'folder':
|
||
|
expected_part = subdirs.name
|
||
|
elif item == 'folders':
|
||
|
if platform == "win32":
|
||
|
assert '\\' in part
|
||
|
else:
|
||
|
assert '/' in part
|
||
|
expected_part = part
|
||
|
elif item == 'ext':
|
||
|
expected_part = file_path.suffix[1:]
|
||
|
if item == 'name':
|
||
|
expected_part = file_path.stem
|
||
|
for i, rx in filesystem.match_date_from_string(expected_part):
|
||
|
expected_part = re.sub(rx, '', expected_part)
|
||
|
elif item == 'custom':
|
||
|
expected_part = mask[2:-2]
|
||
|
elif item in ('city', 'country', 'location', 'state'):
|
||
|
expected_part = part
|
||
|
elif item in exif_tags.keys():
|
||
|
f = False
|
||
|
for key in exif_tags[item]:
|
||
|
if key in exif_data:
|
||
|
f = True
|
||
|
expected_part = exif_data[key]
|
||
|
break
|
||
|
if f == False:
|
||
|
expected_part = ''
|
||
|
|
||
|
assert part == expected_part
|
||
|
|
||
|
|
||
|
def test_get_date_taken(self):
|
||
|
filesystem = FileSystem()
|
||
|
for file_path in self.FILE_PATHS:
|
||
|
exif_data = ExifToolCaching(str(file_path)).asdict()
|
||
|
media = Media(str(file_path))
|
||
|
metadata = media.get_metadata()
|
||
|
date_taken = filesystem.get_date_taken(metadata)
|
||
|
|
||
|
dates = {}
|
||
|
for key, date in ('original', media.date_original), ('created',
|
||
|
media.date_created), ('modified', media.date_modified):
|
||
|
dates[key] = media.get_date_attribute(date)
|
||
|
|
||
|
if media.original_name_key in exif_data:
|
||
|
date_filename = filesystem.get_date_from_string(
|
||
|
exif_data[media.original_name_key])
|
||
|
else:
|
||
|
date_filename = filesystem.get_date_from_string(file_path.name)
|
||
|
|
||
|
if dates['original']:
|
||
|
assert date_taken == dates['original']
|
||
|
elif date_filename:
|
||
|
assert date_taken == date_filename
|
||
|
elif dates['created']:
|
||
|
assert date_taken == dates['created']
|
||
|
elif dates['modified']:
|
||
|
assert date_taken == dates['modified']
|
||
|
|
||
|
def test_sort_files(self, tmp_path):
|
||
|
db = Db(tmp_path)
|
||
|
filesystem = FileSystem(path_format=self.path_format)
|
||
|
|
||
|
summary, has_errors = filesystem.sort_files([self.SRCPATH], tmp_path, db)
|
||
|
|
||
|
# Summary is created and there is no errors
|
||
|
assert summary, summary
|
||
|
assert not has_errors, has_errors
|
||
|
|
||
|
# TODO check if path follow path_format
|
||
|
|
||
|
# TODO make another class?
|
||
|
def test_sort_file(self, tmp_path):
|
||
|
|
||
|
for mode in 'copy', 'move':
|
||
|
filesystem = FileSystem(path_format=self.path_format, mode=mode)
|
||
|
# copy mode
|
||
|
src_path = Path(self.SRCPATH, 'photo.png')
|
||
|
dest_path = Path(tmp_path,'photo_copy.png')
|
||
|
src_checksum = filesystem.checksum(src_path)
|
||
|
result_copy = filesystem.sort_file(src_path, dest_path)
|
||
|
assert result_copy
|
||
|
# Ensure files remain the same
|
||
|
assert filesystem.checkcomp(dest_path, src_checksum)
|
||
|
|
||
|
if mode == 'copy':
|
||
|
assert src_path.exists()
|
||
|
else:
|
||
|
assert not src_path.exists()
|
||
|
|
||
|
# TODO check for conflicts
|
||
|
|
||
|
|
||
|
# TODO check date
|
||
|
|
||
|
# filesystem.sort_files
|
||
|
#- Sort similar images into a directory
|
||
|
# filesystem.sort_similar
|
||
|
|