Add Threading and Lock

This commit is contained in:
amirhossein 2026-01-07 08:03:24 -08:00
parent a8749e3239
commit 1bf944a0cf

38
main.py
View File

@ -3,9 +3,9 @@ import time
import json
import urllib.parse
import traceback
import subprocess # <--- اضافه شد
import sys # <--- اضافه شد
import threading # <--- اضافه شد
import subprocess
import sys
import threading
from flask import Flask, request, jsonify, send_file
from playwright.sync_api import sync_playwright
@ -15,6 +15,10 @@ CHROMIUM_PATH = "/usr/bin/chromium-browser"
if not os.path.exists(CHROMIUM_PATH):
CHROMIUM_PATH = "/usr/bin/chromium"
# --- قفل برای صف‌بندی درخواست‌های سنگین ---
# این قفل باعث می‌شود لایک/فالو/کامنت یکی‌یکی انجام شوند
TASK_LOCK = threading.Lock()
# مرورگر اصلی (فقط یک بار اجرا می‌شود)
playwright_instance = None
browser = None
@ -130,14 +134,21 @@ def inject_cookies(context, cookies_data):
# 🚀 مسیرها (Routes)
# =======================================================
@app.route('/')
def health_check():
"""این مسیر همیشه سریع جواب می‌دهد، حتی اگر ربات مشغول باشد"""
return "OK - Server is Alive", 200
@app.route('/auto_like', methods=['POST'])
def auto_like():
# استفاده از قفل: اگر کسی داخل باشد، بقیه منتظر می‌مانند (صف)
with TASK_LOCK:
context = None
page = None
try:
# 1. دریافت داده‌ها
data = request.json
proxy_str = data.get('proxy') # <--- گرفتن پروکسی از ورودی
proxy_str = data.get('proxy')
cookies = data.get('cookies')
post_url = data.get('post_url')
@ -154,7 +165,7 @@ def auto_like():
page.goto(post_url, wait_until="networkidle", timeout=60000)
except: pass
# 4. لاگیک لایک (همان کد هوشمند قبلی)
# 4. لاگیک لایک
status = "Failed"
target_btn = None
@ -192,12 +203,12 @@ def auto_like():
traceback.print_exc()
return jsonify({"error": str(e)}), 500
finally:
# بسیار مهم: بستن کانتکست برای آزاد کردن رم و آی‌پی
if context: context.close()
@app.route('/auto_comment', methods=['POST'])
def auto_comment():
with TASK_LOCK:
context = None
page = None
try:
@ -220,7 +231,7 @@ def auto_comment():
if page.locator("input[name='username']").count() > 0:
return jsonify({"status": "Failed", "reason": "Login Redirect"}), 401
# لاگیک کامنت (همان کد نهایی و وریفای شده)
# لاگیک کامنت
bubbles = [page.locator(s) for s in ['svg[aria-label="Comment"]', 'svg[aria-label="محاوره"]', 'svg[class*="_ab6-"]']]
bubbles.append(page.get_by_role("button").filter(has_text="Comment"))
@ -279,6 +290,7 @@ def auto_comment():
@app.route('/auto_follow', methods=['POST'])
def auto_follow():
with TASK_LOCK:
context = None
page = None
try:
@ -346,12 +358,13 @@ def auto_follow():
@app.route('/screenshot')
def serve_screenshot():
# اسکرین شات پشت قفل نمی‌ماند
if os.path.exists("current_view.png"):
return send_file("current_view.png", mimetype='image/png')
return "No image"
# =======================================================
# 🔄 تابع آپدیت خودکار (اضافه شده)
# 🔄 تابع آپدیت خودکار
# =======================================================
def auto_update_loop():
"""هر 60 ثانیه چک می‌کند اگر آپدیت آمده بود، برنامه را ریستارت می‌کند"""
@ -381,7 +394,6 @@ def auto_update_loop():
print("[UPDATER] Restarting application...\n")
# 5. Restart
# بستن مرورگر قبل از ریستارت (اختیاری ولی تمیزتر)
if playwright_instance:
playwright_instance.stop()
@ -389,7 +401,7 @@ def auto_update_loop():
except Exception as e:
print(f"[UPDATER ERROR]: {e}")
time.sleep(60) # اگر خطا داد، صبر کن و دوباره تلاش کن
time.sleep(60)
if __name__ == '__main__':
# --- شروع ترد آپدیت کننده در پس‌زمینه ---
@ -397,6 +409,8 @@ if __name__ == '__main__':
update_thread.start()
print(">>> Auto-updater started in background...")
# حتما threaded=False باشد تا تداخل در Playwright پیش نیاید
start_browser_engine() # استارت اولیه موتور
app.run(host='0.0.0.0', port=5000, threaded=False)
# تغییر مهم: threaded=True فعال شد
# درخواست‌های همزمان پذیرفته می‌شوند، اما توابع سنگین با TASK_LOCK صف‌بندی می‌شوند
app.run(host='0.0.0.0', port=5000, threaded=True)