PinkSky / server /file_manager.py
FreshPixels's picture
Rename file_manager.py to server/file_manager.py
2afd95f verified
Raw
History Blame
4.33 kB
"""Работа с файлами"""
import os
import fnmatch
from typing import Dict, List, Tuple, Any
from datetime import datetime
class FileManager:
SUPPORTED_EXTENSIONS = {
'.txt': 'text', '.py': 'python', '.js': 'javascript',
'.html': 'html', '.css': 'css', '.json': 'json',
'.yaml': 'yaml', '.yml': 'yaml', '.md': 'markdown',
'.csv': 'csv', '.xml': 'xml', '.log': 'log',
'.sql': 'sql', '.sh': 'bash', '.bat': 'batch',
'.ps1': 'powershell', '.ipynb': 'jupyter',
}
def __init__(self, base_dir: str = "."):
self.base_dir = base_dir
def read_file(self, file_path: str, max_size: int = 100000) -> Tuple[str, str]:
full_path = os.path.join(self.base_dir, file_path)
if not os.path.exists(full_path):
return ("", f"❌ Файл не найден: {file_path}")
try:
size = os.path.getsize(full_path)
if size > max_size:
return ("", f"⚠️ Файл слишком большой ({size} bytes > {max_size})")
with open(full_path, 'r', encoding='utf-8', errors='ignore') as f:
content = f.read()
ext = os.path.splitext(file_path)[1].lower()
lang = self.SUPPORTED_EXTENSIONS.get(ext, 'text')
return (content, f"✅ Прочитано {len(content)} chars ({lang})")
except Exception as e:
return ("", f"❌ Ошибка чтения: {e}")
def read_multiple_files(self, file_paths: List[str], max_total: int = 50000) -> Dict[str, Tuple[str, str]]:
results = {}
total = 0
for fp in file_paths:
content, status = self.read_file(fp)
if content:
total += len(content)
if total > max_total:
results[fp] = ("", "⚠️ Превышен общий лимит")
break
results[fp] = (content, status)
return results
def list_files(self, directory: str = ".", pattern: str = "*", recursive: bool = False) -> List[str]:
base = os.path.join(self.base_dir, directory)
if not os.path.exists(base):
return []
results = []
if recursive:
for root, dirs, files in os.walk(base):
for f in files:
rel = os.path.relpath(os.path.join(root, f), self.base_dir)
if self._match_pattern(f, pattern):
results.append(rel)
else:
for f in os.listdir(base):
if os.path.isfile(os.path.join(base, f)) and self._match_pattern(f, pattern):
results.append(os.path.join(directory, f))
return results
def save_file(self, file_path: str, content: str) -> str:
full_path = os.path.join(self.base_dir, file_path)
try:
os.makedirs(os.path.dirname(full_path), exist_ok=True)
with open(full_path, 'w', encoding='utf-8') as f:
f.write(content)
return f"✅ Сохранено: {file_path} ({len(content)} chars)"
except Exception as e:
return f"❌ Ошибка сохранения: {e}"
def analyze_file(self, file_path: str) -> Dict[str, Any]:
full_path = os.path.join(self.base_dir, file_path)
if not os.path.exists(full_path):
return {"error": "Файл не найден"}
try:
stat = os.stat(full_path)
ext = os.path.splitext(file_path)[1].lower()
lang = self.SUPPORTED_EXTENSIONS.get(ext, 'unknown')
with open(full_path, 'r', encoding='utf-8', errors='ignore') as f:
content = f.read()
lines = content.count('\n') + 1
return {
"path": file_path,
"size": stat.st_size,
"lines": lines,
"language": lang,
"modified": datetime.fromtimestamp(stat.st_mtime).isoformat(),
"chars": len(content)
}
except Exception as e:
return {"error": str(e)}
def _match_pattern(self, filename: str, pattern: str) -> bool:
if pattern == "*":
return True
return fnmatch.fnmatch(filename, pattern)
FILE_MANAGER = FileManager()