Commit
·
e96c447
1
Parent(s):
e0d11fa
added xvid
Browse files
app.py
CHANGED
@@ -2,36 +2,14 @@ import requests
|
|
2 |
import random
|
3 |
from bs4 import BeautifulSoup
|
4 |
from fastapi import FastAPI, HTTPException, Depends
|
5 |
-
from pydantic import BaseModel
|
6 |
from itertools import islice
|
7 |
-
from
|
8 |
from fastapi.middleware.cors import CORSMiddleware
|
9 |
from xnxx_api import search_filters
|
10 |
from xnxx_api import Client as xnxx_client
|
|
|
|
|
11 |
|
12 |
-
# Constants
|
13 |
-
CREATOR = "EyePatch"
|
14 |
-
API_VERSION = "1.3.0"
|
15 |
-
|
16 |
-
# ----- Pydantic Models -----
|
17 |
-
class SuccessResponse(BaseModel):
|
18 |
-
creator: str = CREATOR
|
19 |
-
status: str = "success"
|
20 |
-
api_version: str = API_VERSION
|
21 |
-
data: Dict[str, Any]
|
22 |
-
|
23 |
-
class ErrorResponse(BaseModel):
|
24 |
-
status: str = "error"
|
25 |
-
creator: str = CREATOR
|
26 |
-
api_version: str = API_VERSION
|
27 |
-
error_code: int
|
28 |
-
message: str
|
29 |
-
|
30 |
-
class ItemPayload(BaseModel):
|
31 |
-
name: str
|
32 |
-
description: Optional[str] = None
|
33 |
-
price: float
|
34 |
-
tags: list[str] = []
|
35 |
|
36 |
# ----- FastAPI Setup -----
|
37 |
app = FastAPI(title="Awesome API", version=API_VERSION)
|
@@ -89,6 +67,25 @@ async def root(version: str = Depends(get_api_version)):
|
|
89 |
return SuccessResponse(data={
|
90 |
"message": "Service operational",
|
91 |
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
92 |
|
93 |
@app.get("/prono/xnxxsearch", response_model=SuccessResponse)
|
94 |
async def xnxx_search(
|
@@ -143,13 +140,14 @@ async def xnxx_search(
|
|
143 |
# search_kwargs["limit"] = page
|
144 |
|
145 |
# Perform the search with only the provided parameters
|
146 |
-
|
147 |
-
|
148 |
-
|
149 |
-
|
|
|
150 |
|
151 |
results_list = []
|
152 |
-
for x in
|
153 |
results_list.append({
|
154 |
"title": x.title,
|
155 |
"url": x.url,
|
@@ -161,7 +159,6 @@ async def xnxx_search(
|
|
161 |
"thumb": x.thumbnail_url[0] if isinstance(x.thumbnail_url, list) and len(x.thumbnail_url) > 0 else None
|
162 |
})
|
163 |
return SuccessResponse(
|
164 |
-
status="True",
|
165 |
data={
|
166 |
"results": results_list
|
167 |
}
|
@@ -171,23 +168,6 @@ async def xnxx_search(
|
|
171 |
status="False",
|
172 |
data={"error": f"Error: {e}"}
|
173 |
)
|
174 |
-
|
175 |
-
@app.get("/protected", responses={
|
176 |
-
200: {"model": SuccessResponse},
|
177 |
-
403: {"model": ErrorResponse}
|
178 |
-
})
|
179 |
-
async def protected_route(secret_key: Optional[str] = None):
|
180 |
-
"""Endpoint demonstrating error responses"""
|
181 |
-
if not secret_key or secret_key != "supersecret123":
|
182 |
-
return ErrorResponse(
|
183 |
-
error_code=403,
|
184 |
-
message="Invalid or missing secret key"
|
185 |
-
)
|
186 |
-
|
187 |
-
return SuccessResponse(data={
|
188 |
-
"secret_data": "🔐 You've unlocked premium content!",
|
189 |
-
"access_level": "VIP"
|
190 |
-
})
|
191 |
|
192 |
|
193 |
@app.get("/prono/hentai", response_model=SuccessResponse)
|
@@ -203,3 +183,139 @@ async def hentai_():
|
|
203 |
status="False",
|
204 |
data={"error": "Error fucking"}
|
205 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2 |
import random
|
3 |
from bs4 import BeautifulSoup
|
4 |
from fastapi import FastAPI, HTTPException, Depends
|
|
|
5 |
from itertools import islice
|
6 |
+
from models import SuccessResponse, ErrorResponse, API_VERSION
|
7 |
from fastapi.middleware.cors import CORSMiddleware
|
8 |
from xnxx_api import search_filters
|
9 |
from xnxx_api import Client as xnxx_client
|
10 |
+
from xvideos_api import Client as xvid_client
|
11 |
+
from xvideos_api import sorting
|
12 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
13 |
|
14 |
# ----- FastAPI Setup -----
|
15 |
app = FastAPI(title="Awesome API", version=API_VERSION)
|
|
|
67 |
return SuccessResponse(data={
|
68 |
"message": "Service operational",
|
69 |
})
|
70 |
+
|
71 |
+
|
72 |
+
@app.get("/protected", responses={
|
73 |
+
200: {"model": SuccessResponse},
|
74 |
+
403: {"model": ErrorResponse}
|
75 |
+
})
|
76 |
+
async def protected_route(secret_key: Optional[str] = None):
|
77 |
+
"""Endpoint demonstrating error responses"""
|
78 |
+
if not secret_key or secret_key != "supersecret123":
|
79 |
+
return ErrorResponse(
|
80 |
+
error_code=403,
|
81 |
+
message="Invalid or missing secret key"
|
82 |
+
)
|
83 |
+
|
84 |
+
return SuccessResponse(data={
|
85 |
+
"secret_data": "🔐 You've unlocked premium content!",
|
86 |
+
"access_level": "VIP"
|
87 |
+
})
|
88 |
+
|
89 |
|
90 |
@app.get("/prono/xnxxsearch", response_model=SuccessResponse)
|
91 |
async def xnxx_search(
|
|
|
140 |
# search_kwargs["limit"] = page
|
141 |
|
142 |
# Perform the search with only the provided parameters
|
143 |
+
c = xnxx_client()
|
144 |
+
search = c.search(**search_kwargs)
|
145 |
+
# response = search.videos
|
146 |
+
# if results is not None:
|
147 |
+
# response = islice(res, results)
|
148 |
|
149 |
results_list = []
|
150 |
+
for x in islice(search.videos, results):
|
151 |
results_list.append({
|
152 |
"title": x.title,
|
153 |
"url": x.url,
|
|
|
159 |
"thumb": x.thumbnail_url[0] if isinstance(x.thumbnail_url, list) and len(x.thumbnail_url) > 0 else None
|
160 |
})
|
161 |
return SuccessResponse(
|
|
|
162 |
data={
|
163 |
"results": results_list
|
164 |
}
|
|
|
168 |
status="False",
|
169 |
data={"error": f"Error: {e}"}
|
170 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
171 |
|
172 |
|
173 |
@app.get("/prono/hentai", response_model=SuccessResponse)
|
|
|
183 |
status="False",
|
184 |
data={"error": "Error fucking"}
|
185 |
)
|
186 |
+
|
187 |
+
|
188 |
+
@app.get("/prono/xnxx-dl", response_model=SuccessResponse, responses={422: {"model": SuccessResponse}})
|
189 |
+
async def xnxx_download(link: str):
|
190 |
+
try:
|
191 |
+
x = xnxx_client()
|
192 |
+
response = x.get_video(link)
|
193 |
+
return SuccessResponse(
|
194 |
+
data={
|
195 |
+
"results": {
|
196 |
+
"title": response.title,
|
197 |
+
"author": response.author,
|
198 |
+
"length": f"{response.length} min",
|
199 |
+
"highest_quality": response.highest_quality,
|
200 |
+
"publish_date": response.publish_date,
|
201 |
+
"views": response.views,
|
202 |
+
"link": response.content_url,
|
203 |
+
"thumb": response.thumbnail_url[0] if isinstance(response.thumbnail_url, list) and len(response.thumbnail_url) > 0 else None
|
204 |
+
}
|
205 |
+
}
|
206 |
+
)
|
207 |
+
|
208 |
+
except Exception as e:
|
209 |
+
return SuccessResponse(
|
210 |
+
status="False",
|
211 |
+
randydev={"error": f"Error fucking: {e}"}
|
212 |
+
)
|
213 |
+
|
214 |
+
|
215 |
+
@app.get("/prono/xvidsearch", response_model=SuccessResponse)
|
216 |
+
async def xvid_search(
|
217 |
+
query: str,
|
218 |
+
quality: Optional[str] = None,
|
219 |
+
upload_time: Optional[str] = None,
|
220 |
+
length: Optional[str] = None,
|
221 |
+
mode: Optional[str] = None,
|
222 |
+
# page: Optional[int] = None,
|
223 |
+
results: Optional[int] = 20
|
224 |
+
):
|
225 |
+
data_dict = {
|
226 |
+
"quality": {
|
227 |
+
"720p": sorting.SortQuality.Sort_720p,
|
228 |
+
"1080p": sorting.SortQuality.Sort_1080_plus
|
229 |
+
},
|
230 |
+
"upload_time": {
|
231 |
+
"3months": sorting.SortDateSort_last_3_months,
|
232 |
+
"6months": sorting.SortDateSort_last_6_months
|
233 |
+
},
|
234 |
+
"length": {
|
235 |
+
"0-10min": sorting.SortVideoTime.Sort_middle,
|
236 |
+
"10min+": sorting.SortVideoTime.Sort_long,
|
237 |
+
"10-20min": sorting.SortVideoTime.Sort_long_10_20min,
|
238 |
+
"20min+": sorting.SortVideoTime.Sort_really_long
|
239 |
+
},
|
240 |
+
"mode": {
|
241 |
+
"rating": sorting.Sort.Sort_rating,
|
242 |
+
"views": sorting.Sort.Sort_views,
|
243 |
+
"random": sorting.Sort.Sort_random,
|
244 |
+
"relevance": sorting.Sort.Sort_relevance
|
245 |
+
}
|
246 |
+
}
|
247 |
+
|
248 |
+
try:
|
249 |
+
# Prepare search parameters
|
250 |
+
search_kwargs = {
|
251 |
+
"query": query
|
252 |
+
}
|
253 |
+
if length is not None:
|
254 |
+
search_kwargs["sorting_time"] = data_dict["length"][length]
|
255 |
+
|
256 |
+
if quality is not None:
|
257 |
+
search_kwargs["sort_quality"] = data_dict["quality"][quality]
|
258 |
+
|
259 |
+
if upload_time is not None:
|
260 |
+
search_kwargs["sorting_time"] = data_dict["upload_time"][upload_time]
|
261 |
+
|
262 |
+
if mode is not None:
|
263 |
+
search_kwargs["sorting_sort"] = data_dict["mode"][mode]
|
264 |
+
|
265 |
+
|
266 |
+
# Perform the search with only the provided parameters
|
267 |
+
c = xvid_client()
|
268 |
+
search = c.search(**search_kwargs)
|
269 |
+
# response = search.videos
|
270 |
+
# if results is not None:
|
271 |
+
# response = islice(res, results)
|
272 |
+
|
273 |
+
results_list = []
|
274 |
+
for x in islice(search, results):
|
275 |
+
results_list.append({
|
276 |
+
"title": x.title,
|
277 |
+
"url": x.url,
|
278 |
+
"author": x.author,
|
279 |
+
"length": x.length,
|
280 |
+
"publish_date": x.publish_date,
|
281 |
+
"views": x.views,
|
282 |
+
"thumb": x.thumbnail_url
|
283 |
+
})
|
284 |
+
return SuccessResponse(
|
285 |
+
data={
|
286 |
+
"results": results_list
|
287 |
+
}
|
288 |
+
)
|
289 |
+
except Exception as e:
|
290 |
+
return SuccessResponse(
|
291 |
+
status="False",
|
292 |
+
data={"error": f"Error: {e}"}
|
293 |
+
)
|
294 |
+
|
295 |
+
|
296 |
+
@app.get("/prono/xvid-dl", response_model=SuccessResponse, responses={422: {"model": SuccessResponse}})
|
297 |
+
async def xvid_download(link: str):
|
298 |
+
try:
|
299 |
+
x = xvid_client()
|
300 |
+
response = x.get_video(link)
|
301 |
+
return SuccessResponse(
|
302 |
+
data={
|
303 |
+
"results": {
|
304 |
+
"title": response.title,
|
305 |
+
"description": response.description,
|
306 |
+
"author": response.author,
|
307 |
+
"length": response.length,
|
308 |
+
"tags": response.tags,
|
309 |
+
"publish_date": response.publish_date,
|
310 |
+
"views": response.views,
|
311 |
+
"link": response.cdn_url,
|
312 |
+
"thumb": response.thumbnail_url
|
313 |
+
}
|
314 |
+
}
|
315 |
+
)
|
316 |
+
|
317 |
+
except Exception as e:
|
318 |
+
return SuccessResponse(
|
319 |
+
status="False",
|
320 |
+
randydev={"error": f"Error fucking: {e}"}
|
321 |
+
)
|
models.py
ADDED
@@ -0,0 +1,26 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from pydantic import BaseModel
|
2 |
+
from typing import Dict, Any, Optional
|
3 |
+
|
4 |
+
# Constants
|
5 |
+
CREATOR = "EyePatch"
|
6 |
+
API_VERSION = "1.3.5"
|
7 |
+
|
8 |
+
# ----- Pydantic Models -----
|
9 |
+
class SuccessResponse(BaseModel):
|
10 |
+
creator: str = CREATOR
|
11 |
+
status: str = "success"
|
12 |
+
api_version: str = API_VERSION
|
13 |
+
data: Dict[str, Any]
|
14 |
+
|
15 |
+
class ErrorResponse(BaseModel):
|
16 |
+
status: str = "error"
|
17 |
+
creator: str = CREATOR
|
18 |
+
api_version: str = API_VERSION
|
19 |
+
error_code: int
|
20 |
+
message: str
|
21 |
+
|
22 |
+
class ItemPayload(BaseModel):
|
23 |
+
name: str
|
24 |
+
description: Optional[str] = None
|
25 |
+
price: float
|
26 |
+
tags: list[str] = []
|