import shutil import subprocess import json import re import hashlib import functools import time from settings.local import DRAFT_DOMAIN, PREVIEW_ROUTER def hex_to_rgb(hex_color: str) -> tuple: """Convert hexadecimal color code to RGB tuple (range 0.0-1.0)""" hex_color = hex_color.lstrip('#') if len(hex_color) == 3: hex_color = ''.join([c*2 for c in hex_color]) # Handle shorthand form (e.g. #fff) try: r = int(hex_color[0:2], 16) / 255.0 g = int(hex_color[2:4], 16) / 255.0 b = int(hex_color[4:6], 16) / 255.0 return (r, g, b) except ValueError: raise ValueError(f"Invalid hexadecimal color code: {hex_color}") def is_windows_path(path): """Detect if the path is Windows style""" # Check if it starts with a drive letter (e.g. C:\) or contains Windows style separators return re.match(r'^[a-zA-Z]:\\|\\\\', path) is not None def zip_draft(draft_name): # Compress folder zip_path = f"./tmp/zip/{draft_name}.zip" shutil.make_archive(f"./tmp/zip/{draft_name}", 'zip', draft_name) return zip_path def url_to_hash(url, length=16): """ Convert URL to a fixed-length hash string (without extension) Parameters: - url: Original URL string - length: Length of the hash string (maximum 64, default 16) Returns: - Hash string (e.g.: 3a7f9e7d9a1b4e2d) """ # Ensure URL is bytes type url_bytes = url.encode('utf-8') # Use SHA-256 to generate hash (secure and highly unique) hash_object = hashlib.sha256(url_bytes) # Truncate to specified length of hexadecimal string return hash_object.hexdigest()[:length] def timing_decorator(func_name): """Decorator: Used to monitor function execution time""" def decorator(func): @functools.wraps(func) def wrapper(*args, **kwargs): start_time = time.time() print(f"[{func_name}] Starting execution...") try: result = func(*args, **kwargs) end_time = time.time() duration = end_time - start_time print(f"[{func_name}] Execution completed, time taken: {duration:.3f} seconds") return result except Exception as e: end_time = time.time() duration = end_time - start_time print(f"[{func_name}] Execution failed, time taken: {duration:.3f} seconds, error: {e}") raise return wrapper return decorator def generate_draft_url(draft_id): return f"{DRAFT_DOMAIN}{PREVIEW_ROUTER}?draft_id={draft_id}"