KekikStream 1.3.6__py3-none-any.whl → 1.3.7__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- KekikStreamAPI/.github/FUNDING.yml +5 -0
- KekikStreamAPI/.gitignore +166 -0
- KekikStreamAPI/AYAR.yml +8 -0
- KekikStreamAPI/CLI/__init__.py +3 -0
- KekikStreamAPI/Core/Modules/_IP_Log.py +27 -0
- KekikStreamAPI/Core/Modules/_hata.py +12 -0
- KekikStreamAPI/Core/Modules/_istek.py +131 -0
- KekikStreamAPI/Core/Motor.py +13 -0
- KekikStreamAPI/Core/__init__.py +24 -0
- KekikStreamAPI/Dockerfile +34 -0
- KekikStreamAPI/Public/API/v1/Libs/__init__.py +7 -0
- KekikStreamAPI/Public/API/v1/Routers/__init__.py +25 -0
- KekikStreamAPI/Public/API/v1/Routers/extract.py +26 -0
- KekikStreamAPI/Public/API/v1/Routers/get_main_page.py +33 -0
- KekikStreamAPI/Public/API/v1/Routers/get_plugin.py +39 -0
- KekikStreamAPI/Public/API/v1/Routers/get_plugin_names.py +13 -0
- KekikStreamAPI/Public/API/v1/Routers/load_item.py +34 -0
- KekikStreamAPI/Public/API/v1/Routers/load_links.py +41 -0
- KekikStreamAPI/Public/API/v1/Routers/search.py +31 -0
- KekikStreamAPI/Public/Home/Routers/__init__.py +9 -0
- KekikStreamAPI/Public/Home/Routers/ana_sayfa.py +14 -0
- KekikStreamAPI/Public/Home/Static/CSS/stil.css +85 -0
- KekikStreamAPI/Public/Home/Static/JS/bakalim.js +1 -0
- KekikStreamAPI/Public/Home/Static/favicon.ico +0 -0
- KekikStreamAPI/Public/Home/Templates/_html_taban.html +50 -0
- KekikStreamAPI/Public/Home/Templates/index.html +33 -0
- KekikStreamAPI/README.md +13 -0
- KekikStreamAPI/Settings/__init__.py +11 -0
- KekikStreamAPI/Tests/Multi.py +64 -0
- KekikStreamAPI/Tests/Single.py +62 -0
- KekikStreamAPI/basla.py +18 -0
- KekikStreamAPI/docker-compose.yml +20 -0
- KekikStreamAPI/requirements.txt +11 -0
- kekikstream-1.3.7.dist-info/LICENSE +674 -0
- {kekikstream-1.3.6.dist-info → kekikstream-1.3.7.dist-info}/METADATA +7 -1
- {kekikstream-1.3.6.dist-info → kekikstream-1.3.7.dist-info}/RECORD +40 -6
- {kekikstream-1.3.6.dist-info → kekikstream-1.3.7.dist-info}/entry_points.txt +1 -0
- kekikstream-1.3.7.dist-info/top_level.txt +2 -0
- kekikstream-1.3.6.dist-info/top_level.txt +0 -1
- {kekikstream-1.3.6.dist-info → KekikStreamAPI}/LICENSE +0 -0
- {kekikstream-1.3.6.dist-info → kekikstream-1.3.7.dist-info}/WHEEL +0 -0
@@ -0,0 +1,166 @@
|
|
1
|
+
# Byte-compiled / optimized / DLL files
|
2
|
+
__pycache__/
|
3
|
+
*.py[cod]
|
4
|
+
*$py.class
|
5
|
+
|
6
|
+
# C extensions
|
7
|
+
*.so
|
8
|
+
|
9
|
+
# Distribution / packaging
|
10
|
+
.Python
|
11
|
+
build/
|
12
|
+
develop-eggs/
|
13
|
+
dist/
|
14
|
+
downloads/
|
15
|
+
eggs/
|
16
|
+
.eggs/
|
17
|
+
lib/
|
18
|
+
lib64/
|
19
|
+
parts/
|
20
|
+
sdist/
|
21
|
+
var/
|
22
|
+
wheels/
|
23
|
+
share/python-wheels/
|
24
|
+
*.egg-info/
|
25
|
+
.installed.cfg
|
26
|
+
*.egg
|
27
|
+
MANIFEST
|
28
|
+
|
29
|
+
# PyInstaller
|
30
|
+
# Usually these files are written by a python script from a template
|
31
|
+
# before PyInstaller builds the exe, so as to inject date/other infos into it.
|
32
|
+
*.manifest
|
33
|
+
*.spec
|
34
|
+
|
35
|
+
# Installer logs
|
36
|
+
pip-log.txt
|
37
|
+
pip-delete-this-directory.txt
|
38
|
+
|
39
|
+
# Unit test / coverage reports
|
40
|
+
htmlcov/
|
41
|
+
.tox/
|
42
|
+
.nox/
|
43
|
+
.coverage
|
44
|
+
.coverage.*
|
45
|
+
.cache
|
46
|
+
nosetests.xml
|
47
|
+
coverage.xml
|
48
|
+
*.cover
|
49
|
+
*.py,cover
|
50
|
+
.hypothesis/
|
51
|
+
.pytest_cache/
|
52
|
+
cover/
|
53
|
+
|
54
|
+
# Translations
|
55
|
+
*.mo
|
56
|
+
*.pot
|
57
|
+
|
58
|
+
# Django stuff:
|
59
|
+
*.log
|
60
|
+
local_settings.py
|
61
|
+
db.sqlite3
|
62
|
+
db.sqlite3-journal
|
63
|
+
|
64
|
+
# Flask stuff:
|
65
|
+
instance/
|
66
|
+
.webassets-cache
|
67
|
+
|
68
|
+
# Scrapy stuff:
|
69
|
+
.scrapy
|
70
|
+
|
71
|
+
# Sphinx documentation
|
72
|
+
docs/_build/
|
73
|
+
|
74
|
+
# PyBuilder
|
75
|
+
.pybuilder/
|
76
|
+
target/
|
77
|
+
|
78
|
+
# Jupyter Notebook
|
79
|
+
.ipynb_checkpoints
|
80
|
+
|
81
|
+
# IPython
|
82
|
+
profile_default/
|
83
|
+
ipython_config.py
|
84
|
+
|
85
|
+
# pyenv
|
86
|
+
# For a library or package, you might want to ignore these files since the code is
|
87
|
+
# intended to run in multiple environments; otherwise, check them in:
|
88
|
+
# .python-version
|
89
|
+
|
90
|
+
# pipenv
|
91
|
+
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
|
92
|
+
# However, in case of collaboration, if having platform-specific dependencies or dependencies
|
93
|
+
# having no cross-platform support, pipenv may install dependencies that don't work, or not
|
94
|
+
# install all needed dependencies.
|
95
|
+
#Pipfile.lock
|
96
|
+
|
97
|
+
# poetry
|
98
|
+
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
|
99
|
+
# This is especially recommended for binary packages to ensure reproducibility, and is more
|
100
|
+
# commonly ignored for libraries.
|
101
|
+
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
|
102
|
+
#poetry.lock
|
103
|
+
|
104
|
+
# pdm
|
105
|
+
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
|
106
|
+
#pdm.lock
|
107
|
+
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
|
108
|
+
# in version control.
|
109
|
+
# https://pdm.fming.dev/latest/usage/project/#working-with-version-control
|
110
|
+
.pdm.toml
|
111
|
+
.pdm-python
|
112
|
+
.pdm-build/
|
113
|
+
|
114
|
+
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
|
115
|
+
__pypackages__/
|
116
|
+
|
117
|
+
# Celery stuff
|
118
|
+
celerybeat-schedule
|
119
|
+
celerybeat.pid
|
120
|
+
|
121
|
+
# SageMath parsed files
|
122
|
+
*.sage.py
|
123
|
+
|
124
|
+
# Environments
|
125
|
+
.env
|
126
|
+
.venv
|
127
|
+
env/
|
128
|
+
venv/
|
129
|
+
ENV/
|
130
|
+
env.bak/
|
131
|
+
venv.bak/
|
132
|
+
|
133
|
+
# Spyder project settings
|
134
|
+
.spyderproject
|
135
|
+
.spyproject
|
136
|
+
|
137
|
+
# Rope project settings
|
138
|
+
.ropeproject
|
139
|
+
|
140
|
+
# mkdocs documentation
|
141
|
+
/site
|
142
|
+
|
143
|
+
# mypy
|
144
|
+
.mypy_cache/
|
145
|
+
.dmypy.json
|
146
|
+
dmypy.json
|
147
|
+
|
148
|
+
# Pyre type checker
|
149
|
+
.pyre/
|
150
|
+
|
151
|
+
# pytype static type analyzer
|
152
|
+
.pytype/
|
153
|
+
|
154
|
+
# Cython debug symbols
|
155
|
+
cython_debug/
|
156
|
+
|
157
|
+
# PyCharm
|
158
|
+
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
|
159
|
+
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
|
160
|
+
# and can be added to the global gitignore or merged into this file. For a more nuclear
|
161
|
+
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
|
162
|
+
#.idea/
|
163
|
+
|
164
|
+
SineWixDB*
|
165
|
+
cookies.txt
|
166
|
+
youtubeCheck.py
|
KekikStreamAPI/AYAR.yml
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
2
|
+
|
3
|
+
from httpx import AsyncClient
|
4
|
+
from Core import kekik_cache
|
5
|
+
from Settings import CACHE_TIME
|
6
|
+
|
7
|
+
@kekik_cache(ttl=CACHE_TIME)
|
8
|
+
async def ip_log(hedef_ip:str) -> dict[str, str]:
|
9
|
+
try:
|
10
|
+
oturum = AsyncClient(timeout=3)
|
11
|
+
|
12
|
+
istek = await oturum.get(f"http://ip-api.com/json/{hedef_ip}")
|
13
|
+
veri = istek.json()
|
14
|
+
|
15
|
+
if veri["status"] != "fail":
|
16
|
+
return {
|
17
|
+
"ulke" : veri["country"] or "",
|
18
|
+
"il" : veri["regionName"] or "",
|
19
|
+
"ilce" : veri["city"] or "",
|
20
|
+
"isp" : veri["isp"] or "",
|
21
|
+
"sirket" : veri["org"] or "",
|
22
|
+
"host" : veri["as"] or ""
|
23
|
+
}
|
24
|
+
else:
|
25
|
+
return {"hata": "Veri Bulunamadı.."}
|
26
|
+
except Exception as hata:
|
27
|
+
return {"hata": f"{type(hata).__name__} » {hata}"}
|
@@ -0,0 +1,12 @@
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
2
|
+
|
3
|
+
from Core import KekikStreamAPI, Request, RedirectResponse, JSONResponse, FileResponse
|
4
|
+
from starlette.exceptions import HTTPException as StarletteHTTPException
|
5
|
+
|
6
|
+
@KekikStreamAPI.exception_handler(StarletteHTTPException)
|
7
|
+
async def custom_http_exception_handler(request:Request, exc):
|
8
|
+
return RedirectResponse("/") if exc.status_code != 410 else JSONResponse(status_code=exc.status_code, content={"detail": exc.detail})
|
9
|
+
|
10
|
+
@KekikStreamAPI.get("/favicon.ico")
|
11
|
+
def get_favicon():
|
12
|
+
return FileResponse("Public/Home/Static/favicon.ico")
|
@@ -0,0 +1,131 @@
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
2
|
+
|
3
|
+
from CLI import konsol
|
4
|
+
from Core import KekikStreamAPI, Request, JSONResponse
|
5
|
+
from time import time
|
6
|
+
from user_agents import parse
|
7
|
+
from ._IP_Log import ip_log
|
8
|
+
import asyncio
|
9
|
+
|
10
|
+
@KekikStreamAPI.middleware("http")
|
11
|
+
async def istekten_once_sonra(request: Request, call_next):
|
12
|
+
baslangic_zamani = time()
|
13
|
+
|
14
|
+
if request.method == "GET":
|
15
|
+
request.state.req_veri = dict(request.query_params) if request.query_params else None
|
16
|
+
else:
|
17
|
+
try:
|
18
|
+
request.state.req_veri = await request.json()
|
19
|
+
except Exception:
|
20
|
+
form_data = await request.form()
|
21
|
+
request.state.req_veri = dict(form_data.items())
|
22
|
+
|
23
|
+
try:
|
24
|
+
ua_header = request.headers.get("User-Agent")
|
25
|
+
parsed_ua = parse(ua_header)
|
26
|
+
cihaz = ua_header if str(parsed_ua).split("/")[2].strip() == "Other" else parsed_ua
|
27
|
+
except Exception:
|
28
|
+
cihaz = request.headers.get("User-Agent")
|
29
|
+
|
30
|
+
log_ip = request.headers.get("X-Forwarded-For") or request.client.host
|
31
|
+
ip_w_cf = (
|
32
|
+
f"{request.headers.get('Cf-Connecting-Ip')} [yellow]| CF: ({log_ip})[/]"
|
33
|
+
if request.headers.get("Cf-Connecting-Ip")
|
34
|
+
else log_ip
|
35
|
+
)
|
36
|
+
|
37
|
+
log_veri = {
|
38
|
+
"id" : request.headers.get("X-Request-ID") or "",
|
39
|
+
"method" : request.method,
|
40
|
+
"url" : str(request.url).rstrip("?").split("?")[0],
|
41
|
+
"veri" : request.state.req_veri,
|
42
|
+
"kod" : None,
|
43
|
+
"sure" : None,
|
44
|
+
"ip" : log_ip,
|
45
|
+
"cihaz" : cihaz,
|
46
|
+
"host" : request.url.hostname,
|
47
|
+
}
|
48
|
+
|
49
|
+
try:
|
50
|
+
# async with asyncio.timeout(7.5):
|
51
|
+
response = await asyncio.wait_for(call_next(request), timeout=7.5)
|
52
|
+
if response:
|
53
|
+
log_veri["kod"] = response.status_code
|
54
|
+
else:
|
55
|
+
log_veri["kod"] = 502
|
56
|
+
response = JSONResponse(status_code=log_veri["kod"], content={"ups": "Yanit Gelmedi.."})
|
57
|
+
except asyncio.TimeoutError:
|
58
|
+
log_veri["kod"] = 504
|
59
|
+
response = JSONResponse(status_code=log_veri["kod"], content={"ups": "Zaman Aşımı.."})
|
60
|
+
|
61
|
+
for skip_path in ("/favicon.ico", "/static", "/webfonts"):
|
62
|
+
if skip_path in request.url.path:
|
63
|
+
return response
|
64
|
+
|
65
|
+
log_veri["sure"] = round(time() - baslangic_zamani, 2)
|
66
|
+
await log_salla(log_veri, request)
|
67
|
+
|
68
|
+
return response
|
69
|
+
|
70
|
+
async def log_salla(log_veri: dict, request: Request):
|
71
|
+
log_url = (
|
72
|
+
log_veri['url'].replace(request.url.scheme, request.headers.get("X-Forwarded-Proto"))
|
73
|
+
if request.headers.get("X-Forwarded-Proto")
|
74
|
+
else log_veri['url']
|
75
|
+
)
|
76
|
+
|
77
|
+
LABEL_WIDTH = 5
|
78
|
+
durum_label = f"[green]{'durum':<{LABEL_WIDTH}}:[/]"
|
79
|
+
ip_label = f"[green]{'ip':<{LABEL_WIDTH}}:[/]"
|
80
|
+
konum_label = f"[green]{'konum':<{LABEL_WIDTH}}:[/]"
|
81
|
+
cihaz_label = f"[green]{'cihaz':<{LABEL_WIDTH}}:[/]"
|
82
|
+
|
83
|
+
log_lines = []
|
84
|
+
|
85
|
+
log_lines.append(f"[bold blue]»[/] [bold turquoise2]{log_url}[/]")
|
86
|
+
|
87
|
+
if log_veri["veri"]:
|
88
|
+
log_lines.append(f"[bold magenta]»[/] [bold cyan]{log_veri['veri']}[/]")
|
89
|
+
|
90
|
+
durum_line = (
|
91
|
+
f" {durum_label} [bold green]{log_veri['method']}[/]"
|
92
|
+
f" [blue]-[/] [bold bright_yellow]{log_veri['kod']}[/]"
|
93
|
+
f" [blue]-[/] [bold yellow2]{log_veri['sure']} sn[/]"
|
94
|
+
)
|
95
|
+
log_lines.append(durum_line)
|
96
|
+
|
97
|
+
if log_veri["id"]:
|
98
|
+
ip_line = (
|
99
|
+
f" {ip_label} [bold bright_blue]{log_veri['id']}[/]"
|
100
|
+
f"[bold green]@[/][bold red]{log_veri['ip']}[/]"
|
101
|
+
)
|
102
|
+
else:
|
103
|
+
ip_line = f" {ip_label} [bold red]{log_veri['ip']}[/]"
|
104
|
+
log_lines.append(ip_line)
|
105
|
+
|
106
|
+
ip_detay = await ip_log(log_veri["ip"].split()[0].replace(",", ""))
|
107
|
+
if ("hata" not in ip_detay) and ip_detay.get("ulke"):
|
108
|
+
il = ip_detay["il"].replace(" Province", "")
|
109
|
+
ilce = ip_detay["ilce"]
|
110
|
+
|
111
|
+
host_str = " ".join(ip_detay["host"].split()[1:4])
|
112
|
+
|
113
|
+
if il != ilce:
|
114
|
+
konum_line = (
|
115
|
+
f" {konum_label} [bold chartreuse3]{ip_detay['ulke']}[/]"
|
116
|
+
f" [blue]|[/] [bold chartreuse3]{il}[/]"
|
117
|
+
f" [blue]|[/] [bold chartreuse3]{ilce}[/]"
|
118
|
+
f" [blue]|[/] [bold chartreuse3]{host_str}[/]"
|
119
|
+
)
|
120
|
+
else:
|
121
|
+
konum_line = (
|
122
|
+
f" {konum_label} [bold chartreuse3]{ip_detay['ulke']}[/]"
|
123
|
+
f" [blue]|[/] [bold chartreuse3]{il}[/]"
|
124
|
+
f" [blue]|[/] [bold chartreuse3]{host_str}[/]"
|
125
|
+
)
|
126
|
+
log_lines.append(konum_line)
|
127
|
+
|
128
|
+
log_lines.append(f" {cihaz_label} [magenta]{log_veri['cihaz']}[/]")
|
129
|
+
|
130
|
+
final_log = "\n".join(log_lines)
|
131
|
+
konsol.log(final_log + "\n")
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
2
|
+
|
3
|
+
from CLI import konsol
|
4
|
+
from Settings import AYAR, HOST, PORT, WORKERS
|
5
|
+
from sys import version_info
|
6
|
+
import uvicorn
|
7
|
+
|
8
|
+
def basla():
|
9
|
+
surum = f"{version_info[0]}.{version_info[1]}"
|
10
|
+
konsol.print(f"\n[bold gold1]{AYAR['PROJE']}[/] [yellow]:bird:[/] [turquoise2]Python {surum}[/] [bold yellow2]uvicorn[/]", width=70, justify="center")
|
11
|
+
konsol.print(f"[red]{HOST}[light_coral]:[/]{PORT}[pale_green1] başlatılmıştır...[/]\n", width=70, justify="center")
|
12
|
+
|
13
|
+
uvicorn.run("Core:KekikStreamAPI", host=HOST, port=PORT, forwarded_allow_ips="*", workers=WORKERS, log_level="error")
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
2
|
+
|
3
|
+
from fastapi import FastAPI, Request, Response, HTTPException
|
4
|
+
from fastapi.staticfiles import StaticFiles
|
5
|
+
from fastapi.responses import JSONResponse, HTMLResponse, RedirectResponse, PlainTextResponse, FileResponse
|
6
|
+
from Kekik.cache import kekik_cache
|
7
|
+
|
8
|
+
KekikStreamAPI = FastAPI(
|
9
|
+
title = "KekikStreamAPI",
|
10
|
+
openapi_url = None,
|
11
|
+
docs_url = None,
|
12
|
+
redoc_url = None
|
13
|
+
)
|
14
|
+
|
15
|
+
# ! ----------------------------------------» Routers
|
16
|
+
|
17
|
+
from Core.Modules import _istek, _hata
|
18
|
+
from Public.Home.Routers import home_router
|
19
|
+
from Public.API.v1.Routers import api_v1_router
|
20
|
+
|
21
|
+
KekikStreamAPI.include_router(home_router, prefix="")
|
22
|
+
KekikStreamAPI.mount("/static/home", StaticFiles(directory="Public/Home/Static"), name="static_home")
|
23
|
+
|
24
|
+
KekikStreamAPI.include_router(api_v1_router, prefix="/api/v1")
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
2
|
+
|
3
|
+
# * Docker İmajı
|
4
|
+
FROM python:3.11.8-slim-bookworm
|
5
|
+
|
6
|
+
# * Çalışma Alanı
|
7
|
+
WORKDIR /usr/src/KekikStreamAPI
|
8
|
+
COPY ./ /usr/src/KekikStreamAPI
|
9
|
+
|
10
|
+
# ? Sistem Kurulumları ve Gereksiz Dosyaların Silinmesi
|
11
|
+
RUN apt-get update -y && \
|
12
|
+
apt-get install --no-install-recommends -y \
|
13
|
+
# git \
|
14
|
+
# ffmpeg \
|
15
|
+
# opus-tools \
|
16
|
+
locales && \
|
17
|
+
sed -i -e 's/# tr_TR.UTF-8 UTF-8/tr_TR.UTF-8 UTF-8/' /etc/locale.gen && \
|
18
|
+
dpkg-reconfigure --frontend=noninteractive locales && \
|
19
|
+
apt-get clean && \
|
20
|
+
rm -rf /var/lib/apt/lists/*
|
21
|
+
|
22
|
+
# * Python Standart Değişkenler
|
23
|
+
ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1 PYTHONIOENCODING="UTF-8"
|
24
|
+
|
25
|
+
# * Dil ve Bölge
|
26
|
+
ENV LANGUAGE="tr_TR.UTF-8" LANG="tr_TR.UTF-8" LC_ALL="tr_TR.UTF-8" TZ="Europe/Istanbul"
|
27
|
+
|
28
|
+
# * Gerekli Paketlerin Yüklenmesi
|
29
|
+
RUN python3 -m pip install --upgrade pip && \
|
30
|
+
python3 -m pip install --no-cache-dir -U setuptools wheel && \
|
31
|
+
python3 -m pip install --no-cache-dir -Ur requirements.txt
|
32
|
+
|
33
|
+
# * Python Çalıştırılması
|
34
|
+
CMD ["python3", "basla.py"]
|
@@ -0,0 +1,7 @@
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
2
|
+
|
3
|
+
from KekikStream.Core import PluginManager, ExtractorManager, MediaManager, MovieInfo, SeriesInfo
|
4
|
+
|
5
|
+
plugin_manager = PluginManager()
|
6
|
+
extractor_manager = ExtractorManager()
|
7
|
+
media_manager = MediaManager()
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
2
|
+
|
3
|
+
from fastapi import APIRouter
|
4
|
+
from Core import Request, kekik_cache
|
5
|
+
from Settings import CACHE_TIME
|
6
|
+
|
7
|
+
api_v1_router = APIRouter()
|
8
|
+
api_v1_global_message = {
|
9
|
+
"with" : "https://github.com/keyiflerolsun/KekikStream"
|
10
|
+
}
|
11
|
+
|
12
|
+
@api_v1_router.get("")
|
13
|
+
@kekik_cache(ttl=CACHE_TIME, is_fastapi=True)
|
14
|
+
async def get_api_v1_router(request: Request):
|
15
|
+
return api_v1_global_message
|
16
|
+
|
17
|
+
|
18
|
+
# ! ----------------------------------------» Routers
|
19
|
+
from .get_plugin_names import *
|
20
|
+
from .get_plugin import *
|
21
|
+
from .get_main_page import *
|
22
|
+
from .search import *
|
23
|
+
from .load_item import *
|
24
|
+
from .load_links import *
|
25
|
+
from .extract import *
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
2
|
+
|
3
|
+
from . import api_v1_router, api_v1_global_message
|
4
|
+
from Core import Request, JSONResponse, kekik_cache
|
5
|
+
from ..Libs import extractor_manager
|
6
|
+
from Settings import CACHE_TIME
|
7
|
+
|
8
|
+
@api_v1_router.get("/extract")
|
9
|
+
@kekik_cache(ttl=CACHE_TIME, is_fastapi=True)
|
10
|
+
async def extract(request:Request):
|
11
|
+
istek = request.state.req_veri
|
12
|
+
if not istek:
|
13
|
+
return JSONResponse(status_code=410, content={"hata": f"{request.url.path}?_encoded_url=&_encoded_referer="})
|
14
|
+
|
15
|
+
_encoded_url = istek.get("encoded_url")
|
16
|
+
_encoded_referer = istek.get("encoded_referer")
|
17
|
+
if not _encoded_url:
|
18
|
+
return JSONResponse(status_code=410, content={"hata": f"{request.url.path}?_encoded_url=&_encoded_referer="})
|
19
|
+
|
20
|
+
extractor = extractor_manager.find_extractor(_encoded_url)
|
21
|
+
if not extractor:
|
22
|
+
return JSONResponse(status_code=404, content={"hata": "Extractor bulunamadı."})
|
23
|
+
|
24
|
+
result = await extractor.extract(_encoded_url, _encoded_referer)
|
25
|
+
|
26
|
+
return {**api_v1_global_message, "result": result}
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
2
|
+
|
3
|
+
from . import api_v1_router, api_v1_global_message
|
4
|
+
from Core import Request, JSONResponse, kekik_cache
|
5
|
+
from ..Libs import plugin_manager
|
6
|
+
from Settings import CACHE_TIME
|
7
|
+
|
8
|
+
from random import choice
|
9
|
+
from urllib.parse import quote_plus
|
10
|
+
|
11
|
+
@api_v1_router.get("/get_main_page")
|
12
|
+
@kekik_cache(ttl=CACHE_TIME, is_fastapi=True)
|
13
|
+
async def get_main_page(request:Request):
|
14
|
+
istek = request.state.req_veri
|
15
|
+
plugin_names = plugin_manager.get_plugin_names()
|
16
|
+
if not istek:
|
17
|
+
return JSONResponse(status_code=410, content={"hata": f"{request.url.path}?plugin={choice(plugin_names)}&page=1&encoded_url=&encoded_category="})
|
18
|
+
|
19
|
+
_plugin = istek.get("plugin")
|
20
|
+
_plugin = _plugin if _plugin in plugin_names else None
|
21
|
+
_page = istek.get("page")
|
22
|
+
_page = int(_page) if _page.isdigit() else None
|
23
|
+
_encoded_url = istek.get("encoded_url")
|
24
|
+
_encoded_category = istek.get("encoded_category")
|
25
|
+
if not _plugin or not _page or not _encoded_url or not _encoded_category:
|
26
|
+
return JSONResponse(status_code=410, content={"hata": f"{request.url.path}?plugin={_plugin or choice(plugin_names)}&page=1&encoded_url=&encoded_category="})
|
27
|
+
|
28
|
+
plugin = plugin_manager.select_plugin(_plugin)
|
29
|
+
result = await plugin.get_main_page(_page, _encoded_url, _encoded_category)
|
30
|
+
for icerik in result:
|
31
|
+
icerik.url = quote_plus(icerik.url)
|
32
|
+
|
33
|
+
return {**api_v1_global_message, "result": result}
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
2
|
+
|
3
|
+
from . import api_v1_router, api_v1_global_message
|
4
|
+
from Core import Request, JSONResponse, kekik_cache
|
5
|
+
from ..Libs import plugin_manager
|
6
|
+
from Settings import CACHE_TIME
|
7
|
+
|
8
|
+
from random import choice
|
9
|
+
from urllib.parse import quote_plus
|
10
|
+
|
11
|
+
@api_v1_router.get("/get_plugin")
|
12
|
+
@kekik_cache(ttl=CACHE_TIME, is_fastapi=True)
|
13
|
+
async def get_plugin(request:Request):
|
14
|
+
istek = request.state.req_veri
|
15
|
+
plugin_names = plugin_manager.get_plugin_names()
|
16
|
+
if not istek:
|
17
|
+
return JSONResponse(status_code=410, content={"hata": f"{request.url.path}?plugin={choice(plugin_names)}"})
|
18
|
+
|
19
|
+
_plugin = istek.get("plugin")
|
20
|
+
_plugin = _plugin if _plugin in plugin_names else None
|
21
|
+
if not _plugin:
|
22
|
+
return JSONResponse(status_code=410, content={"hata": f"{request.url.path}?plugin={_plugin or choice(plugin_names)}"})
|
23
|
+
|
24
|
+
plugin = plugin_manager.select_plugin(_plugin)
|
25
|
+
|
26
|
+
main_page = {}
|
27
|
+
for url, category in plugin.main_page.items():
|
28
|
+
main_page[quote_plus(url)] = quote_plus(category)
|
29
|
+
|
30
|
+
result = {
|
31
|
+
"name" : plugin.name,
|
32
|
+
"language" : plugin.language,
|
33
|
+
"main_url" : plugin.main_url,
|
34
|
+
"favicon" : plugin.favicon,
|
35
|
+
"description" : plugin.description,
|
36
|
+
"main_page" : main_page
|
37
|
+
}
|
38
|
+
|
39
|
+
return {**api_v1_global_message, "result": result}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
2
|
+
|
3
|
+
from . import api_v1_router, api_v1_global_message
|
4
|
+
from Core import Request, kekik_cache
|
5
|
+
from ..Libs import plugin_manager
|
6
|
+
from Settings import CACHE_TIME
|
7
|
+
|
8
|
+
@api_v1_router.get("/get_plugin_names")
|
9
|
+
@kekik_cache(ttl=CACHE_TIME, is_fastapi=True)
|
10
|
+
async def get_plugin_names(request: Request):
|
11
|
+
plugin_names = plugin_manager.get_plugin_names()
|
12
|
+
|
13
|
+
return {**api_v1_global_message, "result": plugin_names}
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
2
|
+
|
3
|
+
from . import api_v1_router, api_v1_global_message
|
4
|
+
from Core import Request, JSONResponse, kekik_cache
|
5
|
+
from ..Libs import plugin_manager, SeriesInfo
|
6
|
+
from Settings import CACHE_TIME
|
7
|
+
|
8
|
+
from random import choice
|
9
|
+
from urllib.parse import quote_plus
|
10
|
+
|
11
|
+
@api_v1_router.get("/load_item")
|
12
|
+
@kekik_cache(ttl=CACHE_TIME, is_fastapi=True)
|
13
|
+
async def load_item(request:Request):
|
14
|
+
istek = request.state.req_veri
|
15
|
+
plugin_names = plugin_manager.get_plugin_names()
|
16
|
+
if not istek:
|
17
|
+
return JSONResponse(status_code=410, content={"hata": f"{request.url.path}?plugin={choice(plugin_names)}&encoded_url="})
|
18
|
+
|
19
|
+
_plugin = istek.get("plugin")
|
20
|
+
_plugin = _plugin if _plugin in plugin_names else None
|
21
|
+
_encoded_url = istek.get("encoded_url")
|
22
|
+
if not _plugin or not _encoded_url:
|
23
|
+
return JSONResponse(status_code=410, content={"hata": f"{request.url.path}?plugin={_plugin or choice(plugin_names)}&encoded_url="})
|
24
|
+
|
25
|
+
plugin = plugin_manager.select_plugin(_plugin)
|
26
|
+
result = await plugin.load_item(_encoded_url)
|
27
|
+
|
28
|
+
result.url = quote_plus(result.url)
|
29
|
+
|
30
|
+
if isinstance(result, SeriesInfo):
|
31
|
+
for episode in result.episodes:
|
32
|
+
episode.url = quote_plus(episode.url)
|
33
|
+
|
34
|
+
return {**api_v1_global_message, "result": result}
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
2
|
+
|
3
|
+
from . import api_v1_router, api_v1_global_message
|
4
|
+
from Core import Request, JSONResponse, kekik_cache
|
5
|
+
from ..Libs import plugin_manager
|
6
|
+
from Settings import CACHE_TIME
|
7
|
+
|
8
|
+
from random import choice
|
9
|
+
from urllib.parse import quote_plus
|
10
|
+
|
11
|
+
@api_v1_router.get("/load_links")
|
12
|
+
@kekik_cache(ttl=CACHE_TIME, is_fastapi=True)
|
13
|
+
async def load_links(request:Request):
|
14
|
+
istek = request.state.req_veri
|
15
|
+
plugin_names = plugin_manager.get_plugin_names()
|
16
|
+
if not istek:
|
17
|
+
return JSONResponse(status_code=410, content={"hata": f"{request.url.path}?plugin={choice(plugin_names)}&encoded_url="})
|
18
|
+
|
19
|
+
_plugin = istek.get("plugin")
|
20
|
+
_plugin = _plugin if _plugin in plugin_names else None
|
21
|
+
_encoded_url = istek.get("encoded_url")
|
22
|
+
if not _plugin or not _encoded_url:
|
23
|
+
return JSONResponse(status_code=410, content={"hata": f"{request.url.path}?plugin={_plugin or choice(plugin_names)}&encoded_url="})
|
24
|
+
|
25
|
+
plugin = plugin_manager.select_plugin(_plugin)
|
26
|
+
links = await plugin.load_links(_encoded_url)
|
27
|
+
|
28
|
+
if hasattr(plugin, "play") and callable(getattr(plugin, "play", None)):
|
29
|
+
result = []
|
30
|
+
for link in links:
|
31
|
+
data = plugin._data.get(link, {})
|
32
|
+
result.append({
|
33
|
+
"name" : data.get("name"),
|
34
|
+
"url" : link,
|
35
|
+
"referer" : data.get("referer"),
|
36
|
+
"subtitles" : data.get("subtitles")
|
37
|
+
})
|
38
|
+
|
39
|
+
return {**api_v1_global_message, "must_extract": False, "result": result}
|
40
|
+
|
41
|
+
return {**api_v1_global_message, "must_extract": True, "result": [quote_plus(link) for link in links]}
|