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 0000000..71ea400 Binary files /dev/null and b/tests/test_files/test_image_001.JPG differ diff --git a/tests/test_files/test_image_001.png b/tests/test_files/test_image_001.png deleted file mode 100644 index 4fef204..0000000 Binary files a/tests/test_files/test_image_001.png and /dev/null differ diff --git a/tests/test_files/test_image_002.JPG b/tests/test_files/test_image_002.JPG new file mode 100644 index 0000000..11abc2c Binary files /dev/null and b/tests/test_files/test_image_002.JPG differ diff --git a/tests/test_files/test_image_002.png b/tests/test_files/test_image_002.png deleted file mode 100644 index 0de31e6..0000000 Binary files a/tests/test_files/test_image_002.png and /dev/null differ 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)