Opera8 commited on
Commit
32f65a0
·
verified ·
1 Parent(s): 8d7ac9a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +59 -18
app.py CHANGED
@@ -56,7 +56,7 @@ def save_usage_data(data):
56
  # بارگذاری اولیه داده‌ها
57
  usage_data_cache = load_usage_data()
58
 
59
- # --- بارگذاری مدل تشخیص محتوای نامناسب (NSFW) ---
60
  print("Loading Safety Checker...")
61
  safety_classifier = pipeline("image-classification", model="Falconsai/nsfw_image_detection", device=-1)
62
 
@@ -133,18 +133,56 @@ ASPECT_RATIOS_MAP = {
133
  "شخصی‌سازی (Custom)": "Custom"
134
  }
135
 
 
136
  BANNED_WORDS = [
137
- "nude", "naked", "sex", "porn", "undressed", "nsfw", "erotic", "xxx",
138
- "breast", "nipple", "genital", "vagina", "penis", "ass", "butt", "sexual",
139
- "lingerie", "bikini", "swimwear", "underwear", "fetish", "topless",
140
- "exhibitionism", "hentai", "ecchi", "18+"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
141
  ]
142
 
143
  def check_text_safety(text):
 
 
 
 
 
144
  text_lower = text.lower()
 
 
 
 
 
 
 
 
 
145
  for word in BANNED_WORDS:
146
- if f" {word} " in f" {text_lower} ":
 
 
147
  return False
 
148
  return True
149
 
150
  def translate_prompt(text):
@@ -282,20 +320,22 @@ def infer(
282
  None, seed, get_quota_exceeded_html(),
283
  gr.update(visible=False), gr.update(visible=True)
284
  )
285
-
286
- # اگر اعتبار داشت، حالا کم می‌کنیم
287
- consume_quota(fingerprint)
288
-
289
- # --- ادامه منطق اصلی ساخت تصویر ---
290
  if input_image is None:
291
  return None, seed, get_error_html("لطفاً ابتدا یک تصویر بارگذاری کنید."), gr.update(visible=True), gr.update(visible=False)
292
 
293
  if is_image_nsfw(input_image):
294
  return None, seed, get_error_html("تصویر ورودی دارای محتوای نامناسب است و پردازش نمی‌شود."), gr.update(visible=True), gr.update(visible=False)
295
 
 
296
  english_prompt = translate_prompt(prompt)
297
  if not check_text_safety(english_prompt):
298
- return None, seed, get_error_html("متن درخواست شامل کلمات غیرمجاز یا غیراخلاقی است."), gr.update(visible=True), gr.update(visible=False)
 
 
 
 
299
 
300
  adapter_internal_name = LORA_MAPPING.get(lora_adapter_persian)
301
  if adapter_internal_name:
@@ -306,7 +346,8 @@ def infer(
306
 
307
  generator = torch.Generator(device=device).manual_seed(seed)
308
 
309
- safety_negative = "nsfw, nude, naked, porn, sexual, xxx, breast, nipple, genital, vagina, penis, ass, lingerie, bikini, swimwear, underwear, fetish, topless, gore, violence, blood"
 
310
  base_negative = "worst quality, low quality, bad anatomy, bad hands, text, error, missing fingers, extra digit, fewer digits, cropped, jpeg artifacts, signature, watermark, username, blurry"
311
  final_negative_prompt = f"{safety_negative}, {base_negative}"
312
 
@@ -334,6 +375,7 @@ def infer(
334
  true_cfg_scale=guidance_scale,
335
  ).images[0]
336
 
 
337
  if is_image_nsfw(result):
338
  return None, seed, get_error_html("تصویر تولید شده حاوی محتوای نامناسب بود و حذف شد."), gr.update(visible=True), gr.update(visible=False)
339
 
@@ -354,10 +396,9 @@ def infer(
354
  except Exception as e:
355
  error_str = str(e)
356
  # -------------------------------------------------------------
357
- # مدیریت خطای GPU QUOTA برای نمایش Modal سفارشی (بخش درخواستی)
358
  # -------------------------------------------------------------
359
  if "quota" in error_str.lower() or "exceeded" in error_str.lower():
360
- # خطا را به بالا پرتاب می‌کنیم تا اسکنر جاوااسکریپت آن را بگیرد
361
  raise e
362
 
363
  return None, seed, get_error_html(f"خطا در پردازش: {error_str}"), gr.update(visible=True), gr.update(visible=False)
@@ -395,7 +436,7 @@ js_upgrade_func = """
395
  }
396
  """
397
 
398
- # --- جاوااسکریپت سراسری (ترکیب شده: اعتبار سنجی + هندلینگ خطای GPU) ---
399
  js_global_content = """
400
  <script>
401
  document.addEventListener('DOMContentLoaded', () => {
@@ -631,7 +672,7 @@ document.addEventListener('DOMContentLoaded', () => {
631
  </script>
632
  """
633
 
634
- # --- CSS Updated (ترکیب استایل‌های مودال، بج و گرادیو) ---
635
  css_code = """
636
  <style>
637
  @import url('https://fonts.googleapis.com/css2?family=Vazirmatn:wght@300;400;500;700&display=swap');
@@ -650,7 +691,7 @@ css_code = """
650
  font-family: 'Vazirmatn', sans-serif !important;
651
  }
652
 
653
- /* --- IP Reset Guide CSS (مودال سفارشی) --- */
654
  :root {
655
  --guide-bg: rgba(255, 255, 255, 0.98);
656
  --guide-border: rgba(102, 126, 234, 0.2);
 
56
  # بارگذاری اولیه داده‌ها
57
  usage_data_cache = load_usage_data()
58
 
59
+ # --- بارگذاری مدل تشخیص محتوای نامناسب (Image Safety) ---
60
  print("Loading Safety Checker...")
61
  safety_classifier = pipeline("image-classification", model="Falconsai/nsfw_image_detection", device=-1)
62
 
 
133
  "شخصی‌سازی (Custom)": "Custom"
134
  }
135
 
136
+ # --- لیست کلمات ممنوعه پیشرفته (Strict Mode) ---
137
  BANNED_WORDS = [
138
+ # General NSFW
139
+ "nsfw", "nude", "naked", "sex", "porn", "erotic", "xxx", "18+", "adult",
140
+ "explicit", "uncensored", "sexual", "lewd", "sensual", "lust", "horny",
141
+
142
+ # Anatomy (Explicit)
143
+ "breast", "breasts", "nipple", "nipples", "vagina", "pussy", "cunt",
144
+ "penis", "dick", "cock", "genital", "genitals", "groin", "pubic",
145
+ "ass", "butt", "buttocks", "anus", "anal", "rectum",
146
+
147
+ # Acts / Concepts
148
+ "intercourse", "masturbation", "orgasm", "blowjob", "bj", "cum", "sperm",
149
+ "ejaculation", "penetration", "fucking", "sucking", "licking",
150
+
151
+ # Clothing / Lingerie
152
+ "lingerie", "bikini", "swimwear", "underwear", "panties", "bra", "thong",
153
+ "topless", "bottomless", "undressed", "unclothed", "skimpy", "transparent",
154
+ "see-through",
155
+
156
+ # Fetish / Styles
157
+ "fetish", "bdsm", "bondage", "latex", "hentai", "ecchi", "ahegao",
158
+ "exhibitionism", "voyeur", "harem",
159
+
160
+ # Violence / Gore (Optional but recommended for strict safety)
161
+ "gore", "bloody", "blood", "kill", "murder", "dead", "torture", "abuse"
162
  ]
163
 
164
  def check_text_safety(text):
165
+ """
166
+ بررسی وجود کلمات ممنوعه در متن انگلیسی.
167
+ از متد whole word matching ساده استفاده می‌کند تا کلماتی مثل 'assassin' اشتباهاً حذف نشوند.
168
+ """
169
+ if not text: return True
170
  text_lower = text.lower()
171
+
172
+ # نرمال‌سازی متن برای جستجوی دقیق‌تر
173
+ # اضافه کردن فاصله به اول و آخر متن برای تشخیص کلمات اول و آخر جمله
174
+ padded_text = f" {text_lower} "
175
+
176
+ # حذف علائم نگارشی برای جلوگیری از دور زدن فیلتر (مثلاً sex.)
177
+ for char in [".", ",", "!", "?", "-", "_", "(", ")", "[", "]", "{", "}"]:
178
+ padded_text = padded_text.replace(char, " ")
179
+
180
  for word in BANNED_WORDS:
181
+ # جستجو به صورت کلمه مستقل
182
+ if f" {word} " in padded_text:
183
+ print(f"Safety Triggered: Found banned word '{word}'")
184
  return False
185
+
186
  return True
187
 
188
  def translate_prompt(text):
 
320
  None, seed, get_quota_exceeded_html(),
321
  gr.update(visible=False), gr.update(visible=True)
322
  )
323
+
324
+ # --- بررسی‌های اولیه (تصویر و متن) قبل از کسر اعتبار ---
 
 
 
325
  if input_image is None:
326
  return None, seed, get_error_html("لطفاً ابتدا یک تصویر بارگذاری کنید."), gr.update(visible=True), gr.update(visible=False)
327
 
328
  if is_image_nsfw(input_image):
329
  return None, seed, get_error_html("تصویر ورودی دارای محتوای نامناسب است و پردازش نمی‌شود."), gr.update(visible=True), gr.update(visible=False)
330
 
331
+ # ترجمه و بررسی متن (مهم: قبل از کسر اعتبار)
332
  english_prompt = translate_prompt(prompt)
333
  if not check_text_safety(english_prompt):
334
+ return None, seed, get_error_html("متن درخواست شامل کلمات غیرمجاز، جنسی یا خشونت‌آمیز است. لطفاً متن را اصلاح کنید."), gr.update(visible=True), gr.update(visible=False)
335
+
336
+ # اگر همه چیز امن بود، حالا اعتبار را کسر می‌کنیم
337
+ if subscription_status != 'paid':
338
+ consume_quota(fingerprint)
339
 
340
  adapter_internal_name = LORA_MAPPING.get(lora_adapter_persian)
341
  if adapter_internal_name:
 
346
 
347
  generator = torch.Generator(device=device).manual_seed(seed)
348
 
349
+ # اضافه کردن کلمات منفی ایمنی به صورت پیش‌فرض به پرامپت منفی
350
+ safety_negative = "nsfw, nude, naked, porn, sexual, xxx, breast, nipple, genital, vagina, penis, ass, lingerie, bikini, swimwear, underwear, fetish, topless, gore, violence, blood, explicit"
351
  base_negative = "worst quality, low quality, bad anatomy, bad hands, text, error, missing fingers, extra digit, fewer digits, cropped, jpeg artifacts, signature, watermark, username, blurry"
352
  final_negative_prompt = f"{safety_negative}, {base_negative}"
353
 
 
375
  true_cfg_scale=guidance_scale,
376
  ).images[0]
377
 
378
+ # بررسی نهایی تصویر تولید شده
379
  if is_image_nsfw(result):
380
  return None, seed, get_error_html("تصویر تولید شده حاوی محتوای نامناسب بود و حذف شد."), gr.update(visible=True), gr.update(visible=False)
381
 
 
396
  except Exception as e:
397
  error_str = str(e)
398
  # -------------------------------------------------------------
399
+ # مدیریت خطای GPU QUOTA
400
  # -------------------------------------------------------------
401
  if "quota" in error_str.lower() or "exceeded" in error_str.lower():
 
402
  raise e
403
 
404
  return None, seed, get_error_html(f"خطا در پردازش: {error_str}"), gr.update(visible=True), gr.update(visible=False)
 
436
  }
437
  """
438
 
439
+ # --- جاوااسکریپت سراسری ---
440
  js_global_content = """
441
  <script>
442
  document.addEventListener('DOMContentLoaded', () => {
 
672
  </script>
673
  """
674
 
675
+ # --- CSS Updated ---
676
  css_code = """
677
  <style>
678
  @import url('https://fonts.googleapis.com/css2?family=Vazirmatn:wght@300;400;500;700&display=swap');
 
691
  font-family: 'Vazirmatn', sans-serif !important;
692
  }
693
 
694
+ /* --- IP Reset Guide CSS (مودال) --- */
695
  :root {
696
  --guide-bg: rgba(255, 255, 255, 0.98);
697
  --guide-border: rgba(102, 126, 234, 0.2);