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)