Spaces:
Sleeping
Sleeping
| """File and directory utilities.""" | |
| import json | |
| import os | |
| import re | |
| import shutil | |
| import time | |
| import uuid | |
| import zipfile | |
| from pathlib import Path | |
| from typing import Any, Dict, List, Optional | |
| def ensure_dir(path: str) -> str: | |
| """Ensure directory exists, creating if necessary. | |
| Args: | |
| path: Directory path | |
| Returns: | |
| Absolute path to directory | |
| """ | |
| os.makedirs(path, exist_ok=True) | |
| return os.path.abspath(path) | |
| def make_run_dir(base_dir: str) -> str: | |
| """Create a unique run directory with timestamp. | |
| Args: | |
| base_dir: Base directory for runs | |
| Returns: | |
| Path to newly created run directory | |
| """ | |
| run_id = time.strftime("%Y%m%d_%H%M%S") + "_" + uuid.uuid4().hex[:8] | |
| run_dir = os.path.join(base_dir, run_id) | |
| ensure_dir(run_dir) | |
| return run_dir | |
| def get_checkpoint_dir(run_dir: str) -> str: | |
| """Get or create checkpoint subdirectory. | |
| Args: | |
| run_dir: Run directory path | |
| Returns: | |
| Path to checkpoint directory | |
| """ | |
| return ensure_dir(os.path.join(run_dir, "checkpoints")) | |
| def write_text_file(path: str, content: Optional[str]) -> str: | |
| """Write text content to file. | |
| Args: | |
| path: File path | |
| content: Text content to write | |
| Returns: | |
| Path to written file | |
| """ | |
| ensure_dir(os.path.dirname(path)) | |
| with open(path, "w", encoding="utf-8") as f: | |
| f.write("" if content is None else str(content)) | |
| return path | |
| def write_json_file(path: str, data: Any) -> str: | |
| """Write JSON data to file. | |
| Args: | |
| path: File path | |
| data: Data to serialize as JSON | |
| Returns: | |
| Path to written file | |
| """ | |
| ensure_dir(os.path.dirname(path)) | |
| with open(path, "w", encoding="utf-8") as f: | |
| json.dump(data, f, indent=2, ensure_ascii=False) | |
| return path | |
| def extract_zip(zip_path: str, extract_dir: str) -> str: | |
| """Extract ZIP file to directory. | |
| Args: | |
| zip_path: Path to ZIP file | |
| extract_dir: Directory to extract to | |
| Returns: | |
| Path to extraction directory | |
| """ | |
| ensure_dir(extract_dir) | |
| with zipfile.ZipFile(zip_path, "r") as zf: | |
| zf.extractall(extract_dir) | |
| return extract_dir | |
| def collect_images_recursive(folder_path: str, extensions: tuple = (".png", ".jpg", ".jpeg")) -> List[str]: | |
| """Recursively collect image files from directory. | |
| Args: | |
| folder_path: Root directory to search | |
| extensions: Tuple of valid image extensions | |
| Returns: | |
| List of image file paths | |
| """ | |
| image_paths: List[str] = [] | |
| for root, _, files in os.walk(folder_path): | |
| for file in files: | |
| if file.lower().endswith(extensions): | |
| image_paths.append(os.path.join(root, file)) | |
| return image_paths | |
| def sort_images(image_paths: List[str]) -> List[str]: | |
| """Sort images by filename number, then alphabetically. | |
| Files starting with numbers are sorted numerically first. | |
| Args: | |
| image_paths: List of image paths | |
| Returns: | |
| Sorted list of image paths | |
| """ | |
| def sort_key(path: str): | |
| name = os.path.basename(path) | |
| m = re.match(r"(\d+)", name) | |
| if m: | |
| return (0, int(m.group(1)), name.lower()) | |
| return (1, name.lower()) | |
| return sorted(image_paths, key=sort_key) | |
| def copy_file_to_dir(src_path: str, dst_dir: str) -> str: | |
| """Copy file to destination directory. | |
| Args: | |
| src_path: Source file path | |
| dst_dir: Destination directory | |
| Returns: | |
| Path to copied file | |
| """ | |
| ensure_dir(dst_dir) | |
| dst_path = os.path.join(dst_dir, os.path.basename(src_path)) | |
| shutil.copy2(src_path, dst_path) | |
| return dst_path | |
| def list_files_in_folder(folder_path: str) -> List[str]: | |
| """List all files in folder recursively. | |
| Args: | |
| folder_path: Directory to scan | |
| Returns: | |
| List of file paths | |
| """ | |
| if not folder_path or not os.path.isdir(folder_path): | |
| return [] | |
| files: List[str] = [] | |
| for root, _, names in os.walk(folder_path): | |
| for name in names: | |
| full = os.path.join(root, name) | |
| if os.path.isfile(full): | |
| files.append(full) | |
| return sorted(files) | |
| def find_first_file_by_ext(folder_path: str, extensions: tuple) -> Optional[str]: | |
| """Find first file matching extensions. | |
| Args: | |
| folder_path: Directory to search | |
| extensions: Tuple of extensions to match | |
| Returns: | |
| Path to first matching file or None | |
| """ | |
| files = list_files_in_folder(folder_path) | |
| for f in files: | |
| if f.lower().endswith(extensions): | |
| return f | |
| return None | |
| def find_all_images_in_folder(folder_path: str, extensions: tuple = (".png", ".jpg", ".jpeg")) -> List[str]: | |
| """Find all images in folder. | |
| Args: | |
| folder_path: Directory to search | |
| extensions: Image extensions to match | |
| Returns: | |
| List of image paths | |
| """ | |
| if not folder_path or not os.path.isdir(folder_path): | |
| return [] | |
| images: List[str] = [] | |
| for root, _, names in os.walk(folder_path): | |
| for name in names: | |
| full = os.path.join(root, name) | |
| if os.path.isfile(full) and name.lower().endswith(extensions): | |
| images.append(full) | |
| return sort_images(images) | |