KekikStream 2.3.9__py3-none-any.whl → 2.5.3__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.
- KekikStream/Core/Extractor/ExtractorBase.py +3 -2
- KekikStream/Core/Extractor/ExtractorLoader.py +8 -14
- KekikStream/Core/HTMLHelper.py +120 -49
- KekikStream/Core/Plugin/PluginBase.py +30 -12
- KekikStream/Core/Plugin/PluginLoader.py +12 -14
- KekikStream/Core/Plugin/PluginManager.py +2 -2
- KekikStream/Core/Plugin/PluginModels.py +0 -3
- KekikStream/Extractors/Abstream.py +27 -0
- KekikStream/Extractors/CloseLoad.py +30 -54
- KekikStream/Extractors/ContentX.py +27 -72
- KekikStream/Extractors/DonilasPlay.py +33 -77
- KekikStream/Extractors/DzenRu.py +10 -24
- KekikStream/Extractors/ExPlay.py +20 -38
- KekikStream/Extractors/Filemoon.py +21 -46
- KekikStream/Extractors/HDMomPlayer.py +30 -0
- KekikStream/Extractors/HDPlayerSystem.py +13 -31
- KekikStream/Extractors/HotStream.py +27 -0
- KekikStream/Extractors/JFVid.py +3 -24
- KekikStream/Extractors/JetTv.py +21 -34
- KekikStream/Extractors/JetV.py +55 -0
- KekikStream/Extractors/MailRu.py +11 -29
- KekikStream/Extractors/MixPlayHD.py +15 -28
- KekikStream/Extractors/MixTiger.py +17 -40
- KekikStream/Extractors/MolyStream.py +17 -21
- KekikStream/Extractors/Odnoklassniki.py +40 -104
- KekikStream/Extractors/PeaceMakerst.py +18 -45
- KekikStream/Extractors/PixelDrain.py +8 -16
- KekikStream/Extractors/PlayerFilmIzle.py +22 -41
- KekikStream/Extractors/RapidVid.py +21 -35
- KekikStream/Extractors/SetPlay.py +18 -43
- KekikStream/Extractors/SibNet.py +7 -17
- KekikStream/Extractors/Sobreatsesuyp.py +23 -45
- KekikStream/Extractors/TRsTX.py +23 -53
- KekikStream/Extractors/TurboImgz.py +7 -14
- KekikStream/Extractors/VCTPlay.py +10 -28
- KekikStream/Extractors/Veev.py +145 -0
- KekikStream/Extractors/VidBiz.py +62 -0
- KekikStream/Extractors/VidHide.py +58 -30
- KekikStream/Extractors/VidMoly.py +65 -99
- KekikStream/Extractors/VidMoxy.py +16 -27
- KekikStream/Extractors/VidPapi.py +24 -54
- KekikStream/Extractors/VideoSeyred.py +19 -40
- KekikStream/Extractors/Videostr.py +58 -0
- KekikStream/Extractors/Vidoza.py +18 -0
- KekikStream/Extractors/Vtbe.py +38 -0
- KekikStream/Extractors/YTDLP.py +2 -2
- KekikStream/Extractors/YildizKisaFilm.py +13 -31
- KekikStream/Extractors/Zeus.py +61 -0
- KekikStream/Plugins/BelgeselX.py +97 -77
- KekikStream/Plugins/DiziBox.py +28 -45
- KekikStream/Plugins/DiziMom.py +179 -0
- KekikStream/Plugins/DiziPal.py +95 -161
- KekikStream/Plugins/DiziYou.py +51 -147
- KekikStream/Plugins/Dizilla.py +40 -61
- KekikStream/Plugins/FilmBip.py +90 -39
- KekikStream/Plugins/FilmEkseni.py +199 -0
- KekikStream/Plugins/FilmMakinesi.py +72 -73
- KekikStream/Plugins/FilmModu.py +25 -35
- KekikStream/Plugins/Filmatek.py +184 -0
- KekikStream/Plugins/FilmciBaba.py +155 -0
- KekikStream/Plugins/FullHDFilmizlesene.py +16 -37
- KekikStream/Plugins/HDFilm.py +243 -0
- KekikStream/Plugins/HDFilmCehennemi.py +242 -189
- KekikStream/Plugins/JetFilmizle.py +101 -69
- KekikStream/Plugins/KultFilmler.py +138 -104
- KekikStream/Plugins/RecTV.py +52 -73
- KekikStream/Plugins/RoketDizi.py +18 -27
- KekikStream/Plugins/SelcukFlix.py +30 -48
- KekikStream/Plugins/SetFilmIzle.py +76 -104
- KekikStream/Plugins/SezonlukDizi.py +90 -94
- KekikStream/Plugins/Sinefy.py +195 -167
- KekikStream/Plugins/SinemaCX.py +148 -78
- KekikStream/Plugins/Sinezy.py +29 -31
- KekikStream/Plugins/SuperFilmGeldi.py +12 -17
- KekikStream/Plugins/UgurFilm.py +85 -38
- KekikStream/Plugins/Watch32.py +160 -0
- KekikStream/Plugins/YabanciDizi.py +176 -211
- {kekikstream-2.3.9.dist-info → kekikstream-2.5.3.dist-info}/METADATA +1 -1
- kekikstream-2.5.3.dist-info/RECORD +99 -0
- {kekikstream-2.3.9.dist-info → kekikstream-2.5.3.dist-info}/WHEEL +1 -1
- KekikStream/Plugins/FullHDFilm.py +0 -249
- kekikstream-2.3.9.dist-info/RECORD +0 -84
- {kekikstream-2.3.9.dist-info → kekikstream-2.5.3.dist-info}/entry_points.txt +0 -0
- {kekikstream-2.3.9.dist-info → kekikstream-2.5.3.dist-info}/licenses/LICENSE +0 -0
- {kekikstream-2.3.9.dist-info → kekikstream-2.5.3.dist-info}/top_level.txt +0 -0
|
@@ -19,81 +19,36 @@ class ContentX(ExtractorBase):
|
|
|
19
19
|
def can_handle_url(self, url: str) -> bool:
|
|
20
20
|
return any(domain in url for domain in self.supported_domains)
|
|
21
21
|
|
|
22
|
-
async def extract(self, url, referer=None) -> list[ExtractResult]:
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
async def extract(self, url: str, referer: str = None) -> list[ExtractResult] | ExtractResult:
|
|
23
|
+
ref = referer or self.get_base_url(url)
|
|
24
|
+
self.httpx.headers.update({"Referer": ref})
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
resp = await self.httpx.get(url)
|
|
27
|
+
sel = HTMLHelper(resp.text)
|
|
28
28
|
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
i_extract_value = HTMLHelper(i_source).regex_first(r"window\.openPlayer\('([^']+)'")
|
|
34
|
-
if not i_extract_value:
|
|
35
|
-
raise ValueError("i_extract is null")
|
|
29
|
+
v_id = sel.regex_first(r"window\.openPlayer\('([^']+)'")
|
|
30
|
+
if not v_id:
|
|
31
|
+
raise ValueError(f"ContentX: ID bulunamadı. {url}")
|
|
36
32
|
|
|
37
33
|
subtitles = []
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
)
|
|
58
|
-
|
|
59
|
-
# base_url kullan (contentx.me yerine)
|
|
60
|
-
vid_source_request = await self.httpx.get(f"{base_url}/source2.php?v={i_extract_value}", headers={"Referer": referer or base_url})
|
|
61
|
-
vid_source_request.raise_for_status()
|
|
62
|
-
|
|
63
|
-
vid_source = vid_source_request.text
|
|
64
|
-
m3u_link = HTMLHelper(vid_source).regex_first(r'file":"([^\"]+)"')
|
|
65
|
-
if not m3u_link:
|
|
66
|
-
raise ValueError("vidExtract is null")
|
|
67
|
-
|
|
68
|
-
m3u_link = m3u_link.replace("\\", "").replace("/m.php", "/master.m3u8")
|
|
69
|
-
results = [
|
|
70
|
-
ExtractResult(
|
|
71
|
-
name = self.name,
|
|
72
|
-
url = m3u_link,
|
|
73
|
-
referer = url,
|
|
74
|
-
subtitles = subtitles
|
|
75
|
-
)
|
|
76
|
-
]
|
|
77
|
-
|
|
78
|
-
dublaj_value = HTMLHelper(i_source).regex_first(r'["\']([^"\']+)["\'],["\']Türkçe["\']')
|
|
79
|
-
if dublaj_value:
|
|
80
|
-
try:
|
|
81
|
-
dublaj_source_request = await self.httpx.get(f"{base_url}/source2.php?v={dublaj_value}", headers={"Referer": referer or base_url})
|
|
82
|
-
dublaj_source_request.raise_for_status()
|
|
83
|
-
|
|
84
|
-
dublaj_source = dublaj_source_request.text
|
|
85
|
-
dublaj_link = HTMLHelper(dublaj_source).regex_first(r'file":"([^\"]+)"')
|
|
86
|
-
if dublaj_link:
|
|
87
|
-
dublaj_link = dublaj_link.replace("\\", "")
|
|
88
|
-
results.append(
|
|
89
|
-
ExtractResult(
|
|
90
|
-
name = f"{self.name} Türkçe Dublaj",
|
|
91
|
-
url = dublaj_link,
|
|
92
|
-
referer = url,
|
|
93
|
-
subtitles = []
|
|
94
|
-
)
|
|
95
|
-
)
|
|
96
|
-
except Exception:
|
|
97
|
-
pass
|
|
34
|
+
for s_url, s_lang in sel.regex_all(r'"file":"([^\"]+)","label":"([^\"]+)"'):
|
|
35
|
+
decoded_lang = s_lang.encode().decode('unicode_escape')
|
|
36
|
+
subtitles.append(Subtitle(name=decoded_lang, url=self.fix_url(s_url.replace("\\", ""))))
|
|
37
|
+
|
|
38
|
+
results = []
|
|
39
|
+
# Base m3u8
|
|
40
|
+
vid_resp = await self.httpx.get(f"{self.get_base_url(url)}/source2.php?v={v_id}", headers={"Referer": url})
|
|
41
|
+
if m3u8_link := HTMLHelper(vid_resp.text).regex_first(r'file":"([^\"]+)"'):
|
|
42
|
+
m3u8_link = m3u8_link.replace("\\", "").replace("/m.php", "/master.m3u8")
|
|
43
|
+
results.append(ExtractResult(name=self.name, url=m3u8_link, referer=url, subtitles=subtitles))
|
|
44
|
+
|
|
45
|
+
# Dublaj Kontrolü
|
|
46
|
+
if dub_id := sel.regex_first(r'["\']([^"\']+)["\'],["\']Türkçe["\']'):
|
|
47
|
+
dub_resp = await self.httpx.get(f"{self.get_base_url(url)}/source2.php?v={dub_id}", headers={"Referer": url})
|
|
48
|
+
if dub_link := HTMLHelper(dub_resp.text).regex_first(r'file":"([^\"]+)"'):
|
|
49
|
+
results.append(ExtractResult(name=f"{self.name} Türkçe Dublaj", url=dub_link.replace("\\", ""), referer=url))
|
|
50
|
+
|
|
51
|
+
if not results:
|
|
52
|
+
raise ValueError(f"ContentX: Video linki bulunamadı. {url}")
|
|
98
53
|
|
|
99
54
|
return results[0] if len(results) == 1 else results
|
|
@@ -2,85 +2,41 @@
|
|
|
2
2
|
|
|
3
3
|
from KekikStream.Core import ExtractorBase, ExtractResult, Subtitle, HTMLHelper
|
|
4
4
|
from Kekik.Sifreleme import AESManager
|
|
5
|
-
import json
|
|
5
|
+
import json, contextlib
|
|
6
6
|
|
|
7
7
|
class DonilasPlay(ExtractorBase):
|
|
8
8
|
name = "DonilasPlay"
|
|
9
9
|
main_url = "https://donilasplay.com"
|
|
10
10
|
|
|
11
|
-
async def extract(self, url, referer=None) -> ExtractResult:
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
continue
|
|
44
|
-
if file:
|
|
45
|
-
# Türkçe kontrolü
|
|
46
|
-
keywords = ["tur", "tr", "türkçe", "turkce"]
|
|
47
|
-
language = "Turkish" if any(k in label.lower() for k in keywords) else label
|
|
48
|
-
subtitles.append(Subtitle(
|
|
49
|
-
name = language,
|
|
50
|
-
url = self.fix_url(file)
|
|
51
|
-
))
|
|
52
|
-
except Exception:
|
|
53
|
-
pass
|
|
54
|
-
|
|
55
|
-
# Fallback: file pattern
|
|
56
|
-
if not m3u_link:
|
|
57
|
-
file_match = hp.regex_first(r'file:"([^"]+)"')
|
|
58
|
-
if file_match:
|
|
59
|
-
m3u_link = file_match
|
|
60
|
-
|
|
61
|
-
# tracks pattern for subtitles
|
|
62
|
-
tracks_match = hp.regex_first(r'tracks:\[([^\]]+)')
|
|
63
|
-
if tracks_match:
|
|
64
|
-
try:
|
|
65
|
-
tracks_str = f"[{tracks_match}]"
|
|
66
|
-
tracks = json.loads(tracks_str)
|
|
67
|
-
for track in tracks:
|
|
68
|
-
file_url = track.get("file")
|
|
69
|
-
label = track.get("label", "")
|
|
70
|
-
if file_url and "Forced" not in label:
|
|
71
|
-
subtitles.append(Subtitle(
|
|
72
|
-
name = label,
|
|
73
|
-
url = self.fix_url(file_url)
|
|
74
|
-
))
|
|
75
|
-
except Exception:
|
|
76
|
-
pass
|
|
77
|
-
|
|
78
|
-
if not m3u_link:
|
|
79
|
-
raise ValueError("m3u link not found")
|
|
80
|
-
|
|
81
|
-
return ExtractResult(
|
|
82
|
-
name = self.name,
|
|
83
|
-
url = m3u_link,
|
|
84
|
-
referer = url,
|
|
85
|
-
subtitles = subtitles
|
|
86
|
-
)
|
|
11
|
+
async def extract(self, url: str, referer: str = None) -> ExtractResult:
|
|
12
|
+
self.httpx.headers.update({"Referer": referer or url})
|
|
13
|
+
|
|
14
|
+
resp = await self.httpx.get(url)
|
|
15
|
+
sel = HTMLHelper(resp.text)
|
|
16
|
+
|
|
17
|
+
m3u8_url = None
|
|
18
|
+
subtitles = []
|
|
19
|
+
|
|
20
|
+
# 1. bePlayer (AES)
|
|
21
|
+
if be_match := sel.regex_first(r"bePlayer\('([^']+)',\s*'(\{[^}]+\})'\);", group=None):
|
|
22
|
+
pass_val, data_val = be_match
|
|
23
|
+
with contextlib.suppress(Exception):
|
|
24
|
+
data = json.loads(AESManager.decrypt(data_val, pass_val))
|
|
25
|
+
m3u8_url = data.get("video_location")
|
|
26
|
+
for sub in data.get("strSubtitles", []):
|
|
27
|
+
if "Forced" not in sub.get("label", ""):
|
|
28
|
+
subtitles.append(Subtitle(name=sub.get("label"), url=self.fix_url(sub.get("file"))))
|
|
29
|
+
|
|
30
|
+
# 2. Fallback
|
|
31
|
+
if not m3u8_url:
|
|
32
|
+
m3u8_url = sel.regex_first(r'file:"([^"]+)"')
|
|
33
|
+
if tracks_match := sel.regex_first(r'tracks:\[([^\]]+)'):
|
|
34
|
+
with contextlib.suppress(Exception):
|
|
35
|
+
for track in json.loads(f"[{tracks_match}]"):
|
|
36
|
+
if "Forced" not in track.get("label", ""):
|
|
37
|
+
subtitles.append(Subtitle(name=track.get("label"), url=self.fix_url(track.get("file"))))
|
|
38
|
+
|
|
39
|
+
if not m3u8_url:
|
|
40
|
+
raise ValueError(f"DonilasPlay: Video linki bulunamadı. {url}")
|
|
41
|
+
|
|
42
|
+
return ExtractResult(name=self.name, url=m3u8_url, referer=url, subtitles=subtitles)
|
KekikStream/Extractors/DzenRu.py
CHANGED
|
@@ -6,33 +6,19 @@ class DzenRu(ExtractorBase):
|
|
|
6
6
|
name = "DzenRu"
|
|
7
7
|
main_url = "https://dzen.ru"
|
|
8
8
|
|
|
9
|
-
async def extract(self, url, referer=None) -> ExtractResult:
|
|
9
|
+
async def extract(self, url: str, referer: str = None) -> ExtractResult:
|
|
10
10
|
video_key = url.split("/")[-1]
|
|
11
|
-
|
|
11
|
+
v_url = f"{self.main_url}/embed/{video_key}"
|
|
12
12
|
|
|
13
13
|
if referer:
|
|
14
14
|
self.httpx.headers.update({"Referer": referer})
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
16
|
+
resp = await self.httpx.get(v_url)
|
|
17
|
+
sel = HTMLHelper(resp.text)
|
|
18
|
+
|
|
19
|
+
# Benzersiz okcdn.ru linklerini bul ve en yüksek kaliteyi (genelde sonuncu) seç
|
|
20
|
+
links = sel.regex_all(r'https://vd\d+\.okcdn\.ru/\?[^"\'\\\s]+')
|
|
21
|
+
if not links:
|
|
22
|
+
raise ValueError(f"DzenRu: Video linki bulunamadı. {url}")
|
|
18
23
|
|
|
19
|
-
|
|
20
|
-
hp = HTMLHelper(istek.text)
|
|
21
|
-
matches = hp.regex_all(r'https://vd\d+\.okcdn\.ru/\?[^"\'\\\s]+')
|
|
22
|
-
|
|
23
|
-
if not matches:
|
|
24
|
-
raise ValueError("DzenRu video link not found")
|
|
25
|
-
|
|
26
|
-
# Benzersiz linkleri al, son kaliteyi kullan
|
|
27
|
-
unique_links = list(set(matches))
|
|
28
|
-
best_link = unique_links[-1] if unique_links else None
|
|
29
|
-
|
|
30
|
-
if not best_link:
|
|
31
|
-
raise ValueError("No valid video URL found")
|
|
32
|
-
|
|
33
|
-
return ExtractResult(
|
|
34
|
-
name = self.name,
|
|
35
|
-
url = best_link,
|
|
36
|
-
referer = self.main_url,
|
|
37
|
-
subtitles = []
|
|
38
|
-
)
|
|
24
|
+
return ExtractResult(name=self.name, url=list(set(links))[-1], referer=self.main_url)
|
KekikStream/Extractors/ExPlay.py
CHANGED
|
@@ -1,53 +1,35 @@
|
|
|
1
1
|
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
2
|
|
|
3
|
-
from KekikStream.Core import ExtractorBase, ExtractResult,
|
|
3
|
+
from KekikStream.Core import ExtractorBase, ExtractResult, HTMLHelper
|
|
4
4
|
from urllib.parse import urlparse, parse_qs
|
|
5
5
|
|
|
6
6
|
class ExPlay(ExtractorBase):
|
|
7
7
|
name = "ExPlay"
|
|
8
8
|
main_url = "https://explay.store"
|
|
9
9
|
|
|
10
|
-
async def extract(self, url, referer=None) -> ExtractResult:
|
|
11
|
-
|
|
10
|
+
async def extract(self, url: str, referer: str = None) -> ExtractResult:
|
|
11
|
+
self.httpx.headers.update({"Referer": referer or url})
|
|
12
12
|
|
|
13
|
-
# URL
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
clean_url = url.split("?partKey=")[0]
|
|
18
|
-
|
|
19
|
-
if referer:
|
|
20
|
-
self.httpx.headers.update({"Referer": referer})
|
|
21
|
-
|
|
22
|
-
istek = await self.httpx.get(clean_url)
|
|
23
|
-
istek.raise_for_status()
|
|
24
|
-
|
|
25
|
-
hp = HTMLHelper(istek.text)
|
|
13
|
+
# Clean URL from partKey for initial request
|
|
14
|
+
clean_url = url.split("?")[0]
|
|
15
|
+
resp = await self.httpx.get(clean_url)
|
|
16
|
+
sel = HTMLHelper(resp.text)
|
|
26
17
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
if not
|
|
30
|
-
raise ValueError("
|
|
31
|
-
video_url = video_url.replace("\\", "")
|
|
18
|
+
v_url = sel.regex_first(r'videoUrl":"([^",]+)"')
|
|
19
|
+
v_srv = sel.regex_first(r'videoServer":"([^",]+)"')
|
|
20
|
+
if not v_url or not v_srv:
|
|
21
|
+
raise ValueError(f"ExPlay: Video url/server bulunamadı. {url}")
|
|
32
22
|
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
if not video_server:
|
|
36
|
-
raise ValueError("videoServer not found")
|
|
37
|
-
|
|
38
|
-
# title çıkar
|
|
39
|
-
title = hp.regex_first(r'title":"([^",]+)"')
|
|
40
|
-
title = title.split(".")[-1] if title else "Unknown"
|
|
23
|
+
params = parse_qs(urlparse(url).query)
|
|
24
|
+
part_key = params.get("partKey", [""])[0]
|
|
41
25
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
m3u_link = f"{self.main_url}{video_url}?s={video_server}"
|
|
26
|
+
suffix = part_key or "Bilinmiyor"
|
|
27
|
+
if not part_key:
|
|
28
|
+
title = sel.regex_first(r'title":"([^",]+)"')
|
|
29
|
+
if title: suffix = title.split(".")[-1]
|
|
47
30
|
|
|
48
31
|
return ExtractResult(
|
|
49
|
-
name
|
|
50
|
-
url
|
|
51
|
-
referer
|
|
52
|
-
subtitles = []
|
|
32
|
+
name = f"{self.name} - {suffix}",
|
|
33
|
+
url = f"{self.main_url}{v_url.replace('\\', '')}?s={v_srv}",
|
|
34
|
+
referer = clean_url
|
|
53
35
|
)
|
|
@@ -13,7 +13,8 @@ class Filemoon(ExtractorBase):
|
|
|
13
13
|
"filemoon.in",
|
|
14
14
|
"filemoon.sx",
|
|
15
15
|
"filemoon.nl",
|
|
16
|
-
"filemoon.com"
|
|
16
|
+
"filemoon.com",
|
|
17
|
+
"bysejikuar.com"
|
|
17
18
|
]
|
|
18
19
|
|
|
19
20
|
def can_handle_url(self, url: str) -> bool:
|
|
@@ -30,60 +31,34 @@ class Filemoon(ExtractorBase):
|
|
|
30
31
|
self.httpx.headers.update(default_headers)
|
|
31
32
|
|
|
32
33
|
# İlk sayfayı al
|
|
33
|
-
istek
|
|
34
|
-
|
|
35
|
-
secici = HTMLHelper(response)
|
|
34
|
+
istek = await self.httpx.get(url)
|
|
35
|
+
secici = HTMLHelper(istek.text)
|
|
36
36
|
|
|
37
37
|
# Eğer iframe varsa, iframe'e git
|
|
38
38
|
iframe_src = secici.select_attr("iframe", "src")
|
|
39
|
+
m3u8_url = None
|
|
39
40
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
if script_data:
|
|
51
|
-
unpacked = Packer.unpack(script_data)
|
|
52
|
-
unpacked_sec = HTMLHelper(unpacked)
|
|
53
|
-
m3u8_url = unpacked_sec.regex_first(r'sources:\[\{file:"(.*?)"')
|
|
54
|
-
else:
|
|
55
|
-
# Iframe varsa devam et
|
|
56
|
-
iframe_url = self.fix_url(iframe_src)
|
|
57
|
-
iframe_headers = default_headers.copy()
|
|
58
|
-
iframe_headers["Accept-Language"] = "en-US,en;q=0.5"
|
|
59
|
-
|
|
60
|
-
istek = await self.httpx.get(iframe_url, headers=iframe_headers)
|
|
61
|
-
response = istek.text
|
|
62
|
-
secici = HTMLHelper(response)
|
|
63
|
-
|
|
64
|
-
script_data = ""
|
|
65
|
-
for script in secici.select("script"):
|
|
66
|
-
if "function(p,a,c,k,e,d)" in script.text():
|
|
67
|
-
script_data = script.text()
|
|
68
|
-
break
|
|
69
|
-
|
|
70
|
-
if script_data:
|
|
71
|
-
unpacked = Packer.unpack(script_data)
|
|
72
|
-
unpacked_sec = HTMLHelper(unpacked)
|
|
73
|
-
m3u8_url = unpacked_sec.regex_first(r'sources:\[\{file:"(.*?)"')
|
|
41
|
+
if iframe_src:
|
|
42
|
+
url = self.fix_url(iframe_src)
|
|
43
|
+
istek = await self.httpx.get(url)
|
|
44
|
+
secici = HTMLHelper(istek.text)
|
|
45
|
+
|
|
46
|
+
# script p,a,c,k,e,d içinde ara
|
|
47
|
+
script_data = secici.regex_first(r"(eval\(function\(p,a,c,k,e,d\).+?)\s*</script>")
|
|
48
|
+
if script_data:
|
|
49
|
+
unpacked = Packer.unpack(script_data)
|
|
50
|
+
m3u8_url = HTMLHelper(unpacked).regex_first(r'sources:\[\{file:"(.*?)"')
|
|
74
51
|
|
|
75
52
|
if not m3u8_url:
|
|
76
|
-
#
|
|
77
|
-
|
|
78
|
-
m3u8_url = resp_sec.regex_first(r'sources:\s*\[\s*\{\s*file:\s*"([^"]+)"') or resp_sec.regex_first(r'file:\s*"([^\"]*?\.m3u8[^"]*)"')
|
|
53
|
+
# Fallback
|
|
54
|
+
m3u8_url = secici.regex_first(r'sources:\s*\[\s*\{\s*file:\s*"([^"]+)"') or secici.regex_first(r'file:\s*"([^\"]*?\.m3u8[^"]*)"')
|
|
79
55
|
|
|
80
56
|
if not m3u8_url:
|
|
81
57
|
raise ValueError(f"Filemoon: Video URL bulunamadı. {url}")
|
|
82
58
|
|
|
83
59
|
return ExtractResult(
|
|
84
|
-
name
|
|
85
|
-
url
|
|
86
|
-
referer
|
|
87
|
-
user_agent = default_headers["User-Agent"]
|
|
88
|
-
subtitles = []
|
|
60
|
+
name = self.name,
|
|
61
|
+
url = self.fix_url(m3u8_url),
|
|
62
|
+
referer = f"{self.get_base_url(url)}/",
|
|
63
|
+
user_agent = default_headers["User-Agent"]
|
|
89
64
|
)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
|
+
|
|
3
|
+
from KekikStream.Core import ExtractorBase, ExtractResult, HTMLHelper
|
|
4
|
+
from Kekik.Sifreleme import AESManager
|
|
5
|
+
import contextlib, json
|
|
6
|
+
|
|
7
|
+
class HDMomPlayer(ExtractorBase):
|
|
8
|
+
name = "HDMomPlayer"
|
|
9
|
+
main_url = "https://hdmomplayer.com"
|
|
10
|
+
|
|
11
|
+
async def extract(self, url: str, referer: str = None) -> ExtractResult:
|
|
12
|
+
self.httpx.headers.update({"Referer": referer or url})
|
|
13
|
+
|
|
14
|
+
resp = await self.httpx.get(url)
|
|
15
|
+
sel = HTMLHelper(resp.text)
|
|
16
|
+
|
|
17
|
+
m3u8_url = None
|
|
18
|
+
if match := sel.regex_first(r"bePlayer\('([^']+)',\s*'(\{[^\}]+\})'\);", group=None):
|
|
19
|
+
pass_val, data_val = match
|
|
20
|
+
with contextlib.suppress(Exception):
|
|
21
|
+
decrypted = AESManager.decrypt(data_val, pass_val)
|
|
22
|
+
m3u8_url = HTMLHelper(decrypted).regex_first(r'video_location":"([^"]+)"')
|
|
23
|
+
|
|
24
|
+
if not m3u8_url:
|
|
25
|
+
m3u8_url = sel.regex_first(r'file:"([^"]+)"')
|
|
26
|
+
|
|
27
|
+
if not m3u8_url:
|
|
28
|
+
raise ValueError(f"HDMomPlayer: Video linki bulunamadı. {url}")
|
|
29
|
+
|
|
30
|
+
return ExtractResult(name=self.name, url=self.fix_url(m3u8_url), referer=url)
|
|
@@ -6,36 +6,18 @@ class HDPlayerSystem(ExtractorBase):
|
|
|
6
6
|
name = "HDPlayerSystem"
|
|
7
7
|
main_url = "https://hdplayersystem.com"
|
|
8
8
|
|
|
9
|
-
async def extract(self, url, referer=None) -> ExtractResult:
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
post_url = f"{self.main_url}/player/index.php?data={vid_id}&do=getVideo"
|
|
18
|
-
|
|
19
|
-
response = await self.httpx.post(
|
|
20
|
-
url = post_url,
|
|
21
|
-
data = {"hash": vid_id, "r": ext_ref},
|
|
22
|
-
headers = {
|
|
23
|
-
"Referer" : ext_ref,
|
|
24
|
-
"Content-Type" : "application/x-www-form-urlencoded; charset=UTF-8",
|
|
25
|
-
"X-Requested-With" : "XMLHttpRequest"
|
|
26
|
-
}
|
|
9
|
+
async def extract(self, url: str, referer: str = None) -> ExtractResult:
|
|
10
|
+
ref = referer or self.main_url
|
|
11
|
+
v_id = url.split("video/")[-1] if "video/" in url else url.split("?data=")[-1]
|
|
12
|
+
|
|
13
|
+
resp = await self.httpx.post(
|
|
14
|
+
f"{self.main_url}/player/index.php?data={v_id}&do=getVideo",
|
|
15
|
+
data = {"hash": v_id, "r": ref},
|
|
16
|
+
headers = {"Referer": ref, "X-Requested-With": "XMLHttpRequest"}
|
|
27
17
|
)
|
|
28
|
-
|
|
18
|
+
|
|
19
|
+
m3u8_url = resp.json().get("securedLink")
|
|
20
|
+
if not m3u8_url:
|
|
21
|
+
raise ValueError(f"HDPlayerSystem: Video URL bulunamadı. {url}")
|
|
29
22
|
|
|
30
|
-
|
|
31
|
-
m3u_link = video_data.get("securedLink")
|
|
32
|
-
|
|
33
|
-
if not m3u_link:
|
|
34
|
-
raise ValueError("securedLink not found in response")
|
|
35
|
-
|
|
36
|
-
return ExtractResult(
|
|
37
|
-
name = self.name,
|
|
38
|
-
url = m3u_link,
|
|
39
|
-
referer = url,
|
|
40
|
-
subtitles = []
|
|
41
|
-
)
|
|
23
|
+
return ExtractResult(name=self.name, url=m3u8_url, referer=url)
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
|
+
|
|
3
|
+
from KekikStream.Core import ExtractorBase, ExtractResult, HTMLHelper
|
|
4
|
+
from Kekik.Sifreleme import AESManager
|
|
5
|
+
import contextlib
|
|
6
|
+
|
|
7
|
+
class HotStream(ExtractorBase):
|
|
8
|
+
name = "HotStream"
|
|
9
|
+
main_url = "https://hotstream.club"
|
|
10
|
+
|
|
11
|
+
async def extract(self, url: str, referer: str = None) -> ExtractResult:
|
|
12
|
+
self.httpx.headers.update({"Referer": referer or url})
|
|
13
|
+
|
|
14
|
+
resp = await self.httpx.get(url)
|
|
15
|
+
sel = HTMLHelper(resp.text)
|
|
16
|
+
|
|
17
|
+
m3u8_url = None
|
|
18
|
+
if match := sel.regex_first(r"bePlayer\('([^']+)',\s*'(\{[^']+\})'\)", group=None):
|
|
19
|
+
pass_val, data_val = match
|
|
20
|
+
with contextlib.suppress(Exception):
|
|
21
|
+
decrypted = AESManager.decrypt(data_val, pass_val)
|
|
22
|
+
m3u8_url = HTMLHelper(decrypted).regex_first(r'"video_location":"([^"]+)"')
|
|
23
|
+
|
|
24
|
+
if not m3u8_url:
|
|
25
|
+
raise ValueError(f"HotStream: Video linki bulunamadı. {url}")
|
|
26
|
+
|
|
27
|
+
return ExtractResult(name=self.name, url=self.fix_url(m3u8_url), referer=url)
|
KekikStream/Extractors/JFVid.py
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
2
|
|
|
3
3
|
from KekikStream.Core import ExtractorBase, ExtractResult
|
|
4
|
-
import re
|
|
5
4
|
|
|
6
5
|
class JFVid(ExtractorBase):
|
|
7
6
|
name = "JFVid"
|
|
@@ -14,27 +13,7 @@ class JFVid(ExtractorBase):
|
|
|
14
13
|
return any(domain in url for domain in self.supported_domains)
|
|
15
14
|
|
|
16
15
|
async def extract(self, url: str, referer: str = None) -> ExtractResult:
|
|
17
|
-
# Dinamik base URL kullan
|
|
18
16
|
base_url = self.get_base_url(url)
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
# /play/ endpoint'inden encodedId'yi al
|
|
24
|
-
# URL format: https://xxx.jfvid.com/play/{encodedId}
|
|
25
|
-
if "/play/" in url:
|
|
26
|
-
encoded_id = url.split("/play/")[-1]
|
|
27
|
-
stream_url = f"{base_url}/stream/{encoded_id}"
|
|
28
|
-
elif "/stream/" in url:
|
|
29
|
-
# Zaten stream URL ise doğrudan kullan
|
|
30
|
-
stream_url = url
|
|
31
|
-
else:
|
|
32
|
-
raise ValueError(f"JFVid: Desteklenmeyen URL formatı. {url}")
|
|
33
|
-
|
|
34
|
-
# Stream endpoint'i direkt m3u8 master playlist döndürür
|
|
35
|
-
return ExtractResult(
|
|
36
|
-
name = self.name,
|
|
37
|
-
url = stream_url,
|
|
38
|
-
referer = referer,
|
|
39
|
-
subtitles = []
|
|
40
|
-
)
|
|
17
|
+
v_id = url.split("/play/")[-1] if "/play/" in url else url.split("/stream/")[-1]
|
|
18
|
+
|
|
19
|
+
return ExtractResult(name=self.name, url=f"{base_url}/stream/{v_id}", referer=referer or base_url)
|