Предзагрузка всех картинок при старте + многопоточный веб-сервер
- _prewarm_media грузит ВСЕ *.jpg из help_img при старте (кроме bg.jpg), чтобы смена картинок услуг не подгружалась лениво в момент сообщения. - Веб-форма: ThreadingHTTPServer — медленный запрос не блокирует остальные; приём заявки сериализован _submit_lock (без гонок в SQLite/Excel). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -1194,15 +1194,15 @@ class VKBotApplication:
|
|||||||
try:
|
try:
|
||||||
peer = config.OPERATOR_PEER_ID
|
peer = config.OPERATOR_PEER_ID
|
||||||
base = os.path.join(os.path.dirname(__file__), "help_img")
|
base = os.path.join(os.path.dirname(__file__), "help_img")
|
||||||
files = ["Logo.jpg", "cs2.jpg", "dota2.jpg", "wot.jpg",
|
# Грузим ВСЕ картинки из папки (кроме фона веб-формы), чтобы ничего
|
||||||
"career_player.jpg", "career_worker.jpg"]
|
# не подгружалось лениво в момент сообщения.
|
||||||
# Загруженные админом картинки услуг (service_<id>.jpg) — приоритетные для карусели
|
count = 0
|
||||||
files += [os.path.basename(p) for p in glob.glob(os.path.join(base, "service_*.jpg"))]
|
for path in sorted(glob.glob(os.path.join(base, "*.jpg"))):
|
||||||
for fn in files:
|
if os.path.basename(path).lower() == "bg.jpg":
|
||||||
path = os.path.join(base, fn)
|
continue
|
||||||
if os.path.exists(path):
|
if self._upload_photo(peer, path):
|
||||||
self._upload_photo(peer, path)
|
count += 1
|
||||||
logger.info("Медиа предзагружены в VK — карусель и логотип будут открываться быстро.")
|
logger.info(f"Медиа предзагружены в VK ({count} картинок) — открываются мгновенно.")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Не удалось предзагрузить медиа: {e}")
|
logger.error(f"Не удалось предзагрузить медиа: {e}")
|
||||||
|
|
||||||
|
|||||||
+10
-2
@@ -6,7 +6,7 @@ import random
|
|||||||
import string
|
import string
|
||||||
import threading
|
import threading
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
from http.server import HTTPServer, SimpleHTTPRequestHandler
|
from http.server import HTTPServer, ThreadingHTTPServer, SimpleHTTPRequestHandler
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
@@ -72,6 +72,8 @@ RATE_LIMIT_MAX = 5
|
|||||||
RATE_LIMIT_WINDOW = 600 # секунд (10 минут)
|
RATE_LIMIT_WINDOW = 600 # секунд (10 минут)
|
||||||
_rate_lock = threading.Lock()
|
_rate_lock = threading.Lock()
|
||||||
_rate_hits = defaultdict(list)
|
_rate_hits = defaultdict(list)
|
||||||
|
# Сериализует приём заявок (генерация ID + запись), чтобы при многопоточности не было гонок
|
||||||
|
_submit_lock = threading.Lock()
|
||||||
|
|
||||||
|
|
||||||
def is_rate_limited(ip: str) -> bool:
|
def is_rate_limited(ip: str) -> bool:
|
||||||
@@ -253,6 +255,11 @@ def gen_promo():
|
|||||||
|
|
||||||
def add_registration(data):
|
def add_registration(data):
|
||||||
"""Сохраняет заявку: SQLite (источник правды) → Excel (нестрого) → уведомления. Возвращает промокод."""
|
"""Сохраняет заявку: SQLite (источник правды) → Excel (нестрого) → уведомления. Возвращает промокод."""
|
||||||
|
with _submit_lock:
|
||||||
|
return _add_registration_locked(data)
|
||||||
|
|
||||||
|
|
||||||
|
def _add_registration_locked(data):
|
||||||
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
current_time = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
|
||||||
next_id = generate_next_id()
|
next_id = generate_next_id()
|
||||||
# Промокод пока выключен флагом config.PROMO_ENABLED
|
# Промокод пока выключен флагом config.PROMO_ENABLED
|
||||||
@@ -433,7 +440,8 @@ class FormHandler(SimpleHTTPRequestHandler):
|
|||||||
def run_server(port=8000):
|
def run_server(port=8000):
|
||||||
init_excel() # Pre-create Excel on startup
|
init_excel() # Pre-create Excel on startup
|
||||||
server_address = ('', port)
|
server_address = ('', port)
|
||||||
httpd = HTTPServer(server_address, FormHandler)
|
# Многопоточный сервер: один медленный/зависший запрос не блокирует остальные.
|
||||||
|
httpd = ThreadingHTTPServer(server_address, FormHandler)
|
||||||
print(f"\n=======================================================")
|
print(f"\n=======================================================")
|
||||||
print(f"Сервер ИКП запущен на http://localhost:{port}/")
|
print(f"Сервер ИКП запущен на http://localhost:{port}/")
|
||||||
print(f"Вы можете открыть форму по адресу: http://localhost:{port}/index.html")
|
print(f"Вы можете открыть форму по адресу: http://localhost:{port}/index.html")
|
||||||
|
|||||||
Reference in New Issue
Block a user