Предзагрузка всех картинок при старте + многопоточный веб-сервер

- _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:
Kenik
2026-06-24 21:58:22 +03:00
parent 7ebcb851e7
commit 667ca4d4f0
2 changed files with 19 additions and 11 deletions
+9 -9
View File
@@ -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
View File
@@ -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")