diff --git a/chat.db b/chat.db index a21c884..aa8949b 100644 Binary files a/chat.db and b/chat.db differ diff --git a/config/__pycache__/__init__.cpython-314.pyc b/config/__pycache__/__init__.cpython-314.pyc index ccec705..31927a6 100644 Binary files a/config/__pycache__/__init__.cpython-314.pyc and b/config/__pycache__/__init__.cpython-314.pyc differ diff --git a/config/__pycache__/config.cpython-314.pyc b/config/__pycache__/config.cpython-314.pyc index d96fada..cad9f82 100644 Binary files a/config/__pycache__/config.cpython-314.pyc and b/config/__pycache__/config.cpython-314.pyc differ diff --git a/config/__pycache__/schema.cpython-314.pyc b/config/__pycache__/schema.cpython-314.pyc index 9a7ecd4..ab716c9 100644 Binary files a/config/__pycache__/schema.cpython-314.pyc and b/config/__pycache__/schema.cpython-314.pyc differ diff --git a/controllers/__pycache__/__init__.cpython-314.pyc b/controllers/__pycache__/__init__.cpython-314.pyc index 9ee4e27..a936839 100644 Binary files a/controllers/__pycache__/__init__.cpython-314.pyc and b/controllers/__pycache__/__init__.cpython-314.pyc differ diff --git a/controllers/__pycache__/chat.cpython-314.pyc b/controllers/__pycache__/chat.cpython-314.pyc index 5ad270f..e026b82 100644 Binary files a/controllers/__pycache__/chat.cpython-314.pyc and b/controllers/__pycache__/chat.cpython-314.pyc differ diff --git a/controllers/__pycache__/tenor.cpython-314.pyc b/controllers/__pycache__/tenor.cpython-314.pyc index e4c654d..25527c1 100644 Binary files a/controllers/__pycache__/tenor.cpython-314.pyc and b/controllers/__pycache__/tenor.cpython-314.pyc differ diff --git a/controllers/tenor.py b/controllers/tenor.py index cf4b3a3..a32b22b 100644 --- a/controllers/tenor.py +++ b/controllers/tenor.py @@ -1,22 +1,20 @@ -""" -controllers/tenor.py — GIPHY API proxy (requests-based). -""" - import json import logging import requests from bottle import route, request, response +import redis + +redis_server = redis.Redis(host="localhost", port=6379, db=0, decode_responses=True) logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) -_giphy_key: str = "GIPHY_API_KEY" +_giphy_key: str = "NR2vkCSTVKnwBx9IavODcsqeSt9Sreze" _session = requests.Session() _session.headers.update({'User-Agent': 'GIPHY-Proxy/1.0'}) GIPHY_BASE = "https://api.giphy.com/v1/gifs" - def init(tenor_cfg): global _giphy_key if hasattr(tenor_cfg, 'api_key') and tenor_cfg.api_key: @@ -25,23 +23,26 @@ def init(tenor_cfg): else: logger.warning("No GIPHY API key configured, using default placeholder") - def _build_params(query_params, extra=None): params = { "api_key": _giphy_key, - "limit": query_params.get("limit", "20"), + "limit": int(query_params.get("limit", "20")), "rating": query_params.get("rating", "g"), "lang": query_params.get("lang", "en"), } - if query_params.get("offset"): - params["offset"] = query_params["offset"] + # Обработка offset + try: + if query_params.get("offset"): + params["offset"] = int(query_params["offset"]) + else: + params["offset"] = 0 + except ValueError: + params["offset"] = 0 if extra: params.update(extra) return params - def _transform_giphy_result(gif): - """Convert GIPHY format -> unified {id, title, file: {hd, md, sm, xs}}.""" images = gif.get("images", {}) return { "id": gif.get("id"), @@ -56,10 +57,9 @@ def _transform_giphy_result(gif): "blur_preview": images.get("preview_gif", {}).get("url", ""), } - def _fetch_giphy(endpoint, params): url = f"{GIPHY_BASE}/{endpoint}" - logger.debug(f"GET {url}") + logger.debug(f"GET {url} with params {params}") try: resp = _session.get(url, params=params, timeout=15) resp.raise_for_status() @@ -68,13 +68,16 @@ def _fetch_giphy(endpoint, params): if isinstance(results, dict): results = [results] transformed = [_transform_giphy_result(g) for g in results] + per_page = int(params.get("limit", 20)) + current_offset = int(params.get("offset", 0)) + total_results = len(transformed) return { "success": True, "results": transformed, "pagination": { - "current_page": (int(params.get("offset", 0)) // max(int(params.get("limit", 20)), 1)) + 1, - "per_page": params.get("limit", 20), - "has_next": len(transformed) >= int(params.get("limit", 20)), + "current_page": (current_offset // per_page) + 1, + "per_page": per_page, + "has_next": total_results >= per_page, }, } except requests.exceptions.RequestException as e: @@ -88,20 +91,41 @@ def _fetch_giphy(endpoint, params): response.status = 502 return {"success": False, "error": error_msg} - def register_routes(app): @app.route("/api/gifs/trending", method="GET") def gifs_trending(): - logger.debug(f"Trending request: {dict(request.query)}") - params = _build_params(request.query) - return _fetch_giphy("trending", params) + try: + logger.debug(f"Trending request: {dict(request.query)}") + params = _build_params(request.query) + answ = _fetch_giphy("trending", params) + serialized_answ = json.dumps(answ) + redis_server.set('trending', serialized_answ, ex=360) + return json.loads(serialized_answ) + except Exception as e: + logger.exception("Error in trending route") + response.status = 500 + return {"success": False, "error": str(e)} @app.route("/api/gifs/search", method="GET") def gifs_search(): - logger.debug(f"Search request: {dict(request.query)}") - q = request.query.get("q", "") - if not q: - response.status = 400 - return {"success": False, "error": "Missing query"} - params = _build_params(request.query, extra={"q": q}) - return _fetch_giphy("search", params) + try: + logger.debug(f"Search request: {dict(request.query)}") + q = request.query.get("q", "") + if not q: + response.status = 400 + return {"success": False, "error": "Missing query parameter 'q'"} + params = _build_params(request.query, extra={"q": q}) + cache_key = f"search:{q.lower().strip()}" + # Проверка кеша + cached = redis_server.get(cache_key) + if cached: + return json.loads(cached) + # Если нет кеша, делаем запрос + answ = _fetch_giphy("search", params) + serialized_answ = json.dumps(answ) + redis_server.set(cache_key, serialized_answ, ex=360) + return answ + except Exception as e: + logger.exception("Error in search route") + response.status = 500 + return {"success": False, "error": str(e)} \ No newline at end of file diff --git a/models/__pycache__/__init__.cpython-314.pyc b/models/__pycache__/__init__.cpython-314.pyc index 2066285..0c07724 100644 Binary files a/models/__pycache__/__init__.cpython-314.pyc and b/models/__pycache__/__init__.cpython-314.pyc differ diff --git a/models/__pycache__/base.cpython-314.pyc b/models/__pycache__/base.cpython-314.pyc index 82b1e12..8afc256 100644 Binary files a/models/__pycache__/base.cpython-314.pyc and b/models/__pycache__/base.cpython-314.pyc differ diff --git a/models/__pycache__/db.cpython-314.pyc b/models/__pycache__/db.cpython-314.pyc index a3d9d84..956a500 100644 Binary files a/models/__pycache__/db.cpython-314.pyc and b/models/__pycache__/db.cpython-314.pyc differ