FuckingChat/controllers/tenor.py

131 lines
4.9 KiB
Python

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" #test 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 _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)}