104 lines
2.9 KiB
Python
104 lines
2.9 KiB
Python
import hashlib
|
|
from blake3 import blake3
|
|
from blurhash import encode
|
|
|
|
from tqdm.auto import tqdm
|
|
|
|
from PIL import Image
|
|
|
|
|
|
def compute_blake3_hash(data, is_file=False, logger=None):
|
|
"""
|
|
Compute BLAKE3 hash of a file or string.
|
|
|
|
Args:
|
|
data (str): File path (if is_file=True) or raw string.
|
|
is_file (bool): Whether the input is a file path. Defaults to False.
|
|
logger: Optional logger for error messages (e.g., Django `self` or `tqdm`).
|
|
|
|
Returns:
|
|
str: BLAKE3 hash or None if an error occurs.
|
|
"""
|
|
try:
|
|
hasher = blake3()
|
|
|
|
if is_file:
|
|
with open(data, "rb") as f:
|
|
while chunk := f.read(65536):
|
|
hasher.update(chunk)
|
|
else:
|
|
hasher.update(data.encode())
|
|
|
|
return hasher.hexdigest()
|
|
|
|
except Exception as e:
|
|
error_message = f"Error computing hash: {e}"
|
|
|
|
if logger:
|
|
if hasattr(logger, "style") and hasattr(logger, "stdout"): # Django command
|
|
logger.stdout.write(logger.style.WARNING(error_message))
|
|
else: # Default to tqdm
|
|
tqdm.write(error_message)
|
|
|
|
return None
|
|
|
|
|
|
# Convenience wrappers for readability
|
|
def compute_file_hash_blake3(file_path, logger=None):
|
|
return compute_blake3_hash(file_path, is_file=True, logger=logger)
|
|
|
|
|
|
def compute_string_hash_blake3(string, logger=None):
|
|
return compute_blake3_hash(string, is_file=False, logger=logger)
|
|
|
|
|
|
def compute_md5_hash(file_path):
|
|
"""
|
|
Compute the MD5 hash of a file.
|
|
|
|
Args:
|
|
file_path (str): Path to the file.
|
|
|
|
Returns:
|
|
str: MD5 hash of the file.
|
|
"""
|
|
try:
|
|
hash_md5 = hashlib.md5()
|
|
with open(file_path, "rb") as f:
|
|
for chunk in iter(lambda: f.read(4096), b""):
|
|
hash_md5.update(chunk)
|
|
return hash_md5.hexdigest()
|
|
except Exception as e:
|
|
tqdm.write(f"Error computing MD5 hash: {e}")
|
|
return None
|
|
|
|
|
|
def compute_blur_hash(image_path, components_x=4, components_y=4, logger=None):
|
|
"""
|
|
Compute the BlurHash of an image.
|
|
|
|
Args:
|
|
image_path (str): Path to the image file.
|
|
components_x (int): Number of horizontal components for BlurHash.
|
|
components_y (int): Number of vertical components for BlurHash.
|
|
logger: Optional logger for error messages.
|
|
|
|
Returns:
|
|
str: BlurHash string or None if an error occurs.
|
|
"""
|
|
try:
|
|
with Image.open(image_path) as img:
|
|
img = img.convert("RGB") # Ensure it's in RGB mode
|
|
blur_hash = encode(img, components_x, components_y)
|
|
return blur_hash
|
|
|
|
except Exception as e:
|
|
error_message = f"Error computing BlurHash: {e}"
|
|
|
|
if logger:
|
|
if hasattr(logger, "style") and hasattr(logger, "stdout"): # Django command
|
|
logger.stdout.write(logger.style.WARNING(error_message))
|
|
else: # Default to tqdm
|
|
tqdm.write(error_message)
|
|
|
|
return None
|