54 percent... wow
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
class ExifData:
|
class ExifData:
|
||||||
"""This is for an object that stores the data of a picture"""
|
"""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.path:str = image_path
|
||||||
self.name:str = image_name
|
self.name:str = image_name
|
||||||
self.day:int = int(day)
|
self.day:int = int(day)
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
|
sys.path.append("../")
|
||||||
import time
|
import time
|
||||||
import shutil
|
import shutil
|
||||||
import logging
|
import logging
|
||||||
from progressbar.progressbar import ProgressBar
|
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):
|
def sort_pictures(images:list, dst:str, logger:logging.Logger):
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import sys
|
import sys
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from meta_data_handler import MetadataHandler
|
from meta_data_handler import get_meta_data
|
||||||
from file_handler import sort_pictures
|
from file_handler import sort_pictures
|
||||||
from scan_folder import *
|
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'))
|
handler.setFormatter(logging.Formatter('%(asctime)s|:%(message)s'))
|
||||||
logger.addHandler(handler)
|
logger.addHandler(handler)
|
||||||
|
|
||||||
metadata_handler = MetadataHandler()
|
|
||||||
|
|
||||||
|
|
||||||
def start_process():
|
def start_process():
|
||||||
try:
|
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)
|
sort_pictures(images=exif_data, dst=dst, logger=logger)
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
print(err)
|
print(err)
|
||||||
|
|||||||
@@ -1,63 +1,66 @@
|
|||||||
import magic
|
import magic
|
||||||
|
import sys
|
||||||
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
from PIL import ExifTags
|
from PIL import ExifTags
|
||||||
|
|
||||||
|
sys.path.append("../")
|
||||||
from src.exif_data import ExifData
|
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:
|
def is_file_video(path:str):
|
||||||
self.__videoFormats = ["MP4", "MOV", "M4V", "MKV", "AVI", "WMV", "AVCHD", "WEBM", "MPEG"]
|
mime = magic.Magic(mime=True)
|
||||||
self.__pictureFormats = ["JPG", "JPEG", "PNG", "TIFF"]
|
file = mime.from_file(path)
|
||||||
self.__keyWords = ["DateTime", "Make"]
|
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):
|
def get_image_meta_data(image_path):
|
||||||
image_extension = str(image_path).split("/")[-1].split(".")
|
image_extension = str(image_path).split("/")[-1].split(".")
|
||||||
# TODO: Sort out videos
|
# TODO: Sort out videos
|
||||||
img = Image.open(f"{image_path}")
|
img = Image.open(f"{image_path}")
|
||||||
values = []
|
values = []
|
||||||
for tag, text in img.getexif().items():
|
for tag, text in img.getexif().items():
|
||||||
if tag in ExifTags.TAGS:
|
if tag in ExifTags.TAGS:
|
||||||
if image_extension[1].upper() in self.__pictureFormats:
|
if image_extension[1].upper() in picture_formats:
|
||||||
values.append(ExifTags.TAGS[tag] + "|" + str(text))
|
values.append(ExifTags.TAGS[tag] + "|" + str(text))
|
||||||
return self.__filter_date_and_make(metaTags=self.__filter_data(value=values), imagePath=image_path)
|
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("|")
|
def filter_date_and_make(meta_tags:list, image_path):
|
||||||
time = _date[1].split(" ")[1]
|
day = None
|
||||||
_date = _date[1].split(" ")[0].split(":")
|
month = None
|
||||||
day = _date[2]
|
year = None
|
||||||
month = _date[1]
|
time = None
|
||||||
year = _date[0]
|
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):
|
return ExifData(image_path=image_path, image_name=image_name, day=day, month=month, year=year, time=time, make=make)
|
||||||
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
|
|
||||||
|
|
||||||
def get_meta_data(self, images: list):
|
|
||||||
exif_data_list = []
|
def filter_data(value):
|
||||||
for image in images:
|
value_return = []
|
||||||
exif_data_list.append(self.__get_image_meta_data(image_path=image))
|
for k in key_words:
|
||||||
return exif_data_list
|
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
|
||||||
|
|||||||
@@ -10,6 +10,6 @@ class TestExifData(unittest.TestCase):
|
|||||||
month=12,
|
month=12,
|
||||||
day=12,
|
day=12,
|
||||||
year=2023,
|
year=2023,
|
||||||
time=1278897213)
|
time="10:10:10")
|
||||||
|
|
||||||
assert exif_data.make == "CAMERA"
|
assert exif_data.make == "CAMERA"
|
||||||
|
|||||||
38
tests/test_file_handle.py
Normal file
38
tests/test_file_handle.py
Normal file
@@ -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']
|
||||||
BIN
tests/test_files/test_image_001.JPG
Normal file
BIN
tests/test_files/test_image_001.JPG
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 24 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 121 B |
BIN
tests/test_files/test_image_002.JPG
Normal file
BIN
tests/test_files/test_image_002.JPG
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 129 B |
@@ -1,6 +1,23 @@
|
|||||||
import unittest
|
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):
|
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)
|
||||||
|
|||||||
Reference in New Issue
Block a user