File size: 4,020 Bytes
feef734
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""Работа с файлами"""
import os
import fnmatch
import logging
from typing import Dict, List, Tuple, Any

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 = "projects"):
        self.base_dir = os.path.abspath(base_dir)
        self.logger = logging.getLogger(__name__)
        os.makedirs(self.base_dir, exist_ok=True)
        self.logger.info(f"FileManager initialized with base_dir: {self.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)
        try:
            real_path = os.path.realpath(full_path)
            if not real_path.startswith(os.path.realpath(self.base_dir)):
                self.logger.warning(f"Path traversal attempt: {file_path}")
                return ("", "▸ ✗ ᴀᴄᴄᴇss ᴅᴇɴɪᴇᴅ\nPath traversal detected ‼️")
        except Exception as e:
            self.logger.error(f"Path resolution failed: {e}")
            return ("", "▸ ⚠️ ᴇʀʀᴏʀ\nPath resolution failed")

        if not os.path.exists(full_path):
            return ("", f"▸ ✗ ғɪʟᴇ ɴᴏᴛ Ғᴏᴜɴᴅ\n`{file_path}`")

        try:
            size = os.path.getsize(full_path)
            if size > max_size:
                return ("", f"▸ ⚠️ ᴛᴏᴏ ʟᴀʀɢᴇ\n{size} bytes > {max_size} limit")

            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"╭───────────────────╮\n"
                f" │ 📖 {lang.upper()} ᴍᴏᴅᴇ │\n"
                "├───────────────────┤\n"
                f" │ `{file_path}` │\n"
                f" │ {len(content)} chars read │\n"
                "╰───────────────────╯"
            )
        except Exception as e:
            self.logger.error(f"Read error for {file_path}: {e}")
            return ("", f"▸ ⚠️ ʀᴇᴀᴅ ᴇʀʀᴏʀ\n{str(e)[:100]}")

    def save_file(self, file_path: str, content: str) -> str:
        full_path = os.path.join(self.base_dir, file_path)
        try:
            real_path = os.path.realpath(full_path)
            if not real_path.startswith(os.path.realpath(self.base_dir)):
                return "▸ ✗ ᴀᴄᴄᴇss ᴅᴇɴɪᴇᴅ\nPath traversal detected ‼️"
        except Exception as e:
            return f"▸ ⚠️ ᴘᴀᴛʜ ᴇʀʀᴏʀ\n{str(e)[:100]}"

        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 (
                "╭───────────────────╮\n"
                " │ 💾 Fɪʟᴇ ʀᴇᴄᴇɪᴠᴇᴅ │\n"
                f" │ `{file_path}`   │\n"
                "├───────────────────┤\n"
                f" │ {len(content)} chars saved │\n"
                "╰───────────────────╯\n\n"
                "Send a command to process it:\n"
                "`/build Analyze this file`"
            )
        except Exception as e:
            self.logger.error(f"Save error for {file_path}: {e}")
            return f"▸ ⚠️ ᴡʀɪᴛᴇ ᴇʀʀᴏʀ\n{str(e)[:100]}"

FILE_MANAGER = FileManager()