85 lines
2.3 KiB
Python
85 lines
2.3 KiB
Python
import os
|
|
from pathlib import Path
|
|
from dataclasses import dataclass
|
|
from typing import List
|
|
from datetime import datetime
|
|
|
|
|
|
@dataclass
|
|
class FileInfo:
|
|
"""Data class to represent file information"""
|
|
name: str
|
|
path: str
|
|
size: int
|
|
file_type: str
|
|
is_dir: bool
|
|
modified_time: str
|
|
|
|
@property
|
|
def size_readable(self) -> str:
|
|
"""Convert size to human-readable format"""
|
|
for unit in ['B', 'KB', 'MB', 'GB']:
|
|
if self.size < 1024:
|
|
return f"{self.size:.2f} {unit}"
|
|
self.size /= 1024
|
|
return f"{self.size:.2f} TB"
|
|
|
|
|
|
class FileSystemReader:
|
|
"""Handles reading file system information"""
|
|
|
|
def __init__(self, root_path: str):
|
|
self.root_path = Path(root_path)
|
|
|
|
def get_files_and_folders(self) -> List[FileInfo]:
|
|
"""
|
|
Read all files and folders from the root path
|
|
|
|
Returns:
|
|
List[FileInfo]: List of file information objects
|
|
"""
|
|
items = []
|
|
|
|
if not self.root_path.exists():
|
|
return items
|
|
|
|
try:
|
|
for item in self.root_path.iterdir():
|
|
try:
|
|
stat_info = item.stat()
|
|
file_info = FileInfo(
|
|
name=item.name,
|
|
path=str(item),
|
|
size=stat_info.st_size,
|
|
file_type=self._get_file_type(item),
|
|
is_dir=item.is_dir(),
|
|
modified_time=datetime.fromtimestamp(
|
|
stat_info.st_mtime
|
|
).strftime("%Y-%m-%d %H:%M:%S")
|
|
)
|
|
items.append(file_info)
|
|
except (PermissionError, OSError):
|
|
# Skip files/folders we can't read
|
|
continue
|
|
|
|
# Sort: folders first, then by name
|
|
items.sort(key=lambda x: (not x.is_dir, x.name.lower()))
|
|
return items
|
|
|
|
except PermissionError:
|
|
return items
|
|
|
|
def _get_file_type(self, path: Path) -> str:
|
|
"""
|
|
Determine file type
|
|
|
|
Args:
|
|
path: Path object
|
|
|
|
Returns:
|
|
str: File type (Folder, or extension)
|
|
"""
|
|
if path.is_dir():
|
|
return "Folder"
|
|
return path.suffix[1:].upper() if path.suffix else "File"
|