Files

125 lines
4.3 KiB
Python

"""
format_detect.py
Description: Detects and handles different image formats for metadata processing.
This module provides functionality to identify the format of image files and determine
the appropriate handler for reading and writing metadata.
Author: Eric Hiss (GitHub: EricRollei)
Contact: [eric@historic.camera, eric@rollei.us]
Version: 1.0.0
Date: [March 2025]
License: Dual License (Non-Commercial and Commercial Use)
Copyright (c) 2025 Eric Hiss. All rights reserved.
Dual License:
1. Non-Commercial Use: This software is licensed under the terms of the
Creative Commons Attribution-NonCommercial 4.0 International License.
To view a copy of this license, visit http://creativecommons.org/licenses/by-nc/4.0/
2. Commercial Use: For commercial use, a separate license is required.
Please contact Eric Hiss at [eric@historic.camera, eric@rollei.us] for licensing options.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
PARTICULAR PURPOSE AND NONINFRINGEMENT.
Dependencies:
This code depends on several third-party libraries, each with its own license:
"""
# Metadata_system/src/eric_metadata/utils/format_detect.py
import os
from typing import Optional, Callable, Dict, List, Set, Tuple
class FormatHandler:
"""Format detection and handling for different image types"""
# Group formats by their handling requirements
FORMAT_HANDLERS: Dict[str, List[str]] = {
'standard': ['.jpg', '.jpeg', '.png', '.tiff', '.tif', '.webp'],
'raw': ['.cr2', '.nef', '.arw', '.dng', '.orf', '.rw2'],
'layered': ['.psd', '.xcf'],
'special': ['.heic', '.heif', '.avif']
}
# Formats PyExiv2 can handle
PYEXIV2_COMPATIBLE: List[str] = ['.jpg', '.jpeg', '.tif', '.tiff', '.png']
# Formats requiring ExifTool
EXIFTOOL_REQUIRED: List[str] = [
'.cr2', '.nef', '.arw', '.dng', '.orf', '.rw2',
'.psd', '.heic', '.heif', '.avif'
]
@classmethod
def get_handler_for_file(cls, filepath: str) -> str:
"""
Determine appropriate handler type for a file
Args:
filepath: Path to the file
Returns:
str: Handler type ('standard', 'raw', 'layered', 'special', 'unknown')
"""
ext = os.path.splitext(filepath)[1].lower()
for category, extensions in cls.FORMAT_HANDLERS.items():
if ext in extensions:
return category
return 'unknown'
@classmethod
def can_use_pyexiv2(cls, filepath: str) -> bool:
"""
Check if PyExiv2 can handle this file format
Args:
filepath: Path to the file
Returns:
bool: True if PyExiv2 can handle this format
"""
ext = os.path.splitext(filepath)[1].lower()
return ext in cls.PYEXIV2_COMPATIBLE
@classmethod
def requires_exiftool(cls, filepath: str) -> bool:
"""
Check if ExifTool is required for this file format
Args:
filepath: Path to the file
Returns:
bool: True if ExifTool is required
"""
ext = os.path.splitext(filepath)[1].lower()
return ext in cls.EXIFTOOL_REQUIRED
@classmethod
def get_file_info(cls, filepath: str) -> Dict[str, any]:
"""
Get information about a file
Args:
filepath: Path to the file
Returns:
dict: File information including format, handler type, etc.
"""
ext = os.path.splitext(filepath)[1].lower()
handler_type = cls.get_handler_for_file(filepath)
return {
'path': filepath,
'extension': ext,
'handler_type': handler_type,
'can_use_pyexiv2': cls.can_use_pyexiv2(filepath),
'requires_exiftool': cls.requires_exiftool(filepath),
'is_raw': handler_type == 'raw',
'is_layered': handler_type == 'layered',
'is_special': handler_type == 'special',
'is_standard': handler_type == 'standard',
'base_path': os.path.splitext(filepath)[0]
}