From cb9e02f4a27b5ec5e82548d4c6c10da6805ed768 Mon Sep 17 00:00:00 2001 From: DasMoorhuhn Date: Fri, 1 Dec 2023 01:26:38 +0100 Subject: [PATCH 1/8] added tests and scan for releases --- requirements.txt | 5 +++- src/__init__.py | 0 src/exif_data.py | 10 ++++---- src/updater.py | 57 ++++++++++++++++++++++++++++++++++++++--- test.gitlab-ci.yml | 30 ++++++++++++++++++++++ tests/__init__.py | 0 tests/test_exif_data.py | 19 ++++++++++++++ 7 files changed, 111 insertions(+), 10 deletions(-) create mode 100644 src/__init__.py create mode 100644 test.gitlab-ci.yml create mode 100644 tests/__init__.py create mode 100644 tests/test_exif_data.py diff --git a/requirements.txt b/requirements.txt index e2c5c44..899e52b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -2,4 +2,7 @@ pillow python-magic progressbar virtualenv -requests \ No newline at end of file +requests +pytest==7.4.* +pytest-cov==4.1.* +pytest-factoryboy==2.5.* \ No newline at end of file diff --git a/src/__init__.py b/src/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/exif_data.py b/src/exif_data.py index 1283552..6fafe4a 100644 --- a/src/exif_data.py +++ b/src/exif_data.py @@ -1,10 +1,10 @@ class ExifData: """This is for an object that stores the data of a picture""" - def __init__(self, image_path, image_name, day, month, year, time, make) -> None: - self.path = image_path - self.name = image_name - self.day = int(day) - self.month = int(month) + def __init__(self, image_path:str, image_name:str, day:int, month:int, year:int, time:int, make:str) -> None: + self.path:str = image_path + self.name:str = image_name + self.day:int = int(day) + self.month:int = int(month) self.year = int(year) self.time = str(time) self.make = str(make) diff --git a/src/updater.py b/src/updater.py index e31aa29..f5a6d2d 100644 --- a/src/updater.py +++ b/src/updater.py @@ -2,17 +2,66 @@ import requests import json +class Version: + def __init__(self, data:dict): + self.version:str = data['version'] + self.version_int:int = int(self.version.replace(".", "")) + self.date:str = data['date'] + + +class Release: + def __init__(self, data:dict): + self.name = data['name'] + self.tag_name = data['tag_name'] + self.description = data['description'] + self.created_at = data['created_at'] + self.released_at = data['released_at'] + self.upcoming_release = data['upcoming_release'] + self.version_int = int(self.tag_name.replace(".", "")) + self.zip_file_url = data['assets']['sources'] + self.__proceed() + + def __proceed(self): + for assest in self.zip_file_url: + if assest['format'] == 'zip': + self.zip_file_url = assest['url'] + break + + def read_version(): with open(file=".version.json") as file: - version = json.load(file) + version = Version(json.load(file)) return version +def install(): + pass + + def check_for_update(): - request = "https://gitlab.com/DasMoorhuhn/autopicture-v3/-/raw/main/src/.version.json" - response = requests.get(request) + version_current = read_version() + request = "https://gitlab.com/api/v4/projects/52637155/releases" + response = requests.get(url=request, timeout=1) if not response.ok: return - print(response.text) + + # Get the latest release + releases_json = json.loads(response.text) + # index version + latest_release = [0, 0] + for release_json in releases_json: + release = Release(release_json) + if release.version_int > version_current.version_int: + latest_release[0] = releases_json.index(release_json) + latest_release[1] = release.version_int + + if latest_release == [0, 0]: return + release = Release(releases_json[latest_release[0]]) + print(f"v{version_current.version} -> v{release.tag_name}") + + if release.version_int > version_current.version_int: + # Update + print("Update") + print(release.zip_file_url) check_for_update() diff --git a/test.gitlab-ci.yml b/test.gitlab-ci.yml new file mode 100644 index 0000000..7e355f2 --- /dev/null +++ b/test.gitlab-ci.yml @@ -0,0 +1,30 @@ +prepare_job: + stage: prepare # This stage must run before the release stage + rules: + - if: $CI_COMMIT_TAG + when: never # Do not run this job when a tag is created manually + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run this job when commits are pushed or merged to the default branch + script: + - echo "EXTRA_DESCRIPTION=some message" >> variables.env # Generate the EXTRA_DESCRIPTION and TAG environment variables + - echo "TAG=v$(cat VERSION)" >> variables.env # and append to the variables.env file + artifacts: + reports: + dotenv: variables.env # Use artifacts:reports:dotenv to expose the variables to other jobs + +release_job: + stage: release + image: registry.gitlab.com/gitlab-org/release-cli:latest + needs: + - job: prepare_job + artifacts: true + rules: + - if: $CI_COMMIT_TAG + when: never # Do not run this job when a tag is created manually + - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # Run this job when commits are pushed or merged to the default branch + script: + - echo "running release_job for $TAG" + release: + name: 'Release $TAG' + description: 'Created using the release-cli $EXTRA_DESCRIPTION' # $EXTRA_DESCRIPTION and the $TAG + tag_name: '$TAG' # variables must be defined elsewhere + ref: '$CI_COMMIT_SHA' # in the pipeline. For example, in the diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_exif_data.py b/tests/test_exif_data.py new file mode 100644 index 0000000..c1fb0c9 --- /dev/null +++ b/tests/test_exif_data.py @@ -0,0 +1,19 @@ +import unittest +import sys +sys.path.append("../") + +from src.exif_data import ExifData + + +class TestExifData(unittest.TestCase): + exif_data = ExifData(image_path="/my/path/lol", + image_name="Secret.png", + make="SALAMI", + day=10, + month=10, + year=1010, + time=1237127392 + ) + + assert exif_data.name == "Secret.png" + assert exif_data.make == "SALAMI" From 2da422abc5243f3dad6ccc22fa6aca34f406d156 Mon Sep 17 00:00:00 2001 From: DasMoorhuhn Date: Thu, 7 Dec 2023 19:59:51 +0100 Subject: [PATCH 2/8] make pytests --- .coveragerc | 2 ++ .gitignore | 4 +++- README.md | 6 ++++++ pytest.ini | 3 +++ tests/test_exif_data.py | 24 ++++++++++-------------- 5 files changed, 24 insertions(+), 15 deletions(-) create mode 100644 .coveragerc create mode 100644 pytest.ini diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000..fe8645c --- /dev/null +++ b/.coveragerc @@ -0,0 +1,2 @@ +[run] +omit = tests/*, __init__.py \ No newline at end of file diff --git a/.gitignore b/.gitignore index af0af93..b3b495e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ __pycache__/ .idea/ app/ -*.log \ No newline at end of file +*/coverage/ +*.log +.coverage diff --git a/README.md b/README.md index 6d51a82..97dbde6 100644 --- a/README.md +++ b/README.md @@ -4,3 +4,9 @@ Dies ist die dritte Version von AutoPicture. # Erste Schritte +# Tests + +```bash +python3.10 -m pytest --no-header -rfp --cov --cov-report html:tests/coverage --cov-report xml:tests/coverage/coverage.xml tests/ +``` + diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 0000000..11422c9 --- /dev/null +++ b/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +pythonpath = . +addopts = --ignore-glob=**/tests/** \ No newline at end of file diff --git a/tests/test_exif_data.py b/tests/test_exif_data.py index c1fb0c9..51a6666 100644 --- a/tests/test_exif_data.py +++ b/tests/test_exif_data.py @@ -1,19 +1,15 @@ -import unittest -import sys -sys.path.append("../") - from src.exif_data import ExifData +import unittest class TestExifData(unittest.TestCase): - exif_data = ExifData(image_path="/my/path/lol", - image_name="Secret.png", - make="SALAMI", - day=10, - month=10, - year=1010, - time=1237127392 - ) + def test_exif_data(self): + exif_data = ExifData(image_path="/path/to/image", + image_name="Image.jpeg", + make="CAMERA", + month=12, + day=12, + year=2023, + time=1278897213) - assert exif_data.name == "Secret.png" - assert exif_data.make == "SALAMI" + assert exif_data.make == "CAMERA" From d9ac0072ac5b4d39bdd58807271d26693ded21c2 Mon Sep 17 00:00:00 2001 From: DasMoorhuhn Date: Thu, 7 Dec 2023 20:38:01 +0100 Subject: [PATCH 3/8] included all files --- .coveragerc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.coveragerc b/.coveragerc index fe8645c..a41e48b 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,2 +1,6 @@ [run] -omit = tests/*, __init__.py \ No newline at end of file +source = src +omit = tests/*, __init__.py + +[report] +include_namespace_packages = True \ No newline at end of file From 529776bac64787ad44539c76699850137dfadca2 Mon Sep 17 00:00:00 2001 From: DasMoorhuhn Date: Thu, 7 Dec 2023 21:54:32 +0100 Subject: [PATCH 4/8] start making tests --- src/main.py | 4 +- src/{folder_handler.py => scan_folder.py} | 4 +- .coveragerc => tests/.coveragerc | 3 -- tests/helpers/__init__.py | 0 tests/helpers/folder_helper.py | 19 +++++++++ pytest.ini => tests/pytest.ini | 0 tests/test_files/test_image_001.png | Bin 0 -> 121 bytes tests/test_files/test_image_002.png | Bin 0 -> 129 bytes tests/test_meta_data_handler.py | 0 tests/test_scan_dir.py | 46 ++++++++++++++++++++++ 10 files changed, 69 insertions(+), 7 deletions(-) rename src/{folder_handler.py => scan_folder.py} (82%) rename .coveragerc => tests/.coveragerc (52%) create mode 100644 tests/helpers/__init__.py create mode 100644 tests/helpers/folder_helper.py rename pytest.ini => tests/pytest.ini (100%) create mode 100644 tests/test_files/test_image_001.png create mode 100644 tests/test_files/test_image_002.png create mode 100644 tests/test_meta_data_handler.py create mode 100644 tests/test_scan_dir.py diff --git a/src/main.py b/src/main.py index 054c30c..ea4fc90 100644 --- a/src/main.py +++ b/src/main.py @@ -3,7 +3,7 @@ import logging from meta_data_handler import MetadataHandler from file_handler import sort_pictures -from folder_handler import * +from scan_folder import * sys.path.append("../") log_folder = "." @@ -29,7 +29,7 @@ def start_process(): raise err -files = recursive_scan_dir(src) +files = recursive_scan_folder(src) if len(files) > 0: start_process() else: diff --git a/src/folder_handler.py b/src/scan_folder.py similarity index 82% rename from src/folder_handler.py rename to src/scan_folder.py index 9b16c8a..61af7b8 100644 --- a/src/folder_handler.py +++ b/src/scan_folder.py @@ -1,11 +1,11 @@ import os -def scan_dir(path:str): +def scan_folder(path:str): return next(os.walk(path))[2] -def recursive_scan_dir(path:str): +def recursive_scan_folder(path:str): results = [] for root, folders, files in os.walk(path): list_files = os.listdir(root) diff --git a/.coveragerc b/tests/.coveragerc similarity index 52% rename from .coveragerc rename to tests/.coveragerc index a41e48b..5507af8 100644 --- a/.coveragerc +++ b/tests/.coveragerc @@ -1,6 +1,3 @@ [run] source = src omit = tests/*, __init__.py - -[report] -include_namespace_packages = True \ No newline at end of file diff --git a/tests/helpers/__init__.py b/tests/helpers/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/helpers/folder_helper.py b/tests/helpers/folder_helper.py new file mode 100644 index 0000000..0581a29 --- /dev/null +++ b/tests/helpers/folder_helper.py @@ -0,0 +1,19 @@ +import os +import shutil +from pathlib import Path + +TEST_FOLDER = ".test_folder" + + +def create_file(file): + Path(os.path.join(TEST_FOLDER, file)).touch() + + +def delete_folder(): + shutil.rmtree(TEST_FOLDER, ignore_errors=True) + + +def create_folders(): + delete_folder() + os.makedirs(os.path.join(TEST_FOLDER, '001', '001')) + os.makedirs(os.path.join(TEST_FOLDER, '002', '001')) diff --git a/pytest.ini b/tests/pytest.ini similarity index 100% rename from pytest.ini rename to tests/pytest.ini diff --git a/tests/test_files/test_image_001.png b/tests/test_files/test_image_001.png new file mode 100644 index 0000000000000000000000000000000000000000..4fef204f78ee6cf0ace9e5e340952e58aed43c48 GIT binary patch literal 121 zcmeAS@N?(olHy`uVBq!ia0vp^AT|dF6Oi-L1ke-*Ho2px!T$GxcSDcYw@}7CW9Z(UEr;B3<$IRpeiJ3s&4+h4G?O7E- O7K5j&pUXO@geCy)Kp>O= literal 0 HcmV?d00001 diff --git a/tests/test_files/test_image_002.png b/tests/test_files/test_image_002.png new file mode 100644 index 0000000000000000000000000000000000000000..0de31e6e7a5f1a972ff02b2211775270b51d9f7f GIT binary patch literal 129 zcmeAS@N?(olHy`uVBq!ia0vp^AT}ol6Oe2Eak7F*W(ivYfF#rGn literal 0 HcmV?d00001 diff --git a/tests/test_meta_data_handler.py b/tests/test_meta_data_handler.py new file mode 100644 index 0000000..e69de29 diff --git a/tests/test_scan_dir.py b/tests/test_scan_dir.py new file mode 100644 index 0000000..fde5766 --- /dev/null +++ b/tests/test_scan_dir.py @@ -0,0 +1,46 @@ +import unittest + +from helpers.folder_helper import delete_folder +from helpers.folder_helper import create_folders +from helpers.folder_helper import create_file +from helpers.folder_helper import TEST_FOLDER +from src.scan_folder import scan_folder +from src.scan_folder import recursive_scan_folder + + +class TestScanFolder(unittest.TestCase): + def test_scan_folder(self): + create_folders() + create_file(file='img_01.jpeg') + files = scan_folder(TEST_FOLDER) + delete_folder() + + assert len(files) == 1 + + def test_scan_empty_folder(self): + create_folders() + files = scan_folder(TEST_FOLDER) + delete_folder() + + assert len(files) == 0 + + def test_scan_recursive_folder(self): + create_folders() + create_file(file='img_01.jpeg') + create_file(file='img_02.jpeg') + create_file(file='001/img_03.jpeg') + create_file(file='001/001/img_04.jpeg') + create_file(file='002/001/img_05.jpeg') + + files = recursive_scan_folder(TEST_FOLDER) + delete_folder() + + assert len(files) == 5 + + def test_scan_recursive_empty_folder(self): + create_folders() + files = recursive_scan_folder(TEST_FOLDER) + delete_folder() + + assert len(files) == 0 + From 3ebe5bba7f0096ab19c28eac57cdfad1d4d23ce5 Mon Sep 17 00:00:00 2001 From: DasMoorhuhn Date: Thu, 7 Dec 2023 22:12:56 +0100 Subject: [PATCH 5/8] fixed test call --- tests/.coveragerc => .coveragerc | 0 README.md | 2 +- tests/pytest.ini => pytest.ini | 2 +- tests/start_tests.sh | 1 + tests/test_scan_dir.py | 3 +-- 5 files changed, 4 insertions(+), 4 deletions(-) rename tests/.coveragerc => .coveragerc (100%) rename tests/pytest.ini => pytest.ini (69%) create mode 100755 tests/start_tests.sh diff --git a/tests/.coveragerc b/.coveragerc similarity index 100% rename from tests/.coveragerc rename to .coveragerc diff --git a/README.md b/README.md index 97dbde6..1359056 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,6 @@ Dies ist die dritte Version von AutoPicture. # Tests ```bash -python3.10 -m pytest --no-header -rfp --cov --cov-report html:tests/coverage --cov-report xml:tests/coverage/coverage.xml tests/ +sh ./tests/start_tests.sh ``` diff --git a/tests/pytest.ini b/pytest.ini similarity index 69% rename from tests/pytest.ini rename to pytest.ini index 11422c9..16d574f 100644 --- a/tests/pytest.ini +++ b/pytest.ini @@ -1,3 +1,3 @@ [pytest] -pythonpath = . +pythonpath = tests addopts = --ignore-glob=**/tests/** \ No newline at end of file diff --git a/tests/start_tests.sh b/tests/start_tests.sh new file mode 100755 index 0000000..7c64f2f --- /dev/null +++ b/tests/start_tests.sh @@ -0,0 +1 @@ +python3.10 -m pytest --no-header -rfp --cov --cov-report html:tests/coverage --cov-report xml:tests/coverage/coverage.xml tests/ \ No newline at end of file diff --git a/tests/test_scan_dir.py b/tests/test_scan_dir.py index fde5766..e24a512 100644 --- a/tests/test_scan_dir.py +++ b/tests/test_scan_dir.py @@ -14,7 +14,7 @@ class TestScanFolder(unittest.TestCase): create_file(file='img_01.jpeg') files = scan_folder(TEST_FOLDER) delete_folder() - + assert len(files) == 1 def test_scan_empty_folder(self): @@ -43,4 +43,3 @@ class TestScanFolder(unittest.TestCase): delete_folder() assert len(files) == 0 - From 9ae71af1aa8cc7db23029def9f72aa0c6c2ed60b Mon Sep 17 00:00:00 2001 From: DasMoorhuhn Date: Thu, 7 Dec 2023 22:27:05 +0100 Subject: [PATCH 6/8] more tests --- src/meta_data_handler.py | 2 +- tests/test_meta_data_handler.py | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/meta_data_handler.py b/src/meta_data_handler.py index da23939..70d089d 100644 --- a/src/meta_data_handler.py +++ b/src/meta_data_handler.py @@ -2,7 +2,7 @@ import magic from PIL import Image from PIL import ExifTags -from exif_data import ExifData +from src.exif_data import ExifData class MetadataHandler: diff --git a/tests/test_meta_data_handler.py b/tests/test_meta_data_handler.py index e69de29..6bab6ac 100644 --- a/tests/test_meta_data_handler.py +++ b/tests/test_meta_data_handler.py @@ -0,0 +1,6 @@ +import unittest +from src.meta_data_handler import MetadataHandler + + +class TestMetadataHandler(unittest.TestCase): + pass From 0012c52adfd32b265e9085511b86b0ccef899cda Mon Sep 17 00:00:00 2001 From: DasMoorhuhn Date: Fri, 8 Dec 2023 00:44:12 +0100 Subject: [PATCH 7/8] 54 percent... wow --- src/exif_data.py | 2 +- src/file_handler.py | 4 +- src/main.py | 6 +- src/meta_data_handler.py | 99 ++++++++++++++-------------- tests/test_exif_data.py | 2 +- tests/test_file_handle.py | 38 +++++++++++ tests/test_files/test_image_001.JPG | Bin 0 -> 24871 bytes tests/test_files/test_image_001.png | Bin 121 -> 0 bytes tests/test_files/test_image_002.JPG | Bin 0 -> 25151 bytes tests/test_files/test_image_002.png | Bin 129 -> 0 bytes tests/test_meta_data_handler.py | 21 +++++- 11 files changed, 115 insertions(+), 57 deletions(-) create mode 100644 tests/test_file_handle.py create mode 100644 tests/test_files/test_image_001.JPG delete mode 100644 tests/test_files/test_image_001.png create mode 100644 tests/test_files/test_image_002.JPG delete mode 100644 tests/test_files/test_image_002.png diff --git a/src/exif_data.py b/src/exif_data.py index 6fafe4a..be26a64 100644 --- a/src/exif_data.py +++ b/src/exif_data.py @@ -1,6 +1,6 @@ class ExifData: """This is for an object that stores the data of a picture""" - def __init__(self, image_path:str, image_name:str, day:int, month:int, year:int, time:int, make:str) -> None: + def __init__(self, image_path:str, image_name:str, day:int, month:int, year:int, time:str, make:str) -> None: self.path:str = image_path self.name:str = image_name self.day:int = int(day) diff --git a/src/file_handler.py b/src/file_handler.py index ca8ce52..beba1a4 100644 --- a/src/file_handler.py +++ b/src/file_handler.py @@ -1,10 +1,12 @@ import os +import sys +sys.path.append("../") import time import shutil import logging from progressbar.progressbar import ProgressBar -from exif_data import ExifData +from src.exif_data import ExifData def sort_pictures(images:list, dst:str, logger:logging.Logger): diff --git a/src/main.py b/src/main.py index ea4fc90..e40638f 100644 --- a/src/main.py +++ b/src/main.py @@ -1,7 +1,7 @@ import sys import logging -from meta_data_handler import MetadataHandler +from meta_data_handler import get_meta_data from file_handler import sort_pictures from scan_folder import * @@ -16,12 +16,10 @@ handler = logging.FileHandler(filename=f'{log_folder}/AutoPicture.log', encoding handler.setFormatter(logging.Formatter('%(asctime)s|:%(message)s')) logger.addHandler(handler) -metadata_handler = MetadataHandler() - def start_process(): try: - exif_data = metadata_handler.get_meta_data(images=files) + exif_data = get_meta_data(images=files) sort_pictures(images=exif_data, dst=dst, logger=logger) except Exception as err: print(err) diff --git a/src/meta_data_handler.py b/src/meta_data_handler.py index 70d089d..72fb1ee 100644 --- a/src/meta_data_handler.py +++ b/src/meta_data_handler.py @@ -1,63 +1,66 @@ import magic +import sys + from PIL import Image from PIL import ExifTags +sys.path.append("../") from src.exif_data import ExifData +video_formats = ["MP4", "MOV", "M4V", "MKV", "AVI", "WMV", "AVCHD", "WEBM", "MPEG"] +picture_formats = ["JPG", "JPEG", "PNG", "TIFF"] +key_words = ["DateTime", "Make"] -class MetadataHandler: - """This class is for getting the meta data from a image or a video""" - def __init__(self) -> None: - self.__videoFormats = ["MP4", "MOV", "M4V", "MKV", "AVI", "WMV", "AVCHD", "WEBM", "MPEG"] - self.__pictureFormats = ["JPG", "JPEG", "PNG", "TIFF"] - self.__keyWords = ["DateTime", "Make"] +def is_file_video(path:str): + mime = magic.Magic(mime=True) + file = mime.from_file(path) + if file.find('video') != -1: return True + else: return False - def __is_file_video(self, path:str): - mime = magic.Magic(mime=True) - file = mime.from_file(path) - if file.find('video') != -1: return True - else: return False - def __get_image_meta_data(self, image_path): - image_extension = str(image_path).split("/")[-1].split(".") - # TODO: Sort out videos - img = Image.open(f"{image_path}") - values = [] - for tag, text in img.getexif().items(): - if tag in ExifTags.TAGS: - if image_extension[1].upper() in self.__pictureFormats: - values.append(ExifTags.TAGS[tag] + "|" + str(text)) - return self.__filter_date_and_make(metaTags=self.__filter_data(value=values), imagePath=image_path) +def get_image_meta_data(image_path): + image_extension = str(image_path).split("/")[-1].split(".") + # TODO: Sort out videos + img = Image.open(f"{image_path}") + values = [] + for tag, text in img.getexif().items(): + if tag in ExifTags.TAGS: + if image_extension[1].upper() in picture_formats: + values.append(ExifTags.TAGS[tag] + "|" + str(text)) + return filter_date_and_make(meta_tags=filter_data(value=values), image_path=image_path) - def __filter_date_and_make(self, metaTags: list, imagePath): - day = None - month = None - year = None - time = None - make = str(metaTags[1]).split("|")[1] - image_name = str(imagePath).split("/")[-1] - _date = str(metaTags[0]).split("|") - time = _date[1].split(" ")[1] - _date = _date[1].split(" ")[0].split(":") - day = _date[2] - month = _date[1] - year = _date[0] +def filter_date_and_make(meta_tags:list, image_path): + day = None + month = None + year = None + time = None + make = str(meta_tags[1]).split("|")[1] + image_name = str(image_path).split("/")[-1] - return ExifData(image_path=imagePath, image_name=image_name, day=day, month=month, year=year, time=time, make=make) + _date = str(meta_tags[0]).split("|") + time = _date[1].split(" ")[1] + _date = _date[1].split(" ")[0].split(":") + day = int(_date[2]) + month = int(_date[1]) + year = int(_date[0]) - def __filter_data(self, value): - value_return = [] - for k in self.__keyWords: - for v in value: - temp = v.split("|") - if temp[0] == k: - value_return.append(v) - return value_return + return ExifData(image_path=image_path, image_name=image_name, day=day, month=month, year=year, time=time, make=make) - def get_meta_data(self, images: list): - exif_data_list = [] - for image in images: - exif_data_list.append(self.__get_image_meta_data(image_path=image)) - return exif_data_list + +def filter_data(value): + value_return = [] + for k in key_words: + for v in value: + temp = v.split("|") + if temp[0] == k: + value_return.append(v) + return value_return + + +def get_meta_data(images: list): + exif_data_list = [] + for image in images: + exif_data_list.append(get_image_meta_data(image_path=image)) + return exif_data_list diff --git a/tests/test_exif_data.py b/tests/test_exif_data.py index 51a6666..52593b1 100644 --- a/tests/test_exif_data.py +++ b/tests/test_exif_data.py @@ -10,6 +10,6 @@ class TestExifData(unittest.TestCase): month=12, day=12, year=2023, - time=1278897213) + time="10:10:10") assert exif_data.make == "CAMERA" diff --git a/tests/test_file_handle.py b/tests/test_file_handle.py new file mode 100644 index 0000000..aa09186 --- /dev/null +++ b/tests/test_file_handle.py @@ -0,0 +1,38 @@ +import unittest +import shutil +import os + +from unittest.mock import Mock + +from src.file_handler import sort_pictures +from src.scan_folder import recursive_scan_folder +from src.meta_data_handler import get_meta_data + +TEST_IMAGES = "tests/test_files" +TEST_FOLDER = ".test_folder" + + +def delete_test_folder(): + shutil.rmtree(TEST_FOLDER, ignore_errors=True) + + +def copy_test_images(): + delete_test_folder() + os.makedirs(os.path.join(TEST_FOLDER, 'Temp')) + os.makedirs(os.path.join(TEST_FOLDER, 'Images')) + shutil.copy(src=os.path.join(TEST_IMAGES, 'test_image_001.JPG'), dst=os.path.join(TEST_FOLDER, 'Temp')) + shutil.copy(src=os.path.join(TEST_IMAGES, 'test_image_002.JPG'), dst=os.path.join(TEST_FOLDER, 'Temp')) + + +class TestFileHandler(unittest.TestCase): + def test_file_handler(self): + copy_test_images() + files = recursive_scan_folder(TEST_FOLDER) + exif_data = get_meta_data(files) + sort_pictures(images=exif_data, logger=Mock(), dst=os.path.join(TEST_FOLDER, 'Images')) + sorted_pictures = recursive_scan_folder(TEST_FOLDER) + delete_test_folder() + + assert len(sorted_pictures) == 2 + assert sorted_pictures == ['.test_folder/Images/SONY/2023/10/25/test_image_002.JPG', + '.test_folder/Images/SONY/2023/10/28/test_image_001.JPG'] diff --git a/tests/test_files/test_image_001.JPG b/tests/test_files/test_image_001.JPG new file mode 100644 index 0000000000000000000000000000000000000000..71ea400e7f5e877f77f67cf0e34a7b77af945118 GIT binary patch literal 24871 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 literal 0 HcmV?d00001 diff --git a/tests/test_files/test_image_001.png b/tests/test_files/test_image_001.png deleted file mode 100644 index 4fef204f78ee6cf0ace9e5e340952e58aed43c48..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 121 zcmeAS@N?(olHy`uVBq!ia0vp^AT|dF6Oi-L1ke-*Ho2px!T$GxcSDcYw@}7CW9Z(UEr;B3<$IRpeiJ3s&4+h4G?O7E- O7K5j&pUXO@geCy)Kp>O= diff --git a/tests/test_files/test_image_002.JPG b/tests/test_files/test_image_002.JPG new file mode 100644 index 0000000000000000000000000000000000000000..11abc2c6a5e6bb1a584013e57bdb59abeb750b28 GIT binary patch literal 25151 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 DEOF#z literal 0 HcmV?d00001 diff --git a/tests/test_files/test_image_002.png b/tests/test_files/test_image_002.png deleted file mode 100644 index 0de31e6e7a5f1a972ff02b2211775270b51d9f7f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 129 zcmeAS@N?(olHy`uVBq!ia0vp^AT}ol6Oe2Eak7F*W(ivYfF#rGn diff --git a/tests/test_meta_data_handler.py b/tests/test_meta_data_handler.py index 6bab6ac..0335113 100644 --- a/tests/test_meta_data_handler.py +++ b/tests/test_meta_data_handler.py @@ -1,6 +1,23 @@ import unittest -from src.meta_data_handler import MetadataHandler +import os + +from src.meta_data_handler import get_meta_data +from src.meta_data_handler import get_image_meta_data +from src.meta_data_handler import filter_data +from src.meta_data_handler import filter_date_and_make +from src.meta_data_handler import is_file_video +from src.scan_folder import recursive_scan_folder + +TEST_IMAGES = "tests/test_files" class TestMetadataHandler(unittest.TestCase): - pass + def test_get_image_meta_data(self): + image_exif_data = get_image_meta_data(image_path=f"{TEST_IMAGES}/test_image_001.JPG") + assert image_exif_data.name == "test_image_001.JPG" + + def test_get_meta_data(self): + images = recursive_scan_folder(TEST_IMAGES) + print(images) + exif_data = get_meta_data(images) + assert len(exif_data) == len(images) From 27c5cd5076fd6b6b76d9b3485118b0fb5bdb9bef Mon Sep 17 00:00:00 2001 From: DasMoorhuhn Date: Fri, 8 Dec 2023 01:14:01 +0100 Subject: [PATCH 8/8] more test stuff --- tests/helpers/folder_helper.py | 11 +++++++++++ tests/test_file_handle.py | 31 +++++++++---------------------- tests/test_scan_dir.py | 1 + 3 files changed, 21 insertions(+), 22 deletions(-) diff --git a/tests/helpers/folder_helper.py b/tests/helpers/folder_helper.py index 0581a29..7cd8521 100644 --- a/tests/helpers/folder_helper.py +++ b/tests/helpers/folder_helper.py @@ -3,6 +3,9 @@ import shutil from pathlib import Path TEST_FOLDER = ".test_folder" +TEST_IMAGES = "tests/test_files" +TEST_TEMP_FOLDER = os.path.join(TEST_FOLDER, 'Temp') +TEST_IMAGE_FOLDER = os.path.join(TEST_FOLDER, 'Images') def create_file(file): @@ -17,3 +20,11 @@ def create_folders(): delete_folder() os.makedirs(os.path.join(TEST_FOLDER, '001', '001')) os.makedirs(os.path.join(TEST_FOLDER, '002', '001')) + + +def copy_test_images(): + delete_folder() + os.makedirs(TEST_TEMP_FOLDER) + os.makedirs(TEST_IMAGE_FOLDER) + shutil.copy(src=os.path.join(TEST_IMAGES, 'test_image_001.JPG'), dst=TEST_TEMP_FOLDER) + shutil.copy(src=os.path.join(TEST_IMAGES, 'test_image_002.JPG'), dst=TEST_TEMP_FOLDER) diff --git a/tests/test_file_handle.py b/tests/test_file_handle.py index aa09186..07a54f4 100644 --- a/tests/test_file_handle.py +++ b/tests/test_file_handle.py @@ -1,38 +1,25 @@ import unittest -import shutil -import os - from unittest.mock import Mock +from helpers.folder_helper import TEST_FOLDER +from helpers.folder_helper import TEST_IMAGE_FOLDER +from helpers.folder_helper import delete_folder +from helpers.folder_helper import copy_test_images + from src.file_handler import sort_pictures from src.scan_folder import recursive_scan_folder from src.meta_data_handler import get_meta_data -TEST_IMAGES = "tests/test_files" -TEST_FOLDER = ".test_folder" - - -def delete_test_folder(): - shutil.rmtree(TEST_FOLDER, ignore_errors=True) - - -def copy_test_images(): - delete_test_folder() - os.makedirs(os.path.join(TEST_FOLDER, 'Temp')) - os.makedirs(os.path.join(TEST_FOLDER, 'Images')) - shutil.copy(src=os.path.join(TEST_IMAGES, 'test_image_001.JPG'), dst=os.path.join(TEST_FOLDER, 'Temp')) - shutil.copy(src=os.path.join(TEST_IMAGES, 'test_image_002.JPG'), dst=os.path.join(TEST_FOLDER, 'Temp')) - class TestFileHandler(unittest.TestCase): def test_file_handler(self): copy_test_images() files = recursive_scan_folder(TEST_FOLDER) exif_data = get_meta_data(files) - sort_pictures(images=exif_data, logger=Mock(), dst=os.path.join(TEST_FOLDER, 'Images')) + sort_pictures(images=exif_data, logger=Mock(), dst=TEST_IMAGE_FOLDER) sorted_pictures = recursive_scan_folder(TEST_FOLDER) - delete_test_folder() + delete_folder() assert len(sorted_pictures) == 2 - assert sorted_pictures == ['.test_folder/Images/SONY/2023/10/25/test_image_002.JPG', - '.test_folder/Images/SONY/2023/10/28/test_image_001.JPG'] + assert "".join(picture for picture in sorted_pictures if '2023/10/25/test_image_002.JPG' in picture) != "" + assert "".join(picture for picture in sorted_pictures if '2023/10/28/test_image_001.JPG' in picture) != "" diff --git a/tests/test_scan_dir.py b/tests/test_scan_dir.py index e24a512..295ed17 100644 --- a/tests/test_scan_dir.py +++ b/tests/test_scan_dir.py @@ -4,6 +4,7 @@ from helpers.folder_helper import delete_folder from helpers.folder_helper import create_folders from helpers.folder_helper import create_file from helpers.folder_helper import TEST_FOLDER + from src.scan_folder import scan_folder from src.scan_folder import recursive_scan_folder