Opera8 commited on
Commit
1a7d9b4
·
verified ·
1 Parent(s): 8f59b64

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +47 -78
app.py CHANGED
@@ -31,13 +31,10 @@ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
31
 
32
  # --- بارگذاری مدل تشخیص محتوای نامناسب (NSFW) ---
33
  print("Loading Safety Checker...")
34
- try:
35
- safety_classifier = pipeline("image-classification", model="Falconsai/nsfw_image_detection", device=-1)
36
- except:
37
- safety_classifier = None # Fallback if model fails to load
38
 
39
  def is_image_nsfw(image):
40
- if image is None or safety_classifier is None: return False
41
  try:
42
  results = safety_classifier(image)
43
  for result in results:
@@ -268,7 +265,7 @@ async (image) => {
268
  }
269
  """
270
 
271
- # --- جاوااسکریپت سراسری (استراتژی حذف کامل برای رفع مشکل رفرش) ---
272
  js_global_content = """
273
  <script>
274
  document.addEventListener('DOMContentLoaded', () => {
@@ -285,45 +282,31 @@ document.addEventListener('DOMContentLoaded', () => {
285
  forceLight();
286
  setInterval(forceLight, 1000);
287
 
288
- // 2. HELPER: Completely destroy the error element
289
- window.destroyErrorToast = function(btn) {
290
- // Try to find the container
291
- const toast = btn.closest('.toast-wrap') || btn.closest('.toast-body') || btn.closest('.error');
292
-
293
- // Find the main run button and click it to retry
 
294
  const runBtn = document.getElementById('run-btn');
295
  if(runBtn) runBtn.click();
296
-
297
- // Remove the error UI immediately
298
- if (toast) {
299
- toast.remove();
300
- }
301
-
302
- // Aggressive cleanup: remove ANY other error toasts visible
303
- document.querySelectorAll('.toast-body, .toast-wrap, .error').forEach(el => {
304
- if(el.innerText.includes("قدم تا ساخت") || el.innerText.includes("quota")) {
305
- el.remove();
306
- }
307
- });
308
  };
309
 
310
- // Just remove toast (for Back button)
311
- window.closeErrorToast = function(btn) {
312
- const toast = btn.closest('.toast-wrap') || btn.closest('.toast-body') || btn.closest('.error');
313
- if(toast) toast.remove();
314
  };
315
 
316
- // 3. LOGIC: Replace content logic
317
- const replaceErrorContent = (node) => {
318
- if (node.querySelector('.ip-reset-guide-container')) return;
 
319
 
320
- const text = node.innerText || "";
321
-
322
- // Check triggers
323
- if (text.toLowerCase().includes('quota') || text.toLowerCase().includes('exceeded') || (text.includes('Error') && node.classList.contains('error'))) {
324
-
325
- const prettyHtml = `
326
- <div class="ip-reset-guide-container">
327
  <div class="guide-header">
328
  <svg class="guide-header-icon" viewbox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
329
  <defs><lineargradient id="grad1" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color: #667eea; stop-opacity: 1;"></stop><stop offset="100%" style="stop-color: #764ba2; stop-opacity: 1;"></stop></lineargradient></defs>
@@ -365,41 +348,47 @@ document.addEventListener('DOMContentLoaded', () => {
365
  </div>
366
 
367
  <div class="guide-actions">
368
- <button class="action-button back-button" onclick="window.closeErrorToast(this)">
369
  <svg class="action-button-icon" viewbox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M19 12H5M12 19l-7-7 7-7" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></svg>
370
  <span>بازگشت</span>
371
  </button>
372
- <button class="action-button retry-button" onclick="window.destroyErrorToast(this)">
373
  <svg class="action-button-icon" viewbox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M23 4v6h-6M1 20v-6h6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path><path d="M20.49 9A9 9 0 0 0 5.64 5.64L1 10m22 4l-4.64 4.36A9 9 0 0 1 3.51 15" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></svg>
374
  <span>تلاش مجدد</span>
375
  </button>
376
  </div>
377
  </div>
378
- `;
379
-
380
- // Inject the HTML
381
- node.innerHTML = prettyHtml;
382
-
383
- node.style.padding = '0';
384
- node.style.border = 'none';
385
- node.style.backgroundColor = 'transparent';
386
- node.style.boxShadow = 'none';
387
- node.classList.remove('error');
388
- }
389
  };
390
 
391
- // 4. AGGRESSIVE SCANNER
392
  setInterval(() => {
393
- const potentialErrors = document.querySelectorAll('.toast-body, .error, .toast-wrap, .eta-bar');
 
394
 
395
  potentialErrors.forEach(el => {
396
- if (el.innerText && (el.innerText.includes('quota') || el.innerText.includes('exceeded') || (el.innerText.includes('Error') && el.classList.contains('error')))) {
397
- if (!el.querySelector('.ip-reset-guide-container')) {
398
- replaceErrorContent(el);
399
- }
 
 
 
 
 
 
 
 
 
 
 
 
400
  }
401
  });
402
- }, 150);
403
  });
404
  </script>
405
  """
@@ -447,26 +436,6 @@ css_code = """
447
  to { opacity: 1; transform: translateY(0); }
448
  }
449
 
450
- .ip-reset-guide-container {
451
- text-align: right;
452
- background: var(--guide-bg);
453
- backdrop-filter: blur(10px);
454
- padding: 25px;
455
- border-radius: var(--radius-lg-guide);
456
- box-shadow: var(--shadow-xl);
457
- border: 1px solid var(--guide-border);
458
- animation: slideInUp 0.6s cubic-bezier(0.4, 0, 0.2, 1) both;
459
- width: 100%;
460
- max-width: 450px;
461
- position: relative;
462
- overflow: hidden;
463
- box-sizing: border-box;
464
- font-family: 'Vazirmatn', sans-serif !important;
465
- direction: rtl;
466
- }
467
- .ip-reset-guide-container::before {
468
- content: ''; position: absolute; top: 0; left: 0; right: 0; height: 5px; background: var(--primary-gradient-guide);
469
- }
470
  .guide-header { display: flex; align-items: center; margin-bottom: 20px; }
471
  .guide-header-icon { width: 50px; height: 50px; margin-left: 15px; animation: float 3s ease-in-out infinite; flex-shrink: 0; }
472
  .guide-header h2 { font-size: 1.3rem; color: var(--guide-text-title); font-weight: 700; margin: 0; }
 
31
 
32
  # --- بارگذاری مدل تشخیص محتوای نامناسب (NSFW) ---
33
  print("Loading Safety Checker...")
34
+ safety_classifier = pipeline("image-classification", model="Falconsai/nsfw_image_detection", device=-1)
 
 
 
35
 
36
  def is_image_nsfw(image):
37
+ if image is None: return False
38
  try:
39
  results = safety_classifier(image)
40
  for result in results:
 
265
  }
266
  """
267
 
268
+ # --- جاوااسکریپت سراسری (استراتژی پنجره شناور مستقل) ---
269
  js_global_content = """
270
  <script>
271
  document.addEventListener('DOMContentLoaded', () => {
 
282
  forceLight();
283
  setInterval(forceLight, 1000);
284
 
285
+ // 2. RETRY FUNCTION
286
+ window.retryGeneration = function() {
287
+ // Close modal
288
+ const modal = document.getElementById('custom-quota-modal');
289
+ if (modal) modal.remove();
290
+
291
+ // Click Run button
292
  const runBtn = document.getElementById('run-btn');
293
  if(runBtn) runBtn.click();
 
 
 
 
 
 
 
 
 
 
 
 
294
  };
295
 
296
+ // Close function
297
+ window.closeErrorModal = function() {
298
+ const modal = document.getElementById('custom-quota-modal');
299
+ if (modal) modal.remove();
300
  };
301
 
302
+ // 3. SHOW MODAL FUNCTION
303
+ const showQuotaModal = () => {
304
+ // Prevent duplicate modals
305
+ if (document.getElementById('custom-quota-modal')) return;
306
 
307
+ const modalHtml = `
308
+ <div id="custom-quota-modal" style="position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.6); backdrop-filter: blur(5px); z-index: 99999; display: flex; align-items: center; justify-content: center; font-family: 'Vazirmatn', sans-serif;">
309
+ <div class="ip-reset-guide-container" style="max-width: 450px; width: 90%; background: white; border-radius: 20px; padding: 25px; box-shadow: 0 10px 40px rgba(0,0,0,0.3); animation: slideInUp 0.4s ease;">
 
 
 
 
310
  <div class="guide-header">
311
  <svg class="guide-header-icon" viewbox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
312
  <defs><lineargradient id="grad1" x1="0%" y1="0%" x2="100%" y2="100%"><stop offset="0%" style="stop-color: #667eea; stop-opacity: 1;"></stop><stop offset="100%" style="stop-color: #764ba2; stop-opacity: 1;"></stop></lineargradient></defs>
 
348
  </div>
349
 
350
  <div class="guide-actions">
351
+ <button class="action-button back-button" onclick="window.closeErrorModal()">
352
  <svg class="action-button-icon" viewbox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M19 12H5M12 19l-7-7 7-7" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></svg>
353
  <span>بازگشت</span>
354
  </button>
355
+ <button class="action-button retry-button" onclick="window.retryGeneration()">
356
  <svg class="action-button-icon" viewbox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M23 4v6h-6M1 20v-6h6" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path><path d="M20.49 9A9 9 0 0 0 5.64 5.64L1 10m22 4l-4.64 4.36A9 9 0 0 1 3.51 15" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"></path></svg>
357
  <span>تلاش مجدد</span>
358
  </button>
359
  </div>
360
  </div>
361
+ </div>
362
+ `;
363
+
364
+ document.body.insertAdjacentHTML('beforeend', modalHtml);
 
 
 
 
 
 
 
365
  };
366
 
367
+ // 4. SCANNER
368
  setInterval(() => {
369
+ // Find ALL possible error containers, including small toasts and status bars
370
+ const potentialErrors = document.querySelectorAll('.toast-body, .error, .toast-wrap, .eta-bar, div[class*="error"]');
371
 
372
  potentialErrors.forEach(el => {
373
+ const text = el.innerText || "";
374
+ // Trigger words
375
+ if (text.toLowerCase().includes('quota') || text.toLowerCase().includes('exceeded')) {
376
+
377
+ // Show our custom modal if not already open
378
+ showQuotaModal();
379
+
380
+ // IMMEDIATELY HIDE/REMOVE the ugly Gradio error
381
+ // We use display:none or remove() to ensure it's gone
382
+ el.style.display = 'none';
383
+ el.style.opacity = '0';
384
+ el.innerText = ''; // Clear text so it doesn't trigger again immediately for this specific node
385
+
386
+ // Also try to find parent wrapper and hide it
387
+ const parentWrap = el.closest('.toast-wrap');
388
+ if(parentWrap) parentWrap.style.display = 'none';
389
  }
390
  });
391
+ }, 100); // Check every 100ms
392
  });
393
  </script>
394
  """
 
436
  to { opacity: 1; transform: translateY(0); }
437
  }
438
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
439
  .guide-header { display: flex; align-items: center; margin-bottom: 20px; }
440
  .guide-header-icon { width: 50px; height: 50px; margin-left: 15px; animation: float 3s ease-in-out infinite; flex-shrink: 0; }
441
  .guide-header h2 { font-size: 1.3rem; color: var(--guide-text-title); font-weight: 700; margin: 0; }