Opera8 commited on
Commit
8fee1a9
·
verified ·
1 Parent(s): c939581

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +39 -18
app.py CHANGED
@@ -3,7 +3,8 @@ import json
3
  import random
4
  import asyncio
5
  import re
6
- import fcntl # برای قفل کردن فایل و هماهنگی بین Worker ها
 
7
  from datetime import datetime
8
  from concurrent.futures import ThreadPoolExecutor
9
  from fastapi import FastAPI, HTTPException, Request
@@ -69,24 +70,36 @@ def sync_generate_content(prompt):
69
 
70
  def check_and_increment_usage(ip: str, fingerprint: str):
71
  """
72
- این تابع با استفاده از قفل فایل، دسترسی همزمان چندین Worker را مدیریت می‌کند
73
- تا محدودیت دقیقاً اعمال شود.
74
  """
75
  today = datetime.now().strftime("%Y-%m-%d")
76
 
77
- # اطمینان از وجود فایل
78
  if not os.path.exists(USAGE_DB_FILE):
79
- with open(USAGE_DB_FILE, 'w') as f:
80
- json.dump({}, f)
 
 
 
81
 
82
  # باز کردن فایل با قابلیت خواندن و نوشتن
83
- with open(USAGE_DB_FILE, 'r+') as f:
 
 
 
 
 
 
 
 
84
  try:
85
- # اعمال قفل انحصاری قط یک Worker در لحظه می‌تواند فایل را بخواند/بنویسد)
86
  fcntl.flock(f, fcntl.LOCK_EX)
87
 
88
  try:
89
- data = json.load(f)
 
90
  except json.JSONDecodeError:
91
  data = {}
92
 
@@ -94,23 +107,24 @@ def check_and_increment_usage(ip: str, fingerprint: str):
94
  ip_key = f"ip:{ip}"
95
  fp_key = f"fp:{fingerprint}"
96
 
97
- # خواندن وضعیت فعلی IP
98
  ip_record = data.get(ip_key, {"date": today, "count": 0})
99
- if ip_record["date"] != today: # ریست کردن روز جدید
100
  ip_record = {"date": today, "count": 0}
101
 
102
- # خواندن وضعیت فعلی Fingerprint
103
  fp_record = data.get(fp_key, {"date": today, "count": 0})
104
- if fp_record["date"] != today: # ریست کردن روز جدید
105
  fp_record = {"date": today, "count": 0}
106
 
107
- # بررسی محدودیت (اگر هر کدام از سقف رد شده باشند، مسدود می‌شود)
 
108
  if ip_record["count"] >= MAX_FREE_DAILY_REQUESTS:
109
  return False
110
  if fingerprint and fp_record["count"] >= MAX_FREE_DAILY_REQUESTS:
111
  return False
112
 
113
- # افزایش شمارنده برای هر دو (برای جلوگیری از دور زدن)
114
  ip_record["count"] += 1
115
  data[ip_key] = ip_record
116
 
@@ -118,10 +132,11 @@ def check_and_increment_usage(ip: str, fingerprint: str):
118
  fp_record["count"] += 1
119
  data[fp_key] = fp_record
120
 
121
- # بازنویسی فایل
122
  f.seek(0)
123
  f.truncate()
124
  json.dump(data, f)
 
125
 
126
  return True
127
 
@@ -139,8 +154,14 @@ async def refine_text(request: IdeaRequest, req: Request):
139
  client_ip = req.client.host
140
  client_fp = request.fingerprint
141
 
142
- # فراخوانی تابع امن با قفل فایل
143
- allowed = check_and_increment_usage(client_ip, client_fp)
 
 
 
 
 
 
144
 
145
  if not allowed:
146
  # کد 429 به معنی Too Many Requests
 
3
  import random
4
  import asyncio
5
  import re
6
+ import fcntl # کتابخانه قفل کردن فایل برای دقت ۱۰۰ درصد
7
+ import time
8
  from datetime import datetime
9
  from concurrent.futures import ThreadPoolExecutor
10
  from fastapi import FastAPI, HTTPException, Request
 
70
 
71
  def check_and_increment_usage(ip: str, fingerprint: str):
72
  """
73
+ این تابع با استفاده از مکانیزم قفل (Lock) فایل، دسترسی همزمان را مدیریت می‌کند.
74
+ این روش دقیق‌ترین راه برای اعمال محدودیت در محیط‌های چند-رشته‌ای است.
75
  """
76
  today = datetime.now().strftime("%Y-%m-%d")
77
 
78
+ # تلاش برای ایجاد فایل اگر وجود ندارد (با مدیریت خطا برای جلوگیری از تداخل)
79
  if not os.path.exists(USAGE_DB_FILE):
80
+ try:
81
+ with open(USAGE_DB_FILE, 'w') as f:
82
+ json.dump({}, f)
83
+ except OSError:
84
+ pass # ممکن است یک پردازش دیگر همزمان فایل را ساخته باشد
85
 
86
  # باز کردن فایل با قابلیت خواندن و نوشتن
87
+ try:
88
+ f = open(USAGE_DB_FILE, 'r+')
89
+ except FileNotFoundError:
90
+ # اگر فایل در لحظه باز کردن حذف شده باشد دوباره می‌سازیم
91
+ f = open(USAGE_DB_FILE, 'w+')
92
+ json.dump({}, f)
93
+ f.seek(0)
94
+
95
+ with f:
96
  try:
97
+ # اعمال قفل انحصاری: بقیه درخواست‌ها منتظر می‌مانند تا این یکی تمام شود
98
  fcntl.flock(f, fcntl.LOCK_EX)
99
 
100
  try:
101
+ content = f.read()
102
+ data = json.loads(content) if content else {}
103
  except json.JSONDecodeError:
104
  data = {}
105
 
 
107
  ip_key = f"ip:{ip}"
108
  fp_key = f"fp:{fingerprint}"
109
 
110
+ # --- منطق بررسی IP ---
111
  ip_record = data.get(ip_key, {"date": today, "count": 0})
112
+ if ip_record["date"] != today: # اگر روز جدید است، ریست کن
113
  ip_record = {"date": today, "count": 0}
114
 
115
+ # --- منطق بررسی اثر انگشت ---
116
  fp_record = data.get(fp_key, {"date": today, "count": 0})
117
+ if fp_record["date"] != today: # اگر روز جدید است، ریست کن
118
  fp_record = {"date": today, "count": 0}
119
 
120
+ # --- شرط مسدودسازی ---
121
+ # اگر هر کدام از سقف رد شده باشند، اجازه نده
122
  if ip_record["count"] >= MAX_FREE_DAILY_REQUESTS:
123
  return False
124
  if fingerprint and fp_record["count"] >= MAX_FREE_DAILY_REQUESTS:
125
  return False
126
 
127
+ # --- ثبت استفاده ---
128
  ip_record["count"] += 1
129
  data[ip_key] = ip_record
130
 
 
132
  fp_record["count"] += 1
133
  data[fp_key] = fp_record
134
 
135
+ # بازنویسی فایل با داده‌های جدید
136
  f.seek(0)
137
  f.truncate()
138
  json.dump(data, f)
139
+ f.flush() # اطمینان از نوشته شدن روی دیسک
140
 
141
  return True
142
 
 
154
  client_ip = req.client.host
155
  client_fp = request.fingerprint
156
 
157
+ # فراخوانی تابع ��ا قفل فایل
158
+ try:
159
+ allowed = check_and_increment_usage(client_ip, client_fp)
160
+ except Exception as e:
161
+ print(f"Error checking limit: {e}")
162
+ # در صورت بروز خطای سیستمی، برای اطمینان کاربر را بلاک می‌کنیم یا باز می‌گذاریم؟
163
+ # اینجا برای امنیت بیشتر، اجازه نمی‌دهیم.
164
+ return JSONResponse(content={"error": "System Error checking limits"}, status_code=500)
165
 
166
  if not allowed:
167
  # کد 429 به معنی Too Many Requests