add go bench client
This commit is contained in:
157
backend/app/utils/file_organizer.py
Normal file
157
backend/app/utils/file_organizer.py
Normal file
@@ -0,0 +1,157 @@
|
||||
"""
|
||||
File Organizer - Organize uploads by hostname
|
||||
"""
|
||||
|
||||
import os
|
||||
import re
|
||||
from pathlib import Path
|
||||
from typing import Tuple
|
||||
|
||||
|
||||
def sanitize_hostname(hostname: str) -> str:
|
||||
"""
|
||||
Sanitize hostname for use as directory name
|
||||
|
||||
Args:
|
||||
hostname: The hostname to sanitize
|
||||
|
||||
Returns:
|
||||
Sanitized hostname safe for use as directory name
|
||||
"""
|
||||
# Remove invalid characters
|
||||
sanitized = re.sub(r'[^\w\-.]', '_', hostname)
|
||||
# Remove leading/trailing dots and underscores
|
||||
sanitized = sanitized.strip('._')
|
||||
# Replace multiple underscores with single
|
||||
sanitized = re.sub(r'_+', '_', sanitized)
|
||||
# Limit length
|
||||
sanitized = sanitized[:100]
|
||||
# Default if empty
|
||||
return sanitized if sanitized else 'unknown'
|
||||
|
||||
|
||||
def get_device_upload_paths(base_upload_dir: str, hostname: str) -> Tuple[str, str]:
|
||||
"""
|
||||
Get organized upload paths for a device
|
||||
|
||||
Args:
|
||||
base_upload_dir: Base upload directory (e.g., "./uploads")
|
||||
hostname: Device hostname
|
||||
|
||||
Returns:
|
||||
Tuple of (images_path, files_path)
|
||||
"""
|
||||
sanitized_hostname = sanitize_hostname(hostname)
|
||||
|
||||
images_path = os.path.join(base_upload_dir, sanitized_hostname, "images")
|
||||
files_path = os.path.join(base_upload_dir, sanitized_hostname, "files")
|
||||
|
||||
return images_path, files_path
|
||||
|
||||
|
||||
def ensure_device_directories(base_upload_dir: str, hostname: str) -> Tuple[str, str]:
|
||||
"""
|
||||
Ensure device upload directories exist
|
||||
|
||||
Args:
|
||||
base_upload_dir: Base upload directory
|
||||
hostname: Device hostname
|
||||
|
||||
Returns:
|
||||
Tuple of (images_path, files_path)
|
||||
"""
|
||||
images_path, files_path = get_device_upload_paths(base_upload_dir, hostname)
|
||||
|
||||
# Create directories if they don't exist
|
||||
Path(images_path).mkdir(parents=True, exist_ok=True)
|
||||
Path(files_path).mkdir(parents=True, exist_ok=True)
|
||||
|
||||
return images_path, files_path
|
||||
|
||||
|
||||
def get_upload_path(base_upload_dir: str, hostname: str, is_image: bool, filename: str) -> str:
|
||||
"""
|
||||
Get the full upload path for a file
|
||||
|
||||
Args:
|
||||
base_upload_dir: Base upload directory
|
||||
hostname: Device hostname
|
||||
is_image: True if file is an image, False for documents
|
||||
filename: The filename to store
|
||||
|
||||
Returns:
|
||||
Full path where file should be stored
|
||||
"""
|
||||
images_path, files_path = ensure_device_directories(base_upload_dir, hostname)
|
||||
|
||||
target_dir = images_path if is_image else files_path
|
||||
|
||||
return os.path.join(target_dir, filename)
|
||||
|
||||
|
||||
def is_image_file(filename: str, mime_type: str = None) -> bool:
|
||||
"""
|
||||
Check if a file is an image based on extension and/or mime type
|
||||
|
||||
Args:
|
||||
filename: The filename
|
||||
mime_type: Optional MIME type
|
||||
|
||||
Returns:
|
||||
True if file is an image
|
||||
"""
|
||||
# Check extension
|
||||
image_extensions = {'.jpg', '.jpeg', '.png', '.gif', '.webp', '.bmp', '.svg'}
|
||||
ext = os.path.splitext(filename)[1].lower()
|
||||
|
||||
if ext in image_extensions:
|
||||
return True
|
||||
|
||||
# Check MIME type if provided
|
||||
if mime_type and mime_type.startswith('image/'):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def migrate_existing_files(base_upload_dir: str, hostname: str, file_list: list) -> dict:
|
||||
"""
|
||||
Migrate existing files to new organized structure
|
||||
|
||||
Args:
|
||||
base_upload_dir: Base upload directory
|
||||
hostname: Device hostname
|
||||
file_list: List of tuples (filename, is_image)
|
||||
|
||||
Returns:
|
||||
Dictionary mapping old paths to new paths
|
||||
"""
|
||||
images_path, files_path = ensure_device_directories(base_upload_dir, hostname)
|
||||
|
||||
migrations = {}
|
||||
|
||||
for filename, is_image in file_list:
|
||||
old_path = os.path.join(base_upload_dir, filename)
|
||||
|
||||
if is_image:
|
||||
new_path = os.path.join(images_path, filename)
|
||||
else:
|
||||
new_path = os.path.join(files_path, filename)
|
||||
|
||||
migrations[old_path] = new_path
|
||||
|
||||
return migrations
|
||||
|
||||
|
||||
def get_relative_path(full_path: str, base_upload_dir: str) -> str:
|
||||
"""
|
||||
Get relative path from base upload directory
|
||||
|
||||
Args:
|
||||
full_path: Full file path
|
||||
base_upload_dir: Base upload directory
|
||||
|
||||
Returns:
|
||||
Relative path from base directory
|
||||
"""
|
||||
return os.path.relpath(full_path, base_upload_dir)
|
||||
Reference in New Issue
Block a user