Alikhani099961 commited on
Commit
cac091d
·
verified ·
1 Parent(s): 9506ed2

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +347 -0
app.py CHANGED
@@ -0,0 +1,347 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import re
3
+ import json
4
+ from typing import Dict, List, Tuple, Optional
5
+ from dataclasses import dataclass
6
+
7
+ @dataclass
8
+ class PineError:
9
+ line_number: int
10
+ error_type: str
11
+ description: str
12
+ suggestion: str
13
+ severity: str
14
+
15
+ class PineProfessionalFixer:
16
+ def __init__(self):
17
+ self.version_patterns = {
18
+ 'v4': r'//@version\s*=\s*4',
19
+ 'v5': r'//@version\s*=\s*5',
20
+ 'v6': r'//@version\s*=\s*6'
21
+ }
22
+
23
+ # نقشه تبدیل توابع قدیمی به جدید
24
+ self.function_migrations = {
25
+ 'v4_to_v5': {
26
+ 'study': 'indicator',
27
+ 'security': 'request.security',
28
+ 'tostring': 'str.tostring',
29
+ 'tonumber': 'str.tonumber',
30
+ 'input': 'input.int',
31
+ 'hline': 'hline',
32
+ 'alertcondition': 'alert'
33
+ },
34
+ 'v5_to_v6': {
35
+ 'syminfo.ticker': 'syminfo.tickerid',
36
+ 'security': 'request.security'
37
+ }
38
+ }
39
+
40
+ # الگوهای خطاهای رایج
41
+ self.error_patterns = {
42
+ 'syntax_errors': [
43
+ (r'(\w+)\s*\(\s*([^)]*)\s*\)\s*=>', r'\1(\2) =>'), # Arrow function syntax
44
+ (r'(\w+)\s*\(\s*([^)]*)\s*\)\s*->', r'\1(\2) =>'), # Wrong arrow
45
+ (r'var\s+(\w+)\s*=\s*([^=]+)(?!=)', r'var \1 = \2'), # var declarations
46
+ (r'if\s*\(\s*([^)]+)\s*\)\s*{', r'if \1'), # if statements
47
+ (r'for\s+(\w+)\s*=\s*([^;]+);([^;]+);([^{]+){', r'for \1 = \2 to \3'), # for loops
48
+ ],
49
+ 'indentation_errors': [
50
+ (r'^(\s{2,})(\S)', r' \2'), # Fix indentation to 4 spaces
51
+ (r'^(\t+)(\S)', lambda m: ' ' * len(m.group(1)) + m.group(2)), # Convert tabs to spaces
52
+ ],
53
+ 'variable_errors': [
54
+ (r'(\w+)\s*:=\s*([^=]+)(?!=)', r'\1 := \2'), # Assignment operators
55
+ (r'(\w+)\s*==\s*([^=]+)', r'\1 == \2'), # Comparison operators
56
+ ]
57
+ }
58
+
59
+ def detect_version(self, code: str) -> str:
60
+ """تشخیص ورژن Pine Script"""
61
+ for version, pattern in self.version_patterns.items():
62
+ if re.search(pattern, code, re.IGNORECASE):
63
+ return version
64
+ return 'v5' # Default version
65
+
66
+ def fix_syntax_errors(self, code: str) -> str:
67
+ """تصحیح خطاهای نحوی"""
68
+ fixed_code = code
69
+
70
+ for pattern, replacement in self.error_patterns['syntax_errors']:
71
+ fixed_code = re.sub(pattern, replacement, fixed_code, flags=re.MULTILINE)
72
+
73
+ return fixed_code
74
+
75
+ def fix_indentation(self, code: str) -> str:
76
+ """تصحیح فاصله‌گذاری و تورفتگی"""
77
+ lines = code.split('\n')
78
+ fixed_lines = []
79
+
80
+ for line in lines:
81
+ # حذف فاصله‌های اضافی در انتهای خط
82
+ line = line.rstrip()
83
+
84
+ # تصحیح تورفتگی
85
+ if line.strip():
86
+ # محاسبه سطح تورفتگی
87
+ indent_level = 0
88
+ for char in line:
89
+ if char == ' ':
90
+ indent_level += 1
91
+ elif char == '\t':
92
+ indent_level += 4
93
+ else:
94
+ break
95
+
96
+ # تصحیح به مضارب 4
97
+ correct_indent = (indent_level // 4) * 4
98
+ fixed_line = ' ' * correct_indent + line.lstrip()
99
+ fixed_lines.append(fixed_line)
100
+ else:
101
+ fixed_lines.append('')
102
+
103
+ return '\n'.join(fixed_lines)
104
+
105
+ def fix_variable_declarations(self, code: str) -> str:
106
+ """تصحیح تعریف متغیرها"""
107
+ fixed_code = code
108
+
109
+ # تصحیح عملگرهای انتساب
110
+ fixed_code = re.sub(r'(\w+)\s*:=\s*([^=\n]+)', r'\1 := \2', fixed_code)
111
+ fixed_code = re.sub(r'(\w+)\s*=\s*([^=\n]+)', r'\1 = \2', fixed_code)
112
+
113
+ return fixed_code
114
+
115
+ def fix_function_calls(self, code: str, version: str) -> str:
116
+ """تصحیح فراخوانی توابع بر اساس ورژن"""
117
+ fixed_code = code
118
+
119
+ if version == 'v4':
120
+ # تبدیل از v4 به v5
121
+ for old_func, new_func in self.function_migrations['v4_to_v5'].items():
122
+ pattern = r'\b' + re.escape(old_func) + r'\b'
123
+ fixed_code = re.sub(pattern, new_func, fixed_code)
124
+
125
+ return fixed_code
126
+
127
+ def fix_parentheses_and_brackets(self, code: str) -> str:
128
+ """تصحیح پرانتزها و براکت‌ها"""
129
+ fixed_code = code
130
+
131
+ # تصحیح فاصله‌های اضافی در پرانتزها
132
+ fixed_code = re.sub(r'\(\s+', '(', fixed_code)
133
+ fixed_code = re.sub(r'\s+\)', ')', fixed_code)
134
+ fixed_code = re.sub(r'\[\s+', '[', fixed_code)
135
+ fixed_code = re.sub(r'\s+\]', ']', fixed_code)
136
+
137
+ return fixed_code
138
+
139
+ def fix_line_endings(self, code: str) -> str:
140
+ """تصحیح پایان خطوط"""
141
+ # تبدیل انواع مختلف line ending به Unix style
142
+ fixed_code = code.replace('\r\n', '\n').replace('\r', '\n')
143
+
144
+ # حذف خطوط خالی اضافی
145
+ fixed_code = re.sub(r'\n{3,}', '\n\n', fixed_code)
146
+
147
+ return fixed_code
148
+
149
+ def validate_pine_structure(self, code: str, version: str) -> List[PineError]:
150
+ """اعتبارسنجی ساختار کلی Pine Script"""
151
+ errors = []
152
+ lines = code.split('\n')
153
+
154
+ # بررسی وجود //@version
155
+ if not re.search(r'//@version\s*=\s*[456]', code):
156
+ errors.append(PineError(
157
+ line_number=1,
158
+ error_type="Version Missing",
159
+ description="Version declaration is missing",
160
+ suggestion="Add //@version=5 at the beginning",
161
+ severity="Critical"
162
+ ))
163
+
164
+ # بررسی وجود indicator یا study
165
+ has_main_declaration = False
166
+ for i, line in enumerate(lines):
167
+ if re.search(r'\b(indicator|study)\s*\(', line):
168
+ has_main_declaration = True
169
+ break
170
+
171
+ if not has_main_declaration:
172
+ errors.append(PineError(
173
+ line_number=1,
174
+ error_type="Main Declaration Missing",
175
+ description="Missing indicator() or study() declaration",
176
+ suggestion="Add indicator('Title') declaration",
177
+ severity="Critical"
178
+ ))
179
+
180
+ return errors
181
+
182
+ def fix_all_errors(self, code: str) -> Tuple[str, List[PineError], str]:
183
+ """تصحیح همه خطاها"""
184
+ if not code.strip():
185
+ return "", [], "❌ لطفاً کد Pine Script خود را وارد کنید"
186
+
187
+ progress = "🔍 شروع تحلیل و تصحیح کد Pine Script...\n"
188
+
189
+ # تشخیص ورژن
190
+ version = self.detect_version(code)
191
+ progress += f"📊 ورژن تشخیص داده شده: {version}\n"
192
+
193
+ # مراحل تصحیح
194
+ fixed_code = code
195
+
196
+ progress += "🔧 تصحیح خطاهای نحوی...\n"
197
+ fixed_code = self.fix_syntax_errors(fixed_code)
198
+
199
+ progress += "📐 تصحیح فاصله‌گذاری و تورفتگی...\n"
200
+ fixed_code = self.fix_indentation(fixed_code)
201
+
202
+ progress += "🔤 تصحیح متغیرها...\n"
203
+ fixed_code = self.fix_variable_declarations(fixed_code)
204
+
205
+ progress += "⚙️ تصحیح فراخوانی توابع...\n"
206
+ fixed_code = self.fix_function_calls(fixed_code, version)
207
+
208
+ progress += "🔗 تصحیح پرانتزها و براکت‌ها...\n"
209
+ fixed_code = self.fix_parentheses_and_brackets(fixed_code)
210
+
211
+ progress += "📝 تصحیح پایان خطوط...\n"
212
+ fixed_code = self.fix_line_endings(fixed_code)
213
+
214
+ # اعتبارسنجی نهایی
215
+ progress += "✅ اعتبارسنجی نهایی...\n"
216
+ validation_errors = self.validate_pine_structure(fixed_code, version)
217
+
218
+ progress += "🎯 تصحیح کامل شد!\n"
219
+
220
+ return fixed_code, validation_errors, progress
221
+
222
+ # ایجاد شیء فیکسر
223
+ fixer = PineProfessionalFixer()
224
+
225
+ def process_pine_code(input_code):
226
+ """پردازش کد Pine Script"""
227
+ if not input_code or not input_code.strip():
228
+ return "", "❌ لطفاً کد Pine Script خود را وارد کنید", ""
229
+
230
+ try:
231
+ fixed_code, errors, progress = fixer.fix_all_errors(input_code)
232
+
233
+ # ایجاد گزارش خطاها
234
+ error_report = ""
235
+ if errors:
236
+ error_report = "⚠️ خطاهای یافت شده:\n"
237
+ for i, error in enumerate(errors, 1):
238
+ error_report += f"{i}. خط {error.line_number}: {error.description}\n"
239
+ error_report += f" پیشنهاد: {error.suggestion}\n"
240
+ error_report += f" اهمیت: {error.severity}\n\n"
241
+ else:
242
+ error_report = "✅ هیچ خطای ساختاری یافت نشد!"
243
+
244
+ # ایجاد پیام موفقیت
245
+ success_message = """
246
+ 🎉 کد شما با موفقیت تصحیح شد!
247
+
248
+ 📋 راهنمای استفاده:
249
+ 1. کد تصحیح شده را از باکس زیر کپی کنید
250
+ 2. در Pine Editor در TradingView پیست کنید
251
+ 3. دکمه 'Add to Chart' را بزنید
252
+
253
+ ✨ کد شما آماده استفاده است!
254
+ """
255
+
256
+ return fixed_code, error_report, success_message
257
+
258
+ except Exception as e:
259
+ error_msg = f"❌ خط�� در تصحیح کد: {str(e)}\nلطفاً کد خود را بررسی کنید و دوباره تلاش کنید."
260
+ return "", error_msg, ""
261
+
262
+ # تعریف رابط کاربری Gradio
263
+ def create_interface():
264
+ with gr.Blocks(title="Pine Script Professional Fixer", theme=gr.themes.Soft()) as interface:
265
+ gr.Markdown("""
266
+ # 🚀 Pine Script Professional Error Fixer
267
+
268
+ ## ابزار حرفه‌ای تصحیح کدهای Pine Script
269
+
270
+ **ویژگی‌ها:**
271
+ - ✅ سازگار با ورژن‌های 4، 5 و 6
272
+ - 🔧 تصحیح خطاهای نحوی و ساختاری
273
+ - 📐 بهینه‌سازی فاصله‌گذاری
274
+ - ⚙️ تبدیل توابع قدیمی به جدید
275
+ - 🎯 آماده برای استفاده در TradingView
276
+ """)
277
+
278
+ with gr.Row():
279
+ with gr.Column(scale=1):
280
+ input_code = gr.Textbox(
281
+ label="📝 کد Pine Script خود را اینجا وارد کنید:",
282
+ placeholder="// مثال:\n//@version=5\nindicator('My Indicator')\nplot(close)",
283
+ lines=15,
284
+ max_lines=25
285
+ )
286
+
287
+ fix_button = gr.Button("🔧 تصحیح و بهینه‌سازی کد", variant="primary", size="lg")
288
+
289
+ with gr.Column(scale=1):
290
+ output_code = gr.Textbox(
291
+ label="✅ کد تصحیح شده:",
292
+ lines=15,
293
+ max_lines=25,
294
+ interactive=False
295
+ )
296
+
297
+ with gr.Row():
298
+ error_report = gr.Textbox(
299
+ label="📊 گزارش خطاها:",
300
+ lines=5,
301
+ interactive=False
302
+ )
303
+
304
+ success_message = gr.Textbox(
305
+ label="🎉 وضعیت:",
306
+ lines=5,
307
+ interactive=False
308
+ )
309
+
310
+ # مثال‌های نمونه
311
+ gr.Markdown("""
312
+ ## 📚 مثال‌های نمونه:
313
+
314
+ **مثال ساده:**
315
+ ```pine
316
+ //@version=5
317
+ indicator("My RSI", shorttitle="RSI")
318
+ rsi_value = ta.rsi(close, 14)
319
+ plot(rsi_value, color=color.blue)
320
+ hline(70, "Overbought", color=color.red)
321
+ hline(30, "Oversold", color=color.green)
322
+ ```
323
+
324
+ **نکات مهم:**
325
+ - حتماً ورژن Pine Script را مشخص کنید
326
+ - از indicator() یا study() استفاده کنید
327
+ - فاصله‌گذاری صحیح را رعایت کنید
328
+ """)
329
+
330
+ # اتصال دکمه به تابع
331
+ fix_button.click(
332
+ fn=process_pine_code,
333
+ inputs=[input_code],
334
+ outputs=[output_code, error_report, success_message]
335
+ )
336
+
337
+ return interface
338
+
339
+ # اجرای برنامه
340
+ if __name__ == "__main__":
341
+ interface = create_interface()
342
+ interface.launch(
343
+ server_name="0.0.0.0",
344
+ server_port=7860,
345
+ share=True,
346
+ show_error=True
347
+ )