File size: 4,427 Bytes
f09864d 02d3e23 ed85b4d 02d3e23 f09864d ed85b4d 02d3e23 f09864d a5a3530 ed85b4d a5a3530 02d3e23 ed85b4d 1d83642 ed85b4d 02d3e23 ed85b4d 1d83642 ed85b4d 02d3e23 ed85b4d 02d3e23 ed85b4d 1d83642 ed85b4d 1d83642 02d3e23 ed85b4d 1d83642 02d3e23 ed85b4d 02d3e23 ed85b4d 02d3e23 ed85b4d 02d3e23 ed85b4d 02d3e23 ed85b4d 02d3e23 ed85b4d 02d3e23 ed85b4d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 | import os
from pathlib import Path
from PIL import Image
from typing import List, Optional, Union, Any, Dict, Tuple
from .utils import IMG_EXTS, VID_EXTS, is_media, size_mb, unique_name
class FileHandler:
def __init__(self) -> None:
self.temp_dir = self._setup_temp()
def _setup_temp(self) -> str:
temp = os.path.join(os.getcwd(), 'temp_processing')
os.makedirs(temp, exist_ok=True)
return temp
def cleanup(self) -> None:
if os.path.exists(self.temp_dir):
import shutil
shutil.rmtree(self.temp_dir, ignore_errors=True)
def info(self, path: str) -> Dict[str, Any]:
return {
'path': path,
'name': os.path.basename(path),
'size_mb': size_mb(path),
'type': self._type(path),
'dims': self._dims(path)
}
def _type(self, path: str) -> str:
ext = Path(path).suffix.lower()
if ext in IMG_EXTS:
return 'image'
elif ext in VID_EXTS:
return 'video'
return 'unknown'
def _dims(self, path: str) -> Optional[str]:
if not os.path.exists(path):
return None
if Path(path).suffix.lower() in IMG_EXTS:
with Image.open(path) as img:
return f"{img.width}x{img.height}"
return None
def get_files(self, input: Union[str, List[Any], None]) -> List[str]:
if not input:
return []
if not isinstance(input, list):
input = [input]
# Handle folder
if (len(input) == 1 and
isinstance(input[0], str) and
os.path.isdir(input[0])):
return self._from_folder(input[0])
return self._extract_paths(input)
def _from_folder(self, folder: str) -> List[str]:
return [str(p) for p in Path(folder).rglob('*')
if p.is_file() and is_media(str(p))]
def _extract_paths(self, files: List[Any]) -> List[str]:
result = []
for f in files:
if f is None:
continue
path = None
if hasattr(f, 'name') and f.name:
path = f.name
elif hasattr(f, 'path') and f.path:
path = f.path
elif isinstance(f, str):
path = f
if path and os.path.exists(path) and is_media(path):
result.append(path)
return result
def preview(self, files: List[str], max_items: int = 6) -> Optional[str]:
if not files:
return None
imgs = [f for f in files[:max_items]
if os.path.exists(f) and Path(f).suffix.lower() in IMG_EXTS]
if not imgs:
return None
# Load and resize
images = []
for path in imgs:
with Image.open(path) as img:
copy = img.copy()
copy.thumbnail((120, 120))
images.append(copy)
# Create grid
cols = min(3, len(images))
rows = (len(images) + cols - 1) // cols
grid = Image.new('RGB', (cols * 120, rows * 120), 'white')
for i, img in enumerate(images):
x, y = (i % cols) * 120, (i // cols) * 120
grid.paste(img, (x, y))
path = os.path.join(self.temp_dir, unique_name('preview', '.jpg'))
grid.save(path, 'JPEG', quality=85)
return path
def files_info(self, input: Union[str, List[Any], None]) -> Tuple[List[str], Dict[str, Any]]:
files = self.get_files(input)
info = {
'total': len(files),
'size_mb': 0,
'images': 0,
'videos': 0,
'details': []
}
for path in files:
detail = self.info(path)
info['details'].append(detail)
info['size_mb'] += detail['size_mb']
if detail['type'] == 'image':
info['images'] += 1
elif detail['type'] == 'video':
info['videos'] += 1
info['size_mb'] = round(info['size_mb'], 2)
return files, info
def temp_path(self, name: str) -> str:
return os.path.join(self.temp_dir, name) |