From 75380bb5eda7bb6a1d8507afc04a9f044cac8936 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 22 Jul 2026 04:41:28 +0300 Subject: [PATCH] fixed gif api --- Anime/README.md | 3 - Games/README.md | 3 - Politics/README.md | 3 - chat.db | Bin 0 -> 8192 bytes config/__pycache__/__init__.cpython-314.pyc | Bin 0 -> 137 bytes config/__pycache__/config.cpython-314.pyc | Bin 0 -> 3429 bytes config/__pycache__/schema.cpython-314.pyc | Bin 0 -> 3664 bytes .../__pycache__/__init__.cpython-314.pyc | Bin 0 -> 142 bytes controllers/__pycache__/chat.cpython-314.pyc | Bin 0 -> 7753 bytes controllers/__pycache__/tenor.cpython-314.pyc | Bin 0 -> 9980 bytes controllers/tenor.py | 168 ++++++++++++++++-- models/__pycache__/__init__.cpython-314.pyc | Bin 0 -> 137 bytes models/__pycache__/base.cpython-314.pyc | Bin 0 -> 2469 bytes models/__pycache__/db.cpython-314.pyc | Bin 0 -> 6116 bytes 14 files changed, 154 insertions(+), 23 deletions(-) delete mode 100644 Anime/README.md delete mode 100644 Games/README.md delete mode 100644 Politics/README.md create mode 100644 chat.db create mode 100644 config/__pycache__/__init__.cpython-314.pyc create mode 100644 config/__pycache__/config.cpython-314.pyc create mode 100644 config/__pycache__/schema.cpython-314.pyc create mode 100644 controllers/__pycache__/__init__.cpython-314.pyc create mode 100644 controllers/__pycache__/chat.cpython-314.pyc create mode 100644 controllers/__pycache__/tenor.cpython-314.pyc create mode 100644 models/__pycache__/__init__.cpython-314.pyc create mode 100644 models/__pycache__/base.cpython-314.pyc create mode 100644 models/__pycache__/db.cpython-314.pyc diff --git a/Anime/README.md b/Anime/README.md deleted file mode 100644 index f0abc44..0000000 --- a/Anime/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Anime Channel - -This directory is dedicated to discussions and content about anime. \ No newline at end of file diff --git a/Games/README.md b/Games/README.md deleted file mode 100644 index 6143c99..0000000 --- a/Games/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Games Channel - -This directory is dedicated to discussions and content about games. \ No newline at end of file diff --git a/Politics/README.md b/Politics/README.md deleted file mode 100644 index 2ea54bd..0000000 --- a/Politics/README.md +++ /dev/null @@ -1,3 +0,0 @@ -# Politics Channel - -This directory is dedicated to discussions and content about politics. \ No newline at end of file diff --git a/chat.db b/chat.db new file mode 100644 index 0000000000000000000000000000000000000000..a21c8846995b3ac1447dec228f10de89de7d59f7 GIT binary patch literal 8192 zcmeI#K~KUk6ae6kXpAHVZywa7M@X0fMi34rc4WX{Oqj!g7gI(D(`^bA2{9h<;>D|H ze~C9&=S|J!3_G_YpK>grT_gzT6k~)?Wch{ZGla0;SdJHI z@&8{$(9!GrPPj^lB~jQQKmY_l00ck)1V8`;KmY_l00cl_?FHsdVQcU3P7&-6`t8${w_u8*AgSST$_@UwOp}A6eRwEQk#@b8Hz%$1JzL(Gc>u9s7fR; zyR_pVcIcp}(ytgy+-ZwMq@9-jMuMNJv^k)Y`|E3+Y2`ypg6A;QsK{~pC6g-7>%s8iW zz_}?tF6crCUBC)I<%m0VXWXT`;%?m?_voIuSNDd{TU=s~>DK0npe>t{A}Ee=uG!N& z6lXtDT>WUdQ}-)wkUdNeC|;07CU+`0jAUPF3Fde+h5USOA<|@H#VgX+=5x!c^!1-Ul1>zhQD#5pJ*O9lnw8R;bmrXaGg2-u>5HnQrB_rbnvSXv9zAPnAX&$W5a(=&6G$^ztZaa&Z*>*N?JYf4K-h| zI??!vH&W5pXHHF>ez!BTnATI7=GQH0g?t9X^5~y7x;;GncZPwK(JZ>az4AwdvY;D6 zXYnFda1utEEdtxK!F@~T7*3+h-HP-v8kJMxeWT_|~P>j)v%8)9=J@U8@I1YJrih z!1MLMSS>JC54=l)REK>=EqYX@Gddryjfi;tpt%7A6BYkwB z2MA3$KMp*mWG%;7^D|(~YBVdT$DO~xuI|n^^L&daNyk~UbT}!Px`fk|Y@YDgvMJeF zXXfQ3&O#r7#^%qACA5u2 zA(ORPfMyAeA~RPOAUlUpjtil^D8zo#-yP%kq8yf;GX|HvXt=f3ePTE@c9R$mo!%iE zNbX`q%?iih3YsC%LN}c1J2_2`))(JAaQa@){XH9d?uRx)(D^L(p!f4LAi&sabnVo(*tg#MmAJPtDAxw( zHV?gdPrLu##(VWhtQLtu_e!TC3(Fy227=G~17h@p6DA=Fb7Q3t2wO1Ph;o88==7HDXYl0iWx_qoAAA{~^`h(M- zUj+e1!F+04^q0>(>4Rld=KiPAeEyrif70dn!X-}jdwv;G${eAPLS#y4N&FOC9)NKR zEKZ3m$3Y&o#C zu4dauTfaQmvgfO9N2PYQ5uwN>>5a$QELH^bk=X`>`J@F039DGmxd`n;zYAaB6vxXp z@H!Rv?E+%w&lR=;7Om2Du_|nq9jiDALK*lneV*m=S-8w+WKXlWX}OXYC}BlvS(6c} zqlXMtSz0MVsj{@7^-4x5IS7Q+>H)J>4M9u8Q}i$luk5DGarm6&*nfS< z>tD@Qqm|HFX#GUP?W=e`^i+pG-S^Nv42A6tRzj7~hoM$g90{Hra{PTrJo#&n+-0}` zkO~>VBl=-vKM=!3(QG+)vH2`=YMDiKCC$LD31kepXpS+wGF)o@QjP%D@e8U>=sTgg zfefGMlF2?w=ndI?9=VUN6tbmdb%MMMI!Jq@{T9ggJjVDj$75l~i?Ht>$n#G$@Go@! qAv*ua-&t9@xm3yD%&)(-d1zwG|7uzML7>myA3EVN@?^hRTmJ`hBVYIc literal 0 HcmV?d00001 diff --git a/config/__pycache__/schema.cpython-314.pyc b/config/__pycache__/schema.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9a7ecd4e7bc2ff16a7ed76bfd8308f7810930e09 GIT binary patch literal 3664 zcmb_f&u`pB6drrMw)bZ?X|kK`rpYF0t1c}`Q46h<5*3<;w53ILQ7ws=cgNV4P@SrmuJ zIMEU%qDhy<;J25WWLN^)-W4gYj)@Fw1qO(lyaf zH4J9dZNu~Y?d4n&;m%Ycf#muJ) zMm*J6_EWZ7H|#anW7gkULVO7wbpfKl2S30wNx-w`09+F~g>o{)LJ0Wz$);9MjJP(d#XPt@+ue zK`o=PtYh$pR?DR^tL>T8FGM3-z{C@mHV%7`AWY9Q(NB1c`U%TnK%5MuHVx+Ibe+@J zu4E!=tC$V^dk%a`2DeEt+bswOgaR4gB)0O-C&Gb%WYtU@8 zhg*d1nRRM19V*LNHT914*Z1d`aWhgWQFM@r7 z$LvcUMCfOXM$>Y1<~}kVKMfn4soPf50tatDv7Cnc#2;uHU%~1;&wy3hP_k@|o`A_} zA}zvKz-~}N0lj5>Q>8m=U4?;~^6mp17RH6BFf#cK>0DG8SS97CF!~2Kq*7EEfhR1C z@(2{hE*3^0ixHUmUM)vY!8aX67(=KcoJY8T@HWB}!ZgA~gmHukgh_#*`tx_4(TP$^M2dz;MZgC$YizJJ`?k(A?;OUZV<)~!2OeHQ;epG-= zQ<{wY`q>92{nDg?NS`Vfr}&@s6D)ncxAbP=g>NW5lv1?ui_qp9KfG27WF_&vTHsl;hENi3JPYdkY{COFD;=2zOBw%U~pyYytGKi@RuC z1?iqDco$=P58(>JYiPfOV-R>O2m$SdGB92k1Q;lFZtml&Bbsq^Z<|`VOAKdV9uEsE5Q7TWo7t#j`%Z00b5Y6W z%IFC%KH1WSG_#8rpSWfUJvD<`55m215HlY6LEtyB#U(S3E!500oBDNhBk-{Ce-*B+ zSLM-PzS%6#c0PPDcKZ3!=Ga_k;YFqTd}OmS+nIj>-mf>yGf?&zaU?&S=3Xu1E4tor z@tTx5_*cR7C?1j&L-%F2-hvw@MRoQ{JCBFrITqvsuT8#sEx6Ln(mP(ApPebO3}7Gz;935Qeu2Ksp)DYSL literal 0 HcmV?d00001 diff --git a/controllers/__pycache__/__init__.cpython-314.pyc b/controllers/__pycache__/__init__.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..9ee4e273a2d95dbe307cca2812e22abd9968b6f4 GIT binary patch literal 142 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 Z%~w`Dqf3KfG#ctC_0q=CRF`a@{{jD{YP$dc literal 0 HcmV?d00001 diff --git a/controllers/tenor.py b/controllers/tenor.py index 834c6b1..68dca3c 100644 --- a/controllers/tenor.py +++ b/controllers/tenor.py @@ -5,48 +5,188 @@ controllers/tenor.py — Tenor GIF API proxy. import json import urllib.request import urllib.parse +import logging from bottle import route, request, response +# Настройка логирования +logging.basicConfig(level=logging.DEBUG) +logger = logging.getLogger(__name__) -_api_key: str = "" +_api_key: str = "aw3wqJXDc2LXcyL0zRg0v7LvXQCh69hciOxRMk23V1mWYxfql4NhKglzArCEHwBs" def init(tenor_cfg): global _api_key - _api_key = tenor_cfg.api_key + if hasattr(tenor_cfg, 'api_key') and tenor_cfg.api_key: + _api_key = tenor_cfg.api_key + logger.info(f"Tenor API key initialized: {_api_key[:10]}...") + else: + logger.warning("No Tenor API key provided, using default key") def register_routes(app): @app.route("/api/gifs/trending", method="GET") def gifs_trending(): + logger.debug(f"Trending request received with params: {dict(request.query)}") + if not _api_key: response.status = 400 return {"success": False, "error": "Tenor API key not configured"} + try: - limit = request.query.get("limit", "20") - url = f"https://tenor.googleapis.com/v2/trending?key={_api_key}&limit={limit}&media_filter=tinygif" - with urllib.request.urlopen(url) as resp: + # Get query parameters with defaults + page = request.query.get("page", "1") + per_page = request.query.get("limit", "24") + customer_id = request.query.get("customer_id", "") + locale = request.query.get("locale", "us") # Default to US + content_filter = request.query.get("content_filter", "off") + format_filter = request.query.get("format_filter", "") + + # Build URL according to KLIPY API spec + base_url = f"https://api.klipy.com/api/v1/{_api_key}/gifs/trending" + params = { + "page": page, + "per_page": per_page, + "content_filter": content_filter, + "locale": locale # Always include locale + } + + # Add optional parameters if provided + if customer_id: + params["customer_id"] = customer_id + if format_filter: + params["format_filter"] = format_filter + + url = f"{base_url}?{urllib.parse.urlencode(params)}" + logger.debug(f"Requesting URL: {url}") + + # Create request with headers + req = urllib.request.Request(url, headers={ + 'Accept': 'application/json', + 'User-Agent': 'KLIPY-Proxy/1.0' + }) + + with urllib.request.urlopen(req, timeout=10) as resp: data = json.loads(resp.read()) - return {"success": True, "results": data.get("results", [])} - except Exception as e: + logger.debug(f"KLIPY response: {json.dumps(data)[:200]}...") + + # Transform KLIPY response to match expected format + response_data = { + "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) + } + } + + logger.debug(f"Returning {len(response_data['results'])} results") + return response_data + + except urllib.error.HTTPError as e: + error_msg = f"HTTP Error {e.code}: {e.reason}" + logger.error(error_msg) + try: + error_body = e.read().decode('utf-8') + logger.error(f"Error body: {error_body}") + except: + pass response.status = 502 - return {"success": False, "error": str(e)} + return {"success": False, "error": error_msg} + except urllib.error.URLError as e: + error_msg = f"Connection 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} @app.route("/api/gifs/search", method="GET") def gifs_search(): + logger.debug(f"Search request received with params: {dict(request.query)}") + if not _api_key: response.status = 400 return {"success": False, "error": "Tenor API key not configured"} + try: q = request.query.get("q", "") if not q: response.status = 400 return {"success": False, "error": "Missing query"} - limit = request.query.get("limit", "20") - url = f"https://tenor.googleapis.com/v2/search?key={_api_key}&q={urllib.parse.quote(q)}&limit={limit}&media_filter=tinygif" - with urllib.request.urlopen(url) as resp: + + # Get query parameters with defaults + page = request.query.get("page", "1") + per_page = request.query.get("limit", "24") + customer_id = request.query.get("customer_id", "") + locale = request.query.get("locale", "us") # Default to US + content_filter = request.query.get("content_filter", "off") + format_filter = request.query.get("format_filter", "") + + # Build URL according to KLIPY API spec + base_url = f"https://api.klipy.com/api/v1/{_api_key}/gifs/search" + params = { + "q": q, + "page": page, + "per_page": per_page, + "content_filter": content_filter, + "locale": locale # Always include locale + } + + # Add optional parameters if provided + if customer_id: + params["customer_id"] = customer_id + if format_filter: + params["format_filter"] = format_filter + + url = f"{base_url}?{urllib.parse.urlencode(params)}" + logger.debug(f"Requesting URL: {url}") + + # Create request with headers + req = urllib.request.Request(url, headers={ + 'Accept': 'application/json', + 'User-Agent': 'KLIPY-Proxy/1.0' + }) + + with urllib.request.urlopen(req, timeout=10) as resp: data = json.loads(resp.read()) - return {"success": True, "results": data.get("results", [])} - except Exception as e: + logger.debug(f"KLIPY response: {json.dumps(data)[:200]}...") + + # Transform KLIPY response to match expected format + response_data = { + "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) + } + } + + logger.debug(f"Returning {len(response_data['results'])} results") + return response_data + + except urllib.error.HTTPError as e: + error_msg = f"HTTP Error {e.code}: {e.reason}" + logger.error(error_msg) + try: + error_body = e.read().decode('utf-8') + logger.error(f"Error body: {error_body}") + except: + pass response.status = 502 - return {"success": False, "error": str(e)} + return {"success": False, "error": error_msg} + except urllib.error.URLError as e: + error_msg = f"Connection 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} \ No newline at end of file diff --git a/models/__pycache__/__init__.cpython-314.pyc b/models/__pycache__/__init__.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..2066285f2b4ba4d9e79a0c2859903ed30f247f1f GIT binary patch literal 137 zcmdPqj$PJXGdrdY z6_RPILJvqq;*eviN)@P5#W8%SJ2c7XZPqQ=RFQ@VnnfBn#U**dCj}xTMIt7B#Mj5<{FIcGiJVl3 zlJpaQGC%@-s1x-gP3S_JI3pht8uyW)EA@d?nh9=7Lz>)$NLW(_P~2Y`1>Hc=&YG5! zm@^!6sJx*5Rehjl&5UJWgA{IYuttN4(l=4RM89~9QcZ#^%Ftkh^X;kkw8Uu`6F~T?xTvXmyDvR>olP2@WmC2 z?L)eLy<%7%64muw0XxKkk1yE(cj~%B!0?Q25U^mbLQF^3aR}aAXCFX!C-QdDOjHt+ zmCQA;a3XJz#Op4^K~Qv=A2tpP@OS8UQNcT!^4AQLK+0(SS71h~X<;J7kPXQ|#2H^d znvpbK6GnJf8xh%+Dg9_xJ>)q@6E&YEjWkohzo~JeMMK`aA>iUc_}7*!y`>pB#l<75jN0?Ekk++D?QF?GmYxYmaJ zWSQLA^!!k(I1Gx;r@;QZgT6*<67omCckTsi;`o}3IBrcrk&gQl_pa2$%WHln2yAK` zUkfrpXj5Z+EzATF)E2v+x%X8~ocK2if<_**k~kZ0$Lv8IVJym68!%=AVKHu08CDp; z!ije=#)6A`8S7(=)dyA?>jy^LTdc`dN*SoWc2BJ^wh;4tw3dRAox9mqTyU;i z`^pRMdMuHk+%d|Xpj_f+0DuB9L6(?=h9sJqybb+I@+MWtyF#xxFs|B~r!rLD7dFn) zO+0TqWb0J6G1=12df!EZjmPw|LGqY|({2B(B@%-v(SSE64aQ-H zpzg5h7*y3pod?C_tqmSs*?Vlce|d6sY`Qi!y)t_7 zrND*L+?s&=p_c*F-n01rYR~>!&;FI}p_NGDuJAnEy?AixQa!w{I{92w?xb#~R>hq) zapz*XF7A06Y_F!=QaBrrP+8ZrHqA zso9vJZaFgtxC6LRb8aV8#u@{C9G?J`H2`M>7+3@Sisw1;m4djjCusB!bnXc{w;^$y c|L*Y(C|&=CB6Fv>yJQ2gb)zH5?Qk#tADz)W5C8xG literal 0 HcmV?d00001 diff --git a/models/__pycache__/db.cpython-314.pyc b/models/__pycache__/db.cpython-314.pyc new file mode 100644 index 0000000000000000000000000000000000000000..a3d9d842264bbe02d5eec7abb6add2215e29b388 GIT binary patch literal 6116 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 LrfG*jMGyNA?8te| literal 0 HcmV?d00001