File size: 7,256 Bytes
750e443
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
import gradio as gr
import chardet
import mimetypes
import pandas as pd
import json
import yaml
import toml
import configparser
import xml.etree.ElementTree as ET
from pathlib import Path

def read_file(file):
    if file is None:
        return "لطفا یک فایل انتخاب کنید"
    
    try:
        file_path = file.name
        file_extension = Path(file_path).suffix.lower().strip('.')
        
        # ابتدا با MIME type بررسی می‌کنیم
        mime_type, _ = mimetypes.guess_type(file_path)
        
        # اگر فایل صوتی یا تصویری باشد
        if mime_type and (mime_type.startswith('audio/') or mime_type.startswith('image/') or mime_type.startswith('video/')):
            return f"فایل‌های صوتی، تصویری و ویدیویی پشتیبانی نمی‌شوند. (MIME: {mime_type})"
        
        # فایل‌های باینری معروف که نباید خوانده شوند
        binary_extensions = {
            'exe', 'dll', 'so', 'dylib', 'bin', 'dat', 'db', 'sqlite',
            'zip', 'rar', '7z', 'tar', 'gz', 'bz2', 'xz',
            'jpg', 'jpeg', 'png', 'gif', 'bmp', 'ico', 'svg', 'webp',
            'mp3', 'mp4', 'avi', 'mkv', 'mov', 'wmv', 'flv', 'webm',
            'wav', 'flac', 'aac', 'ogg', 'wma', 'm4a',
            'pdf', 'doc', 'ppt', 'pptx', 'odt', 'ods', 'odp'
        }
        
        if file_extension in binary_extensions:
            return f"فرمت فایل .{file_extension} یک فایل باینری است و پشتیبانی نمی‌شود"
        
        # فایل‌های Excel
        if file_extension in ['xlsx', 'xls', 'xlsm', 'xlsb']:
            df = pd.read_excel(file_path)
            return f"=== محتوای Excel ===\n{df.to_string()}"
        
        # فایل‌های CSV و TSV
        elif file_extension in ['csv', 'tsv']:
            separator = '\t' if file_extension == 'tsv' else ','
            df = pd.read_csv(file_path, sep=separator)
            return f"=== محتوای {file_extension.upper()} ===\n{df.to_string()}"
        
        # فایل‌های JSON
        elif file_extension == 'json':
            with open(file_path, 'r', encoding='utf-8') as f:
                data = json.load(f)
            return f"=== محتوای JSON ===\n{json.dumps(data, indent=2, ensure_ascii=False)}"
        
        # فایل‌های YAML
        elif file_extension in ['yaml', 'yml']:
            with open(file_path, 'r', encoding='utf-8') as f:
                data = yaml.safe_load(f)
            return f"=== محتوای YAML ===\n{yaml.dump(data, allow_unicode=True, default_flow_style=False)}"
        
        # فایل‌های TOML
        elif file_extension == 'toml':
            with open(file_path, 'r', encoding='utf-8') as f:
                data = toml.load(f)
            return f"=== محتوای TOML ===\n{toml.dumps(data)}"
        
        # فایل‌های INI/CFG
        elif file_extension in ['ini', 'cfg', 'conf', 'config']:
            config = configparser.ConfigParser()
            config.read(file_path, encoding='utf-8')
            output = f"=== محتوای {file_extension.upper()} ===\n"
            for section in config.sections():
                output += f"\n[{section}]\n"
                for key, value in config.items(section):
                    output += f"{key} = {value}\n"
            return output
        
        # فایل‌های XML
        elif file_extension == 'xml':
            tree = ET.parse(file_path)
            root = tree.getroot()
            return f"=== محتوای XML ===\n{ET.tostring(root, encoding='unicode')}"
        
        # سایر فایل‌ها - تلاش برای خواندن به عنوان متن
        else:
            # تشخیص encoding
            with open(file_path, 'rb') as f:
                raw_data = f.read(10000)  # فقط 10KB اول برای تشخیص
                result = chardet.detect(raw_data)
                encoding = result['encoding'] if result['encoding'] else 'utf-8'
                confidence = result['confidence'] if 'confidence' in result else 0
            
            # اگر احتمال encoding کم باشد، احتمالا فایل باینری است
            if confidence < 0.7:
                try:
                    # تلاش با UTF-8
                    with open(file_path, 'r', encoding='utf-8') as f:
                        content = f.read()
                    return f"=== محتوای فایل (UTF-8) ===\n{content}"
                except UnicodeDecodeError:
                    return "این فایل احتمالاً باینری است یا encoding آن قابل تشخیص نیست"
            
            # خواندن با encoding تشخیص داده شده
            try:
                with open(file_path, 'r', encoding=encoding) as f:
                    content = f.read()
                return f"=== محتوای فایل ({encoding}) ===\n{content}"
            except:
                # تلاش نهایی با encodings مختلف
                for enc in ['utf-8', 'utf-16', 'latin-1', 'windows-1252', 'cp1256']:
                    try:
                        with open(file_path, 'r', encoding=enc) as f:
                            content = f.read()
                        return f"=== محتوای فایل ({enc}) ===\n{content}"
                    except:
                        continue
                
                return "نمی‌توان این فایل را خواند. احتمالاً فایل باینری است."
            
    except Exception as e:
        return f"خطا در خواندن فایل: {str(e)}"

# لیست فرمت‌های پشتیبانی شده
supported_formats = """
**فرمت‌های پشتیبانی شده:**
- فایل‌های متنی: .txt, .log, .md, .rst, .tex
- کدهای برنامه‌نویسی: .py, .js, .ts, .java, .cpp, .c, .h, .cs, .rb, .go, .rs, .swift, .kt, .scala, .r, .m, .php, .pl, .lua, .sh, .bat, .ps1
- فایل‌های وب: .html, .htm, .css, .scss, .sass, .less, .jsx, .tsx, .vue
- فایل‌های پیکربندی: .json, .yaml, .yml, .toml, .ini, .cfg, .conf, .config, .env, .properties
- فایل‌های داده: .csv, .tsv, .xml
- فایل‌های Office: .xlsx, .xls (نیاز به محتوای متنی)
- و بسیاری فرمت‌های متنی دیگر...

**فرمت‌های پشتیبانی نشده:**
- تصاویر: .jpg, .png, .gif, .bmp, و...
- صوت: .mp3, .wav, .flac, و...
- ویدیو: .mp4, .avi, .mkv, و...
- فایل‌های فشرده: .zip, .rar, .tar, و...
- فایل‌های باینری: .exe, .dll, .bin, و...
"""

# رابط کاربری Gradio
iface = gr.Interface(
    fn=read_file,
    inputs=gr.File(label="فایل را انتخاب کنید", file_types=None),
    outputs=gr.Textbox(label="محتوای فایل", lines=25, max_lines=100),
    title="خواننده جامع فایل‌های متنی",
    description="تقریباً هر فایل متنی را آپلود کنید تا محتوای آن را مشاهده کنید\n" + supported_formats,
    examples=[],
    theme="soft"
)

if __name__ == "__main__":
    iface.launch()