ordigi/tests/test_filesystem.py

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