Opera8 commited on
Commit
c5067f5
·
verified ·
1 Parent(s): 17a6967

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +125 -109
app.py CHANGED
@@ -263,12 +263,85 @@ async (image) => {
263
  }
264
  """
265
 
266
- # --- تنظیمات HTML/CSS و جاوااسکریپت سراسری (شامل مدیریت خطا) ---
267
- html_code = """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
268
  <style>
269
  @import url('https://fonts.googleapis.com/css2?family=Vazirmatn:wght@300;400;500;700&display=swap');
270
 
271
- :root, .dark, body, .gradio-container {
272
  --body-background-fill: #f5f7fa !important;
273
  --body-text-color: #1f2937 !important;
274
  --background-fill-primary: #ffffff !important;
@@ -279,16 +352,16 @@ html_code = """
279
  --block-title-text-color: #111827 !important;
280
  --input-background-fill: #ffffff !important;
281
  color-scheme: light !important;
282
- }
283
 
284
- body {
285
  font-family: 'Vazirmatn', sans-serif !important;
286
  background-color: #f5f7fa !important;
287
  margin: 0;
288
  padding: 10px;
289
- }
290
 
291
- #col-container {
292
  margin: 0 auto;
293
  max-width: 980px;
294
  direction: rtl;
@@ -298,9 +371,9 @@ body {
298
  border-radius: 24px;
299
  box-shadow: 0 10px 40px -10px rgba(0,0,0,0.08);
300
  border: 1px solid rgba(255,255,255,0.8);
301
- }
302
 
303
- #main-title h1 {
304
  font-size: 2.4em !important;
305
  text-align: center;
306
  color: #1a202c !important;
@@ -309,24 +382,24 @@ body {
309
  background: -webkit-linear-gradient(45deg, #2563eb, #1e40af);
310
  -webkit-background-clip: text;
311
  -webkit-text-fill-color: transparent;
312
- }
313
 
314
- #main-description {
315
  text-align: center;
316
  font-size: 1.15em;
317
  color: #4b5563 !important;
318
  margin-bottom: 40px;
319
  line-height: 1.6;
320
- }
321
 
322
- .gr-input-label, span.label-wrap, label span {
323
  font-weight: 700 !important;
324
  color: #374151 !important;
325
  font-size: 0.95em !important;
326
  margin-bottom: 8px !important;
327
- }
328
 
329
- textarea, input[type="text"] {
330
  border: 2px solid #e2e8f0 !important;
331
  border-radius: 12px !important;
332
  background-color: #ffffff !important;
@@ -334,20 +407,20 @@ textarea, input[type="text"] {
334
  padding: 12px !important;
335
  transition: all 0.3s ease;
336
  font-family: 'Vazirmatn', sans-serif !important;
337
- }
338
 
339
- textarea:focus, input[type="text"]:focus {
340
  border-color: #3b82f6 !important;
341
  box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.1) !important;
342
  outline: none;
343
- }
344
 
345
- .gr-dropdown {
346
  background: #ffffff !important;
347
  border-radius: 12px !important;
348
- }
349
 
350
- .primary-btn, button.primary {
351
  background: linear-gradient(135deg, #10b981 0%, #059669 100%) !important;
352
  border: none !important;
353
  color: white !important;
@@ -360,27 +433,27 @@ textarea:focus, input[type="text"]:focus {
360
  cursor: pointer !important;
361
  width: 100%;
362
  margin-top: 15px;
363
- }
364
 
365
- .primary-btn:hover, button.primary:hover {
366
  transform: translateY(-2px);
367
  box-shadow: 0 8px 25px rgba(16, 185, 129, 0.45) !important;
368
- }
369
 
370
- .primary-btn:active, button.primary:active {
371
  transform: translateY(1px);
372
- }
373
 
374
- #download-btn {
375
  background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%) !important;
376
  box-shadow: 0 4px 15px rgba(59, 130, 246, 0.3) !important;
377
- }
378
- #download-btn:hover {
379
  box-shadow: 0 8px 25px rgba(59, 130, 246, 0.45) !important;
380
- }
381
 
382
  .gradio-container .prose table,
383
- .gradio-container table {
384
  background-color: #ffffff !important;
385
  color: #111827 !important;
386
  border: 1px solid #e5e7eb !important;
@@ -388,111 +461,54 @@ textarea:focus, input[type="text"]:focus {
388
  overflow: hidden !important;
389
  width: 100% !important;
390
  margin-top: 20px !important;
391
- }
392
 
393
- .gradio-container thead th {
394
  background-color: #f3f4f6 !important;
395
  color: #374151 !important;
396
  font-weight: 700 !important;
397
  border-bottom: 2px solid #e5e7eb !important;
398
  padding: 12px !important;
399
  text-align: right !important;
400
- }
401
 
402
- .gradio-container tbody tr {
403
  background-color: #ffffff !important;
404
  border-bottom: 1px solid #f3f4f6 !important;
405
- }
406
 
407
- .gradio-container tbody tr:hover {
408
  background-color: #f9fafb !important;
409
- }
410
 
411
- .gradio-container tbody td {
412
  background-color: #ffffff !important;
413
  color: #374151 !important;
414
  padding: 10px !important;
415
- }
416
 
417
  .gradio-container tbody td span,
418
- .gradio-container tbody td p {
419
  color: #374151 !important;
420
- }
421
 
422
- footer { display: none !important; }
423
- .flagging { display: none !important; }
424
 
425
- /* استایل برای Toast های گرادیو */
426
- .toast-body {
427
  direction: rtl !important;
428
  text-align: right !important;
429
- }
430
 
431
- @media (prefers-color-scheme: dark) {
432
- body, .gradio-container, .prose, table, tr, td, th {
433
  background-color: #ffffff !important;
434
  color: #333333 !important;
435
- }
436
- }
437
  </style>
438
-
439
- <script>
440
- // 1. اجبار تم روشن
441
- function forceLightMode() {
442
- const body = document.querySelector('body');
443
- if (body) {
444
- body.classList.remove('dark');
445
- body.style.backgroundColor = '#f5f7fa';
446
- body.style.color = '#333333';
447
- }
448
- document.querySelectorAll('.dark').forEach(el => {
449
- el.classList.remove('dark');
450
- });
451
- }
452
- forceLightMode();
453
- setInterval(forceLightMode, 1000);
454
-
455
- // 2. شناسایی و تغییر پیام خطای GPU Quota
456
- const observer = new MutationObserver((mutations) => {
457
- mutations.forEach((mutation) => {
458
- if (mutation.addedNodes.length) {
459
- mutation.addedNodes.forEach((node) => {
460
- if (node.nodeType === 1 && (node.classList.contains('toast-body') || node.classList.contains('error'))) {
461
- const originalText = node.innerText || "";
462
-
463
- // اگر پیام خطا شامل کلمات کلیدی سهمیه GPU بود
464
- if (originalText.includes('exceeded your GPU quota') || originalText.includes('GPU quota')) {
465
- if (!node.dataset.translated) {
466
- node.innerHTML = `
467
- <div style="font-family: 'Vazirmatn', sans-serif; direction: rtl; text-align: right; padding: 5px;">
468
- <div style="display: flex; align-items: center; gap: 10px; margin-bottom: 8px;">
469
- <span style="font-size: 28px;">✈️</span>
470
- <h3 style="margin: 0; color: #c0392b; font-size: 16px;">ظرفیت سرور تکمیل شد</h3>
471
- </div>
472
- <p style="margin: 0; color: #333; font-size: 13px; line-height: 1.6;">
473
- متأسفانه سهمیه رایگان پردازش تمام شده است.
474
- </p>
475
- <div style="background-color: #e0f2f1; border: 1px solid #80cbc4; border-radius: 8px; padding: 8px; margin-top: 10px;">
476
- <p style="margin: 0; color: #00695c; font-weight: bold; font-size: 12px;">💡 راه حل سریع:</p>
477
- <p style="margin: 4px 0 0 0; font-size: 12px; color: #004d40;">
478
- لطفاً <b>حالت هواپیما (Airplane Mode)</b> گوشی خود را روشن و سپس خاموش کنید و دوباره تلاش کنید.
479
- </p>
480
- </div>
481
- </div>
482
- `;
483
- node.dataset.translated = 'true';
484
- node.style.border = '2px solid #e74c3c';
485
- node.style.backgroundColor = '#fff';
486
- }
487
- }
488
- }
489
- });
490
- }
491
- });
492
- });
493
-
494
- observer.observe(document.body, { childList: true, subtree: true });
495
- </script>
496
  """
497
 
498
  with gr.Blocks() as demo:
 
263
  }
264
  """
265
 
266
+ # --- جاوااسکریپت اصلی (شامل مدیریت هوشمند خطا) ---
267
+ # این اسکریپت با دقت هر تغییری در صفحه را رصد می‌کند و اگر خطای GPU را ببیند، آن را جایگزین می‌کند.
268
+ js_global_func = """
269
+ function() {
270
+ // 1. اجبار تم روشن
271
+ const forceLight = () => {
272
+ const body = document.querySelector('body');
273
+ if (body) {
274
+ body.classList.remove('dark');
275
+ body.style.backgroundColor = '#f5f7fa';
276
+ body.style.color = '#333333';
277
+ }
278
+ document.querySelectorAll('.dark').forEach(el => el.classList.remove('dark'));
279
+ };
280
+ forceLight();
281
+ setInterval(forceLight, 1000);
282
+
283
+ // 2. مدیریت خطای GPU (نسخه پیشرفته)
284
+ const observer = new MutationObserver((mutations) => {
285
+ mutations.forEach((mutation) => {
286
+ if (mutation.addedNodes.length) {
287
+ mutation.addedNodes.forEach((node) => {
288
+ // بررسی تمام نودهای اضافه شده (چه المنت چه متن)
289
+ if (node.nodeType === 1) { // اگر المنت باشد
290
+ const textContent = node.innerText || "";
291
+ if (textContent.includes("exceeded your GPU quota") || textContent.includes("GPU quota")) {
292
+
293
+ // پیدا کردن کانتینر اصلی ارور (معمولاً کلاس toast-body یا error دارد)
294
+ // اگر خودش کانتینر نبود، والدش را پیدا می‌کنیم یا خودش را تغییر می‌دهیم
295
+ let targetNode = node;
296
+ if (!targetNode.classList.contains('toast-body')) {
297
+ const parentToast = targetNode.closest('.toast-body');
298
+ if (parentToast) targetNode = parentToast;
299
+ }
300
+
301
+ if (!targetNode.dataset.fixed) {
302
+ targetNode.innerHTML = `
303
+ <div style="font-family: 'Vazirmatn', sans-serif; direction: rtl; text-align: right; padding: 10px; background: white; border-radius: 8px;">
304
+ <div style="display: flex; align-items: center; gap: 10px; margin-bottom: 8px;">
305
+ <span style="font-size: 30px;">✈️</span>
306
+ <h3 style="margin: 0; color: #c0392b; font-size: 18px; font-weight: bold;">ظرفیت تکمیل شد</h3>
307
+ </div>
308
+ <p style="margin: 5px 0; color: #333; font-size: 14px;">
309
+ سهمیه رایگان استفاده از سرور تمام شده است.
310
+ </p>
311
+ <div style="background-color: #e0f2f1; border: 1px solid #80cbc4; border-radius: 8px; padding: 10px; margin-top: 10px;">
312
+ <p style="margin: 0; color: #00695c; font-weight: bold; font-size: 13px;">💡 راه حل:</p>
313
+ <p style="margin: 5px 0 0 0; font-size: 13px; color: #004d40;">
314
+ لطفاً <b>حالت هواپیما (Airplane Mode)</b> گوشی خود را روشن و سپس خاموش کنید و صفحه را رفرش کنید.
315
+ </p>
316
+ </div>
317
+ </div>
318
+ `;
319
+ targetNode.dataset.fixed = "true";
320
+ // مخفی کردن استایل‌های پیش‌فرض زشت
321
+ targetNode.style.border = "none";
322
+ targetNode.style.boxShadow = "0 4px 15px rgba(0,0,0,0.1)";
323
+ // اگر والدی دارد که بوردر قرمز دارد، آن را هم پاکسازی کن
324
+ if(targetNode.parentElement) {
325
+ targetNode.parentElement.style.border = "none";
326
+ targetNode.parentElement.style.backgroundColor = "transparent";
327
+ }
328
+ }
329
+ }
330
+ }
331
+ });
332
+ }
333
+ });
334
+ });
335
+
336
+ observer.observe(document.body, { childList: true, subtree: true });
337
+ }
338
+ """
339
+
340
+ html_code = f"""
341
  <style>
342
  @import url('https://fonts.googleapis.com/css2?family=Vazirmatn:wght@300;400;500;700&display=swap');
343
 
344
+ :root, .dark, body, .gradio-container {{
345
  --body-background-fill: #f5f7fa !important;
346
  --body-text-color: #1f2937 !important;
347
  --background-fill-primary: #ffffff !important;
 
352
  --block-title-text-color: #111827 !important;
353
  --input-background-fill: #ffffff !important;
354
  color-scheme: light !important;
355
+ }}
356
 
357
+ body {{
358
  font-family: 'Vazirmatn', sans-serif !important;
359
  background-color: #f5f7fa !important;
360
  margin: 0;
361
  padding: 10px;
362
+ }}
363
 
364
+ #col-container {{
365
  margin: 0 auto;
366
  max-width: 980px;
367
  direction: rtl;
 
371
  border-radius: 24px;
372
  box-shadow: 0 10px 40px -10px rgba(0,0,0,0.08);
373
  border: 1px solid rgba(255,255,255,0.8);
374
+ }}
375
 
376
+ #main-title h1 {{
377
  font-size: 2.4em !important;
378
  text-align: center;
379
  color: #1a202c !important;
 
382
  background: -webkit-linear-gradient(45deg, #2563eb, #1e40af);
383
  -webkit-background-clip: text;
384
  -webkit-text-fill-color: transparent;
385
+ }}
386
 
387
+ #main-description {{
388
  text-align: center;
389
  font-size: 1.15em;
390
  color: #4b5563 !important;
391
  margin-bottom: 40px;
392
  line-height: 1.6;
393
+ }}
394
 
395
+ .gr-input-label, span.label-wrap, label span {{
396
  font-weight: 700 !important;
397
  color: #374151 !important;
398
  font-size: 0.95em !important;
399
  margin-bottom: 8px !important;
400
+ }}
401
 
402
+ textarea, input[type="text"] {{
403
  border: 2px solid #e2e8f0 !important;
404
  border-radius: 12px !important;
405
  background-color: #ffffff !important;
 
407
  padding: 12px !important;
408
  transition: all 0.3s ease;
409
  font-family: 'Vazirmatn', sans-serif !important;
410
+ }}
411
 
412
+ textarea:focus, input[type="text"]:focus {{
413
  border-color: #3b82f6 !important;
414
  box-shadow: 0 0 0 4px rgba(59, 130, 246, 0.1) !important;
415
  outline: none;
416
+ }}
417
 
418
+ .gr-dropdown {{
419
  background: #ffffff !important;
420
  border-radius: 12px !important;
421
+ }}
422
 
423
+ .primary-btn, button.primary {{
424
  background: linear-gradient(135deg, #10b981 0%, #059669 100%) !important;
425
  border: none !important;
426
  color: white !important;
 
433
  cursor: pointer !important;
434
  width: 100%;
435
  margin-top: 15px;
436
+ }}
437
 
438
+ .primary-btn:hover, button.primary:hover {{
439
  transform: translateY(-2px);
440
  box-shadow: 0 8px 25px rgba(16, 185, 129, 0.45) !important;
441
+ }}
442
 
443
+ .primary-btn:active, button.primary:active {{
444
  transform: translateY(1px);
445
+ }}
446
 
447
+ #download-btn {{
448
  background: linear-gradient(135deg, #3b82f6 0%, #2563eb 100%) !important;
449
  box-shadow: 0 4px 15px rgba(59, 130, 246, 0.3) !important;
450
+ }}
451
+ #download-btn:hover {{
452
  box-shadow: 0 8px 25px rgba(59, 130, 246, 0.45) !important;
453
+ }}
454
 
455
  .gradio-container .prose table,
456
+ .gradio-container table {{
457
  background-color: #ffffff !important;
458
  color: #111827 !important;
459
  border: 1px solid #e5e7eb !important;
 
461
  overflow: hidden !important;
462
  width: 100% !important;
463
  margin-top: 20px !important;
464
+ }}
465
 
466
+ .gradio-container thead th {{
467
  background-color: #f3f4f6 !important;
468
  color: #374151 !important;
469
  font-weight: 700 !important;
470
  border-bottom: 2px solid #e5e7eb !important;
471
  padding: 12px !important;
472
  text-align: right !important;
473
+ }}
474
 
475
+ .gradio-container tbody tr {{
476
  background-color: #ffffff !important;
477
  border-bottom: 1px solid #f3f4f6 !important;
478
+ }}
479
 
480
+ .gradio-container tbody tr:hover {{
481
  background-color: #f9fafb !important;
482
+ }}
483
 
484
+ .gradio-container tbody td {{
485
  background-color: #ffffff !important;
486
  color: #374151 !important;
487
  padding: 10px !important;
488
+ }}
489
 
490
  .gradio-container tbody td span,
491
+ .gradio-container tbody td p {{
492
  color: #374151 !important;
493
+ }}
494
 
495
+ footer {{ display: none !important; }}
496
+ .flagging {{ display: none !important; }}
497
 
498
+ /* استایل Toast */
499
+ .toast-body {{
500
  direction: rtl !important;
501
  text-align: right !important;
502
+ }}
503
 
504
+ @media (prefers-color-scheme: dark) {{
505
+ body, .gradio-container, .prose, table, tr, td, th {{
506
  background-color: #ffffff !important;
507
  color: #333333 !important;
508
+ }}
509
+ }}
510
  </style>
511
+ <script>{js_global_func}</script>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
512
  """
513
 
514
  with gr.Blocks() as demo: