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 = "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: _giphy_key = tenor_cfg.api_key logger.info(f"GIPHY API key initialized: {_giphy_key[:10]}...") else: logger.warning("No GIPHY API key configured, using default placeholder") def _build_params(query_params, extra=None): params = { "api_key": _giphy_key, "limit": int(query_params.get("limit", "20")), "rating": query_params.get("rating", "g"), "lang": query_params.get("lang", "en"), } # Обработка 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): images = gif.get("images", {}) return { "id": gif.get("id"), "title": gif.get("title", ""), "slug": gif.get("slug", gif.get("id", "")), "file": { "hd": {"gif": {"url": images.get("original", {}).get("url", "")}}, "md": {"gif": {"url": images.get("downsized_large", {}).get("url", "") or images.get("downsized", {}).get("url", "")}}, "sm": {"gif": {"url": images.get("fixed_width_downsampled", {}).get("url", "") or images.get("fixed_width", {}).get("url", "")}}, "xs": {"gif": {"url": images.get("fixed_width_small", {}).get("url", "")}}, }, "blur_preview": images.get("preview_gif", {}).get("url", ""), } def _fetch_giphy(endpoint, params): url = f"{GIPHY_BASE}/{endpoint}" logger.debug(f"GET {url} with params {params}") try: resp = _session.get(url, params=params, timeout=15) resp.raise_for_status() data = resp.json() results = data.get("data", []) 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": (current_offset // per_page) + 1, "per_page": per_page, "has_next": total_results >= per_page, }, } except requests.exceptions.RequestException as e: error_msg = f"GIPHY error: {str(e)}" logger.error(error_msg) response.status = 502 return {"success": False, "error": error_msg} except Exception as e: error_msg = f"Unexpected error: {str(e)}" logger.error(error_msg) response.status = 502 return {"success": False, "error": error_msg} def register_routes(app): @app.route("/api/gifs/trending", method="GET") def gifs_trending(): 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(): 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)}