first push
This commit is contained in:
10
src/exif_data.py
Normal file
10
src/exif_data.py
Normal file
@@ -0,0 +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)
|
||||
self.year = int(year)
|
||||
self.time = str(time)
|
||||
self.make = str(make)
|
||||
39
src/file_handler.py
Normal file
39
src/file_handler.py
Normal file
@@ -0,0 +1,39 @@
|
||||
import os
|
||||
import time
|
||||
import shutil
|
||||
import logging
|
||||
from progressbar.progressbar import ProgressBar
|
||||
|
||||
from exif_data import ExifData
|
||||
|
||||
|
||||
def sort_pictures(images:list, dst:str, logger:logging.Logger):
|
||||
image_total = len(images)
|
||||
image_counter = 0
|
||||
logging_infos = []
|
||||
progress_bar = ProgressBar(
|
||||
maxval=image_total,
|
||||
term_width=70
|
||||
)
|
||||
|
||||
print(f"Start sorting {image_total} images\n")
|
||||
progress_bar.start()
|
||||
start_timer = time.process_time()
|
||||
for image in images:
|
||||
image:ExifData
|
||||
path = os.path.join(dst, str(image.make), str(image.year), str(image.month), str(image.day))
|
||||
if not os.path.exists(path): os.makedirs(path)
|
||||
|
||||
stat_info = os.stat(image.path)
|
||||
shutil.move(src=image.path, dst=f"{path}/{image.name}")
|
||||
# os.chmod(path=f"{path}/{image.name}", mode=stat_info.st_mode)
|
||||
# logging_infos.append(f"Moved {image.path} -> {path}/{image.name}")
|
||||
logger.info(f"Moved {image.path} -> {path}/{image.name}")
|
||||
|
||||
progress_bar.update(image_counter)
|
||||
image_counter += 1
|
||||
|
||||
progress_bar.finish()
|
||||
print(f"\nDone\nSorted {image_total} images in {round(start_timer, 2)} seconds")
|
||||
|
||||
return logging_infos
|
||||
15
src/folder_handler.py
Normal file
15
src/folder_handler.py
Normal file
@@ -0,0 +1,15 @@
|
||||
import os
|
||||
|
||||
|
||||
def scan_dir(path:str):
|
||||
return next(os.walk(path))[2]
|
||||
|
||||
|
||||
def recursive_scan_dir(path:str):
|
||||
results = []
|
||||
for root, folders, files in os.walk(path):
|
||||
list_files = os.listdir(root)
|
||||
for file in list_files:
|
||||
current_file = f"{root}{os.sep}{file}"
|
||||
if os.path.isfile(current_file): results.append(current_file)
|
||||
return results
|
||||
23
src/main.py
Normal file
23
src/main.py
Normal file
@@ -0,0 +1,23 @@
|
||||
import sys
|
||||
import logging
|
||||
|
||||
from meta_data_handler import MetadataHandler
|
||||
from file_handler import sort_pictures
|
||||
from folder_handler import *
|
||||
|
||||
sys.path.append("../")
|
||||
log_folder = "."
|
||||
src = "../app/TempPic"
|
||||
dst = "../app/Bilder"
|
||||
|
||||
logger = logging.getLogger('AutoPicture')
|
||||
logger.setLevel(logging.DEBUG)
|
||||
handler = logging.FileHandler(filename=f'{log_folder}/AutoPicture.log', encoding='utf-8', mode='a')
|
||||
handler.setFormatter(logging.Formatter('%(asctime)s|%(levelname)s|%(name)s|:%(message)s'))
|
||||
logger.addHandler(handler)
|
||||
|
||||
metadata_handler = MetadataHandler()
|
||||
|
||||
files = recursive_scan_dir("../app")
|
||||
exif_data = metadata_handler.get_meta_data(images=files)
|
||||
sort_pictures(images=exif_data, dst=dst, logger=logger)
|
||||
63
src/meta_data_handler.py
Normal file
63
src/meta_data_handler.py
Normal file
@@ -0,0 +1,63 @@
|
||||
import magic
|
||||
from PIL import Image
|
||||
from PIL import ExifTags
|
||||
|
||||
from exif_data import ExifData
|
||||
|
||||
|
||||
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(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 __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]
|
||||
|
||||
return ExifData(image_path=imagePath, image_name=image_name, day=day, month=month, year=year, time=time, make=make)
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
Reference in New Issue
Block a user