diff --git a/controllers/tenor.py b/controllers/tenor.py index 3e1bc1e..cf4b3a3 100644 --- a/controllers/tenor.py +++ b/controllers/tenor.py @@ -1,120 +1,87 @@ """ -controllers/tenor.py — Klipy GIF API proxy (requests-based) with Tenor fallback. +controllers/tenor.py — GIPHY API proxy (requests-based). """ import json import logging -import random import requests from bottle import route, request, response logging.basicConfig(level=logging.DEBUG) logger = logging.getLogger(__name__) -_klipy_key: str = "aw3wqJXDc2LXcyL0zRg0v7LvXQCh69hciOxRMk23V1mWYxfql4NhKglzArCEHwBs" -_tenor_keys = [ - "AIzaSyBi0xcrRsFkWV6TvG5udT71OVqSh_vuCQc", - "AIzaSyDe5BdI5kQ6YLsTE_Dd8E5tLgJ4j7hYsWs", - "AIzaSyCb2Cw5i9nFZzG5b7GdDf7e5f6h7j8k9l0", -] -_timeout = 25 +_giphy_key: str = "GIPHY_API_KEY" +_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 _klipy_key + global _giphy_key if hasattr(tenor_cfg, 'api_key') and tenor_cfg.api_key: - _klipy_key = tenor_cfg.api_key - logger.info(f"Klipy API key initialized: {_klipy_key[:10]}...") + _giphy_key = tenor_cfg.api_key + logger.info(f"GIPHY API key initialized: {_giphy_key[:10]}...") else: - logger.warning("No Klipy API key provided, using default key") + logger.warning("No GIPHY API key configured, using default placeholder") def _build_params(query_params, extra=None): params = { - "page": query_params.get("page", "1"), - "per_page": query_params.get("limit", "24"), - "content_filter": query_params.get("content_filter", "off"), - "locale": query_params.get("locale", "us"), + "api_key": _giphy_key, + "limit": query_params.get("limit", "20"), + "rating": query_params.get("rating", "g"), + "lang": query_params.get("lang", "en"), } - if query_params.get("customer_id"): - params["customer_id"] = query_params["customer_id"] - if query_params.get("format_filter"): - params["format_filter"] = query_params["format_filter"] + if query_params.get("offset"): + params["offset"] = query_params["offset"] if extra: params.update(extra) return params -def _fetch_tenor_fallback(endpoint, params): - """Fallback to original Tenor API if Klipy fails.""" - tenor_key = random.choice(_tenor_keys) - base = "https://tenor.googleapis.com/v2" - path = "featured" if "trending" in endpoint else "search" - p = { - "key": tenor_key, - "limit": params.get("per_page", 24), +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"), + "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", ""), } - if "q" in params: - p["q"] = params["q"] - url = f"{base}/{path}" - logger.info(f"Tenor fallback: GET {url}") + + +def _fetch_giphy(endpoint, params): + url = f"{GIPHY_BASE}/{endpoint}" + logger.debug(f"GET {url}") try: - resp = requests.get(url, params=p, timeout=15) + resp = _session.get(url, params=params, timeout=15) resp.raise_for_status() data = resp.json() - results = data.get("results", []) - # Transform Tenor format -> Klipy-like format - transformed = [] - for gif in results: - mf = gif.get("media_formats", {}) - tf = { - "id": gif.get("id"), - "title": gif.get("title", ""), - "slug": gif.get("h1_title", ""), - "file": { - "hd": {"gif": {"url": mf.get("gif", {}).get("url", "")}}, - "md": {"gif": {"url": mf.get("mediumgif", {}).get("url", "") or mf.get("gif", {}).get("url", "")}}, - "sm": {"gif": {"url": mf.get("tinygif", {}).get("url", "")}}, - "xs": {"gif": {"url": mf.get("nanogif", {}).get("url", "")}}, - }, - "blur_preview": mf.get("tinygif", {}).get("url", ""), - } - transformed.append(tf) - logger.info(f"Tenor fallback returned {len(transformed)} results") + results = data.get("data", []) + if isinstance(results, dict): + results = [results] + transformed = [_transform_giphy_result(g) for g in results] return { "success": True, "results": transformed, - "fallback": "tenor", + "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)), + }, } - except Exception as e: - error_msg = f"Tenor fallback also failed: {str(e)}" + 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} - - -def _fetch_klipy(endpoint, params): - url = f"https://api.klipy.com/api/v1/{_klipy_key}/{endpoint}" - logger.debug(f"GET {url} params={params}") - try: - resp = requests.get(url, params=params, timeout=_timeout) - resp.raise_for_status() - data = resp.json() - return { - "success": data.get("result", False), - "results": data.get("data", {}).get("data", []), - "pagination": { - "current_page": data.get("data", {}).get("current_page", 1), - "per_page": data.get("data", {}).get("per_page", 24), - "has_next": data.get("data", {}).get("has_next", False), - }, - } - except requests.exceptions.Timeout: - logger.warning("Klipy timeout, falling back to Tenor...") - return _fetch_tenor_fallback(endpoint, params) - except requests.exceptions.RequestException as e: - logger.warning(f"Klipy error ({str(e)[:80]}), falling back to Tenor...") - return _fetch_tenor_fallback(endpoint, params) except Exception as e: error_msg = f"Unexpected error: {str(e)}" logger.error(error_msg) @@ -127,7 +94,7 @@ def register_routes(app): def gifs_trending(): logger.debug(f"Trending request: {dict(request.query)}") params = _build_params(request.query) - return _fetch_klipy("gifs/trending", params) + return _fetch_giphy("trending", params) @app.route("/api/gifs/search", method="GET") def gifs_search(): @@ -137,4 +104,4 @@ def register_routes(app): response.status = 400 return {"success": False, "error": "Missing query"} params = _build_params(request.query, extra={"q": q}) - return _fetch_klipy("gifs/search", params) + return _fetch_giphy("search", params)