KekikStream 1.7.2__py3-none-any.whl → 1.7.5__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 +23 -6
- KekikStream/Core/Plugin/PluginBase.py +29 -8
- KekikStream/Extractors/CloseLoad.py +2 -2
- KekikStream/Extractors/ContentX.py +4 -4
- KekikStream/Extractors/DzenRu.py +39 -0
- KekikStream/Extractors/ExPlay.py +54 -0
- KekikStream/Extractors/FirePlayer.py +61 -0
- KekikStream/Extractors/HDPlayerSystem.py +42 -0
- KekikStream/Extractors/JetTv.py +46 -0
- KekikStream/Extractors/MailRu.py +2 -2
- KekikStream/Extractors/MixPlayHD.py +2 -2
- KekikStream/Extractors/MixTiger.py +61 -0
- KekikStream/Extractors/Odnoklassniki.py +2 -2
- KekikStream/Extractors/PeaceMakerst.py +4 -4
- KekikStream/Extractors/PixelDrain.py +1 -1
- KekikStream/Extractors/PlayerFilmIzle.py +62 -0
- KekikStream/Extractors/RapidVid.py +2 -2
- KekikStream/Extractors/SetPlay.py +58 -0
- KekikStream/Extractors/SetPrime.py +46 -0
- KekikStream/Extractors/SibNet.py +2 -2
- KekikStream/Extractors/Sobreatsesuyp.py +4 -4
- KekikStream/Extractors/TRsTX.py +4 -4
- KekikStream/Extractors/TauVideo.py +2 -2
- KekikStream/Extractors/TurboImgz.py +2 -2
- KekikStream/Extractors/TurkeyPlayer.py +34 -0
- KekikStream/Extractors/VidHide.py +72 -0
- KekikStream/Extractors/VidMoly.py +4 -4
- KekikStream/Extractors/VidMoxy.py +2 -2
- KekikStream/Extractors/VidPapi.py +90 -0
- KekikStream/Extractors/VideoSeyred.py +3 -3
- KekikStream/Extractors/YildizKisaFilm.py +42 -0
- KekikStream/Plugins/DiziBox.py +15 -15
- KekikStream/Plugins/DiziPal.py +11 -11
- KekikStream/Plugins/DiziYou.py +4 -4
- KekikStream/Plugins/Dizilla.py +10 -6
- KekikStream/Plugins/FilmBip.py +145 -0
- KekikStream/Plugins/FilmMakinesi.py +3 -3
- KekikStream/Plugins/FilmModu.py +6 -6
- KekikStream/Plugins/FullHDFilm.py +164 -0
- KekikStream/Plugins/FullHDFilmizlesene.py +3 -3
- KekikStream/Plugins/HDFilmCehennemi.py +3 -0
- KekikStream/Plugins/JetFilmizle.py +16 -9
- KekikStream/Plugins/KultFilmler.py +219 -0
- KekikStream/Plugins/RecTV.py +6 -6
- KekikStream/Plugins/RoketDizi.py +207 -0
- KekikStream/Plugins/SelcukFlix.py +216 -0
- KekikStream/Plugins/SezonlukDizi.py +11 -8
- KekikStream/Plugins/SineWix.py +4 -4
- KekikStream/Plugins/Sinefy.py +214 -0
- KekikStream/Plugins/SinemaCX.py +9 -9
- KekikStream/Plugins/Sinezy.py +99 -0
- KekikStream/Plugins/SuperFilmGeldi.py +121 -0
- KekikStream/Plugins/UgurFilm.py +6 -6
- KekikStream/requirements.txt +2 -2
- {kekikstream-1.7.2.dist-info → kekikstream-1.7.5.dist-info}/METADATA +2 -1
- kekikstream-1.7.5.dist-info/RECORD +85 -0
- kekikstream-1.7.2.dist-info/RECORD +0 -64
- {kekikstream-1.7.2.dist-info → kekikstream-1.7.5.dist-info}/WHEEL +0 -0
- {kekikstream-1.7.2.dist-info → kekikstream-1.7.5.dist-info}/entry_points.txt +0 -0
- {kekikstream-1.7.2.dist-info → kekikstream-1.7.5.dist-info}/licenses/LICENSE +0 -0
- {kekikstream-1.7.2.dist-info → kekikstream-1.7.5.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
|
+
|
|
3
|
+
from KekikStream.Core import ExtractorBase, ExtractResult
|
|
4
|
+
import re
|
|
5
|
+
|
|
6
|
+
class SetPlay(ExtractorBase):
|
|
7
|
+
name = "SetPlay"
|
|
8
|
+
main_url = "https://setplay.cfd"
|
|
9
|
+
|
|
10
|
+
async def extract(self, url, referer=None) -> ExtractResult:
|
|
11
|
+
ext_ref = referer or ""
|
|
12
|
+
|
|
13
|
+
if referer:
|
|
14
|
+
self.httpx.headers.update({"Referer": referer})
|
|
15
|
+
|
|
16
|
+
istek = await self.httpx.get(url)
|
|
17
|
+
istek.raise_for_status()
|
|
18
|
+
|
|
19
|
+
# videoUrl çıkar
|
|
20
|
+
video_url_match = re.search(r'videoUrl":"([^",]+)"', istek.text)
|
|
21
|
+
if not video_url_match:
|
|
22
|
+
raise ValueError("videoUrl not found")
|
|
23
|
+
video_url = video_url_match[1].replace("\\", "")
|
|
24
|
+
|
|
25
|
+
# videoServer çıkar
|
|
26
|
+
video_server_match = re.search(r'videoServer":"([^",]+)"', istek.text)
|
|
27
|
+
if not video_server_match:
|
|
28
|
+
raise ValueError("videoServer not found")
|
|
29
|
+
video_server = video_server_match[1]
|
|
30
|
+
|
|
31
|
+
# title çıkar (opsiyonel)
|
|
32
|
+
title_match = re.search(r'title":"([^",]+)"', istek.text)
|
|
33
|
+
title_base = title_match[1].split(".")[-1] if title_match else "Unknown"
|
|
34
|
+
|
|
35
|
+
# partKey logic
|
|
36
|
+
from urllib.parse import urlparse, parse_qs
|
|
37
|
+
parsed = urlparse(url)
|
|
38
|
+
params = parse_qs(parsed.query)
|
|
39
|
+
part_key = params.get("partKey", [""])[0]
|
|
40
|
+
|
|
41
|
+
name_suffix = ""
|
|
42
|
+
if "turkcedublaj" in part_key.lower():
|
|
43
|
+
name_suffix = "Dublaj"
|
|
44
|
+
elif "turkcealtyazi" in part_key.lower():
|
|
45
|
+
name_suffix = "Altyazı"
|
|
46
|
+
else:
|
|
47
|
+
name_suffix = title_base
|
|
48
|
+
|
|
49
|
+
# M3U8 link oluştur
|
|
50
|
+
m3u_link = f"{self.main_url}{video_url}?s={video_server}"
|
|
51
|
+
|
|
52
|
+
return ExtractResult(
|
|
53
|
+
name = f"{self.name} - {name_suffix}",
|
|
54
|
+
url = m3u_link,
|
|
55
|
+
referer = url,
|
|
56
|
+
headers = {},
|
|
57
|
+
subtitles = []
|
|
58
|
+
)
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
|
+
|
|
3
|
+
from KekikStream.Core import ExtractorBase, ExtractResult
|
|
4
|
+
from urllib.parse import urlparse, parse_qs
|
|
5
|
+
import re
|
|
6
|
+
|
|
7
|
+
class SetPrime(ExtractorBase):
|
|
8
|
+
name = "SetPrime"
|
|
9
|
+
main_url = "https://setplay.site"
|
|
10
|
+
|
|
11
|
+
async def extract(self, url, referer=None) -> ExtractResult:
|
|
12
|
+
# URL parsing
|
|
13
|
+
parsed = urlparse(url)
|
|
14
|
+
params = parse_qs(parsed.query)
|
|
15
|
+
part_key = params.get("partKey", [""])[0].upper()
|
|
16
|
+
clean_url = url.split("?partKey=")[0]
|
|
17
|
+
|
|
18
|
+
# POST URL: embed?i= -> embed/get?i=
|
|
19
|
+
post_url = clean_url.replace("embed?i=", "embed/get?i=")
|
|
20
|
+
|
|
21
|
+
response = await self.httpx.post(
|
|
22
|
+
url = post_url,
|
|
23
|
+
headers = {"Referer": clean_url}
|
|
24
|
+
)
|
|
25
|
+
response.raise_for_status()
|
|
26
|
+
|
|
27
|
+
# Links parse
|
|
28
|
+
links_match = re.search(r'Links":\["([^"\]]+)"', response.text)
|
|
29
|
+
if not links_match:
|
|
30
|
+
raise ValueError("Links not found in SetPrime response")
|
|
31
|
+
|
|
32
|
+
link_suffix = links_match.group(1)
|
|
33
|
+
if not link_suffix.startswith("/"):
|
|
34
|
+
raise ValueError("Links not valid (must start with /)")
|
|
35
|
+
|
|
36
|
+
m3u_link = f"{self.main_url}{link_suffix}"
|
|
37
|
+
|
|
38
|
+
display_name = f"{self.name} - {part_key}" if part_key else self.name
|
|
39
|
+
|
|
40
|
+
return ExtractResult(
|
|
41
|
+
name = display_name,
|
|
42
|
+
url = m3u_link,
|
|
43
|
+
referer = clean_url,
|
|
44
|
+
headers = {},
|
|
45
|
+
subtitles = []
|
|
46
|
+
)
|
KekikStream/Extractors/SibNet.py
CHANGED
|
@@ -9,9 +9,9 @@ class SibNet(ExtractorBase):
|
|
|
9
9
|
|
|
10
10
|
async def extract(self, url, referer=None) -> ExtractResult:
|
|
11
11
|
if referer:
|
|
12
|
-
self.
|
|
12
|
+
self.httpx.headers.update({"Referer": referer})
|
|
13
13
|
|
|
14
|
-
response = await self.
|
|
14
|
+
response = await self.httpx.get(url)
|
|
15
15
|
response.raise_for_status()
|
|
16
16
|
|
|
17
17
|
match = re.search(r'player\.src\(\[\{src: \"([^\"]+)\"', response.text)
|
|
@@ -9,9 +9,9 @@ class Sobreatsesuyp(ExtractorBase):
|
|
|
9
9
|
|
|
10
10
|
async def extract(self, url, referer=None) -> ExtractResult:
|
|
11
11
|
if referer:
|
|
12
|
-
self.
|
|
12
|
+
self.httpx.headers.update({"Referer": referer})
|
|
13
13
|
|
|
14
|
-
istek = await self.
|
|
14
|
+
istek = await self.httpx.get(url)
|
|
15
15
|
istek.raise_for_status()
|
|
16
16
|
|
|
17
17
|
file_match = re.search(r'file\":\"([^\"]+)', istek.text)
|
|
@@ -21,7 +21,7 @@ class Sobreatsesuyp(ExtractorBase):
|
|
|
21
21
|
file_path = file_match[1].replace("\\", "")
|
|
22
22
|
post_link = f"{self.main_url}/{file_path}"
|
|
23
23
|
|
|
24
|
-
post_istek = await self.
|
|
24
|
+
post_istek = await self.httpx.post(post_link)
|
|
25
25
|
post_istek.raise_for_status()
|
|
26
26
|
|
|
27
27
|
try:
|
|
@@ -41,7 +41,7 @@ class Sobreatsesuyp(ExtractorBase):
|
|
|
41
41
|
continue
|
|
42
42
|
|
|
43
43
|
playlist_url = f"{self.main_url}/playlist/{file.lstrip('/')}.txt"
|
|
44
|
-
playlist_request = await self.
|
|
44
|
+
playlist_request = await self.httpx.post(playlist_url, headers={"Referer": referer or self.main_url})
|
|
45
45
|
playlist_request.raise_for_status()
|
|
46
46
|
|
|
47
47
|
all_results.append(
|
KekikStream/Extractors/TRsTX.py
CHANGED
|
@@ -9,9 +9,9 @@ class TRsTX(ExtractorBase):
|
|
|
9
9
|
|
|
10
10
|
async def extract(self, url, referer=None) -> list[ExtractResult]:
|
|
11
11
|
if referer:
|
|
12
|
-
self.
|
|
12
|
+
self.httpx.headers.update({"Referer": referer})
|
|
13
13
|
|
|
14
|
-
istek = await self.
|
|
14
|
+
istek = await self.httpx.get(url)
|
|
15
15
|
istek.raise_for_status()
|
|
16
16
|
|
|
17
17
|
file_match = re.search(r'file\":\"([^\"]+)', istek.text)
|
|
@@ -21,7 +21,7 @@ class TRsTX(ExtractorBase):
|
|
|
21
21
|
file_path = file_match[1].replace("\\", "")
|
|
22
22
|
post_link = f"{self.main_url}/{file_path}"
|
|
23
23
|
|
|
24
|
-
post_istek = await self.
|
|
24
|
+
post_istek = await self.httpx.post(post_link)
|
|
25
25
|
post_istek.raise_for_status()
|
|
26
26
|
|
|
27
27
|
try:
|
|
@@ -42,7 +42,7 @@ class TRsTX(ExtractorBase):
|
|
|
42
42
|
continue
|
|
43
43
|
|
|
44
44
|
playlist_url = f"{self.main_url}/playlist/{file.lstrip('/')}.txt"
|
|
45
|
-
playlist_request = await self.
|
|
45
|
+
playlist_request = await self.httpx.post(playlist_url, headers={"Referer": referer or self.main_url})
|
|
46
46
|
playlist_request.raise_for_status()
|
|
47
47
|
|
|
48
48
|
video_data = playlist_request.text
|
|
@@ -8,12 +8,12 @@ class TauVideo(ExtractorBase):
|
|
|
8
8
|
|
|
9
9
|
async def extract(self, url, referer=None) -> list[ExtractResult]:
|
|
10
10
|
if referer:
|
|
11
|
-
self.
|
|
11
|
+
self.httpx.headers.update({"Referer": referer})
|
|
12
12
|
|
|
13
13
|
video_key = url.split("/")[-1]
|
|
14
14
|
api_url = f"{self.main_url}/api/video/{video_key}"
|
|
15
15
|
|
|
16
|
-
response = await self.
|
|
16
|
+
response = await self.httpx.get(api_url)
|
|
17
17
|
response.raise_for_status()
|
|
18
18
|
|
|
19
19
|
api_data = response.json()
|
|
@@ -9,9 +9,9 @@ class TurboImgz(ExtractorBase):
|
|
|
9
9
|
|
|
10
10
|
async def extract(self, url, referer=None) -> ExtractResult:
|
|
11
11
|
if referer:
|
|
12
|
-
self.
|
|
12
|
+
self.httpx.headers.update({"Referer": referer})
|
|
13
13
|
|
|
14
|
-
istek = await self.
|
|
14
|
+
istek = await self.httpx.get(url)
|
|
15
15
|
istek.raise_for_status()
|
|
16
16
|
|
|
17
17
|
if video_match := re.search(r'file: "(.*)",', istek.text):
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
|
+
|
|
3
|
+
from KekikStream.Core import ExtractorBase, ExtractResult, Subtitle
|
|
4
|
+
import re, json
|
|
5
|
+
|
|
6
|
+
class TurkeyPlayer(ExtractorBase):
|
|
7
|
+
name = "TurkeyPlayer"
|
|
8
|
+
main_url = "https://watch.turkeyplayer.com/"
|
|
9
|
+
|
|
10
|
+
async def extract(self, url: str, referer: str = None) -> ExtractResult:
|
|
11
|
+
if referer:
|
|
12
|
+
self.httpx.headers.update({"Referer": referer})
|
|
13
|
+
|
|
14
|
+
istek = await self.httpx.get(url)
|
|
15
|
+
page_content = istek.text
|
|
16
|
+
|
|
17
|
+
video_json_match = re.search(r'var\s+video\s*=\s*(\{.*?\});', page_content, re.DOTALL)
|
|
18
|
+
if not video_json_match:
|
|
19
|
+
raise ValueError("TurkeyPlayer: Video JSON bulunamadı")
|
|
20
|
+
|
|
21
|
+
video_data = json.loads(video_json_match.group(1))
|
|
22
|
+
|
|
23
|
+
video_id = video_data.get("id")
|
|
24
|
+
video_md5 = video_data.get("md5")
|
|
25
|
+
|
|
26
|
+
master_url = f"https://watch.turkeyplayer.com/m3u8/8/{video_md5}/master.txt?s=1&id={video_id}&cache=1"
|
|
27
|
+
|
|
28
|
+
return ExtractResult(
|
|
29
|
+
name = self.name,
|
|
30
|
+
url = master_url,
|
|
31
|
+
referer = referer or url,
|
|
32
|
+
headers = dict(self.httpx.headers),
|
|
33
|
+
subtitles = []
|
|
34
|
+
)
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
|
+
|
|
3
|
+
from KekikStream.Core import ExtractorBase, ExtractResult, Subtitle
|
|
4
|
+
from Kekik.Sifreleme import Packer
|
|
5
|
+
from parsel import Selector
|
|
6
|
+
import re
|
|
7
|
+
|
|
8
|
+
class VidHide(ExtractorBase):
|
|
9
|
+
name = "VidHide"
|
|
10
|
+
main_url = "https://vidhidepro.com"
|
|
11
|
+
|
|
12
|
+
def get_embed_url(self, url: str) -> str:
|
|
13
|
+
if "/d/" in url:
|
|
14
|
+
return url.replace("/d/", "/v/")
|
|
15
|
+
elif "/download/" in url:
|
|
16
|
+
return url.replace("/download/", "/v/")
|
|
17
|
+
elif "/file/" in url:
|
|
18
|
+
return url.replace("/file/", "/v/")
|
|
19
|
+
else:
|
|
20
|
+
return url.replace("/f/", "/v/")
|
|
21
|
+
|
|
22
|
+
async def extract(self, url: str, referer: str = None) -> ExtractResult:
|
|
23
|
+
if referer:
|
|
24
|
+
self.httpx.headers.update({"Referer": referer})
|
|
25
|
+
|
|
26
|
+
self.httpx.headers.update({
|
|
27
|
+
"Sec-Fetch-Dest" : "empty",
|
|
28
|
+
"Sec-Fetch-Mode" : "cors",
|
|
29
|
+
"Sec-Fetch-Site" : "cross-site",
|
|
30
|
+
"Origin" : self.main_url,
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
embed_url = self.get_embed_url(url)
|
|
34
|
+
istek = await self.httpx.get(embed_url)
|
|
35
|
+
response = istek.text
|
|
36
|
+
|
|
37
|
+
script = None
|
|
38
|
+
if "eval(function" in response:
|
|
39
|
+
try:
|
|
40
|
+
unpacked = Packer.unpack(response)
|
|
41
|
+
if "var links" in unpacked:
|
|
42
|
+
script = unpacked.split("var links")[1]
|
|
43
|
+
else:
|
|
44
|
+
script = unpacked
|
|
45
|
+
except Exception:
|
|
46
|
+
pass
|
|
47
|
+
|
|
48
|
+
if not script:
|
|
49
|
+
if matches := re.search(r'sources:\s*(\[.*?\])', response, re.DOTALL):
|
|
50
|
+
script = matches.group(1)
|
|
51
|
+
|
|
52
|
+
m3u8_url = None
|
|
53
|
+
if script:
|
|
54
|
+
# m3u8 urls could be prefixed by 'file:', 'hls2:' or 'hls4:', so we just match ':'
|
|
55
|
+
if match := re.search(r':\s*"([^"]*?m3u8[^"]*?)"', script):
|
|
56
|
+
m3u8_url = match.group(1)
|
|
57
|
+
|
|
58
|
+
if not m3u8_url:
|
|
59
|
+
# Fallback direct search in response if unpacking failed or structure changed
|
|
60
|
+
if match := re.search(r'file:"(.*?\.m3u8.*?)"', response):
|
|
61
|
+
m3u8_url = match.group(1)
|
|
62
|
+
|
|
63
|
+
if not m3u8_url:
|
|
64
|
+
raise ValueError(f"VidHide: Video URL bulunamadı. {url}")
|
|
65
|
+
|
|
66
|
+
return ExtractResult(
|
|
67
|
+
name = self.name,
|
|
68
|
+
url = self.fix_url(m3u8_url),
|
|
69
|
+
referer = f"{self.main_url}/",
|
|
70
|
+
headers = dict(self.httpx.headers),
|
|
71
|
+
subtitles = []
|
|
72
|
+
)
|
|
@@ -11,9 +11,9 @@ class VidMoly(ExtractorBase):
|
|
|
11
11
|
|
|
12
12
|
async def extract(self, url: str, referer: str = None) -> ExtractResult:
|
|
13
13
|
if referer:
|
|
14
|
-
self.
|
|
14
|
+
self.httpx.headers.update({"Referer": referer})
|
|
15
15
|
|
|
16
|
-
self.
|
|
16
|
+
self.httpx.headers.update({
|
|
17
17
|
"Sec-Fetch-Dest" : "iframe",
|
|
18
18
|
})
|
|
19
19
|
|
|
@@ -21,10 +21,10 @@ class VidMoly(ExtractorBase):
|
|
|
21
21
|
self.main_url = self.main_url.replace(".me", ".net")
|
|
22
22
|
url = url.replace(".me", ".net")
|
|
23
23
|
|
|
24
|
-
response = await self.
|
|
24
|
+
response = await self.httpx.get(url)
|
|
25
25
|
if "Select number" in response.text:
|
|
26
26
|
secici = Selector(response.text)
|
|
27
|
-
response = await self.
|
|
27
|
+
response = await self.httpx.post(
|
|
28
28
|
url = url,
|
|
29
29
|
data = {
|
|
30
30
|
"op" : secici.css("input[name='op']::attr(value)").get(),
|
|
@@ -10,9 +10,9 @@ class VidMoxy(ExtractorBase):
|
|
|
10
10
|
|
|
11
11
|
async def extract(self, url, referer=None) -> ExtractResult:
|
|
12
12
|
if referer:
|
|
13
|
-
self.
|
|
13
|
+
self.httpx.headers.update({"Referer": referer})
|
|
14
14
|
|
|
15
|
-
istek = await self.
|
|
15
|
+
istek = await self.httpx.get(url)
|
|
16
16
|
istek.raise_for_status()
|
|
17
17
|
|
|
18
18
|
subtitles = []
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
|
+
|
|
3
|
+
from KekikStream.Core import ExtractorBase, ExtractResult, Subtitle
|
|
4
|
+
import re
|
|
5
|
+
|
|
6
|
+
class VidPapi(ExtractorBase):
|
|
7
|
+
name = "VidApi"
|
|
8
|
+
main_url = "https://vidpapi.xyz"
|
|
9
|
+
|
|
10
|
+
async def extract(self, url, referer=None) -> ExtractResult:
|
|
11
|
+
ext_ref = referer or ""
|
|
12
|
+
|
|
13
|
+
# URL parsing
|
|
14
|
+
if "video/" in url:
|
|
15
|
+
vid_id = url.split("video/")[-1]
|
|
16
|
+
else:
|
|
17
|
+
vid_id = url.split("?data=")[-1]
|
|
18
|
+
|
|
19
|
+
# 1. Altyazıları çek
|
|
20
|
+
sub_url = f"{self.main_url}/player/index.php?data={vid_id}"
|
|
21
|
+
sub_headers = {
|
|
22
|
+
"Content-Type" : "application/x-www-form-urlencoded; charset=UTF-8",
|
|
23
|
+
"X-Requested-With" : "XMLHttpRequest",
|
|
24
|
+
"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:137.0) Gecko/20100101 Firefox/137.0",
|
|
25
|
+
"Referer" : ext_ref or "https://kultfilmler.pro/"
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
subtitles = []
|
|
29
|
+
try:
|
|
30
|
+
sub_istek = await self.httpx.post(
|
|
31
|
+
url = sub_url,
|
|
32
|
+
headers = sub_headers,
|
|
33
|
+
data = {"hash": vid_id, "r": "https://kultfilmler.pro/"}
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
subtitle_match = re.search(r'var playerjsSubtitle = "([^"]*)"', sub_istek.text, re.IGNORECASE)
|
|
37
|
+
if subtitle_match and subtitle_match.group(1):
|
|
38
|
+
raw_subs = subtitle_match.group(1)
|
|
39
|
+
|
|
40
|
+
found_subs = re.findall(r'\[(.*?)\](.*?)(?:,|$)', raw_subs)
|
|
41
|
+
for lang, sub_link in found_subs:
|
|
42
|
+
lang = lang.strip()
|
|
43
|
+
if "Türkçe" in lang:
|
|
44
|
+
lang_code = "tr"
|
|
45
|
+
lang_name = "Turkish"
|
|
46
|
+
elif "İngilizce" in lang:
|
|
47
|
+
lang_code = "en"
|
|
48
|
+
lang_name = "English"
|
|
49
|
+
else:
|
|
50
|
+
lang_code = lang[:2].lower()
|
|
51
|
+
lang_name = lang
|
|
52
|
+
|
|
53
|
+
subtitles.append(Subtitle(
|
|
54
|
+
name = lang_name,
|
|
55
|
+
url = sub_link.strip()
|
|
56
|
+
))
|
|
57
|
+
|
|
58
|
+
except Exception as e:
|
|
59
|
+
pass
|
|
60
|
+
|
|
61
|
+
# 2. Videoyu çek
|
|
62
|
+
video_url = f"{self.main_url}/player/index.php?data={vid_id}&do=getVideo"
|
|
63
|
+
video_headers = sub_headers.copy()
|
|
64
|
+
|
|
65
|
+
response = await self.httpx.post(
|
|
66
|
+
url = video_url,
|
|
67
|
+
headers = video_headers,
|
|
68
|
+
data = {"hash": vid_id, "r": "https://kultfilmler.pro/"}
|
|
69
|
+
)
|
|
70
|
+
response.raise_for_status()
|
|
71
|
+
|
|
72
|
+
try:
|
|
73
|
+
video_data = response.json()
|
|
74
|
+
except Exception:
|
|
75
|
+
return None
|
|
76
|
+
|
|
77
|
+
stream_url = video_data.get("securedLink")
|
|
78
|
+
if not stream_url or not stream_url.strip():
|
|
79
|
+
stream_url = video_data.get("videoSource")
|
|
80
|
+
|
|
81
|
+
if not stream_url:
|
|
82
|
+
raise ValueError("No video link found in VidPapi response")
|
|
83
|
+
|
|
84
|
+
return ExtractResult(
|
|
85
|
+
name = self.name,
|
|
86
|
+
url = stream_url,
|
|
87
|
+
referer = ext_ref or self.main_url,
|
|
88
|
+
headers = {},
|
|
89
|
+
subtitles = subtitles
|
|
90
|
+
)
|
|
@@ -9,18 +9,18 @@ class VideoSeyred(ExtractorBase):
|
|
|
9
9
|
|
|
10
10
|
async def extract(self, url, referer=None) -> ExtractResult:
|
|
11
11
|
if referer:
|
|
12
|
-
self.
|
|
12
|
+
self.httpx.headers.update({"Referer": referer})
|
|
13
13
|
|
|
14
14
|
video_id = url.split("embed/")[1].split("?")[0]
|
|
15
15
|
if len(video_id) > 10:
|
|
16
|
-
kontrol = await self.
|
|
16
|
+
kontrol = await self.httpx.get(url)
|
|
17
17
|
kontrol.raise_for_status()
|
|
18
18
|
|
|
19
19
|
video_id = re.search(r"playlist\/(.*)\.json", kontrol.text)[1]
|
|
20
20
|
|
|
21
21
|
video_url = f"{self.main_url}/playlist/{video_id}.json"
|
|
22
22
|
|
|
23
|
-
response = await self.
|
|
23
|
+
response = await self.httpx.get(video_url)
|
|
24
24
|
response.raise_for_status()
|
|
25
25
|
|
|
26
26
|
try:
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
|
+
|
|
3
|
+
from KekikStream.Core import ExtractorBase, ExtractResult
|
|
4
|
+
|
|
5
|
+
class YildizKisaFilm(ExtractorBase):
|
|
6
|
+
name = "YildizKisaFilm"
|
|
7
|
+
main_url = "https://yildizkisafilm.org"
|
|
8
|
+
|
|
9
|
+
async def extract(self, url, referer=None) -> ExtractResult:
|
|
10
|
+
ext_ref = referer or ""
|
|
11
|
+
|
|
12
|
+
if "video/" in url:
|
|
13
|
+
vid_id = url.split("video/")[-1]
|
|
14
|
+
else:
|
|
15
|
+
vid_id = url.split("?data=")[-1]
|
|
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
|
+
}
|
|
27
|
+
)
|
|
28
|
+
response.raise_for_status()
|
|
29
|
+
|
|
30
|
+
video_data = response.json()
|
|
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 = ext_ref,
|
|
40
|
+
headers = {},
|
|
41
|
+
subtitles = []
|
|
42
|
+
)
|
KekikStream/Plugins/DiziBox.py
CHANGED
|
@@ -42,11 +42,11 @@ class DiziBox(PluginBase):
|
|
|
42
42
|
|
|
43
43
|
#@kekik_cache(ttl=60*60)
|
|
44
44
|
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
45
|
-
self.
|
|
45
|
+
self.httpx.cookies.update({
|
|
46
46
|
"isTrustedUser" : "true",
|
|
47
47
|
"dbxu" : str(time.time() * 1000).split(".")[0]
|
|
48
48
|
})
|
|
49
|
-
istek = await self.
|
|
49
|
+
istek = await self.httpx.get(
|
|
50
50
|
url = f"{url.replace('SAYFA', str(page))}",
|
|
51
51
|
allow_redirects = True
|
|
52
52
|
)
|
|
@@ -64,11 +64,11 @@ class DiziBox(PluginBase):
|
|
|
64
64
|
|
|
65
65
|
#@kekik_cache(ttl=60*60)
|
|
66
66
|
async def search(self, query: str) -> list[SearchResult]:
|
|
67
|
-
self.
|
|
67
|
+
self.httpx.cookies.update({
|
|
68
68
|
"isTrustedUser" : "true",
|
|
69
69
|
"dbxu" : str(time.time() * 1000).split(".")[0]
|
|
70
70
|
})
|
|
71
|
-
istek = await self.
|
|
71
|
+
istek = await self.httpx.get(f"{self.main_url}/?s={query}")
|
|
72
72
|
secici = Selector(istek.text)
|
|
73
73
|
|
|
74
74
|
return [
|
|
@@ -82,7 +82,7 @@ class DiziBox(PluginBase):
|
|
|
82
82
|
|
|
83
83
|
#@kekik_cache(ttl=60*60)
|
|
84
84
|
async def load_item(self, url: str) -> SeriesInfo:
|
|
85
|
-
istek = await self.
|
|
85
|
+
istek = await self.httpx.get(url)
|
|
86
86
|
secici = Selector(istek.text)
|
|
87
87
|
|
|
88
88
|
title = secici.css("div.tv-overview h1 a::text").get()
|
|
@@ -96,7 +96,7 @@ class DiziBox(PluginBase):
|
|
|
96
96
|
episodes = []
|
|
97
97
|
for sezon_link in secici.css("div#seasons-list a::attr(href)").getall():
|
|
98
98
|
sezon_url = self.fix_url(sezon_link)
|
|
99
|
-
sezon_istek = await self.
|
|
99
|
+
sezon_istek = await self.httpx.get(sezon_url)
|
|
100
100
|
sezon_secici = Selector(sezon_istek.text)
|
|
101
101
|
|
|
102
102
|
for bolum in sezon_secici.css("article.grid-box"):
|
|
@@ -131,8 +131,8 @@ class DiziBox(PluginBase):
|
|
|
131
131
|
async def _iframe_decode(self, name:str, iframe_link:str, referer:str) -> list[str]:
|
|
132
132
|
results = []
|
|
133
133
|
|
|
134
|
-
self.
|
|
135
|
-
self.
|
|
134
|
+
self.httpx.headers.update({"Referer": referer})
|
|
135
|
+
self.httpx.cookies.update({
|
|
136
136
|
"isTrustedUser" : "true",
|
|
137
137
|
"dbxu" : str(time.time() * 1000).split(".")[0]
|
|
138
138
|
})
|
|
@@ -140,12 +140,12 @@ class DiziBox(PluginBase):
|
|
|
140
140
|
if "/player/king/king.php" in iframe_link:
|
|
141
141
|
iframe_link = iframe_link.replace("king.php?v=", "king.php?wmode=opaque&v=")
|
|
142
142
|
|
|
143
|
-
istek = await self.
|
|
143
|
+
istek = await self.httpx.get(iframe_link)
|
|
144
144
|
secici = Selector(istek.text)
|
|
145
145
|
iframe = secici.css("div#Player iframe::attr(src)").get()
|
|
146
146
|
|
|
147
|
-
self.
|
|
148
|
-
istek = await self.
|
|
147
|
+
self.httpx.headers.update({"Referer": self.main_url})
|
|
148
|
+
istek = await self.httpx.get(iframe)
|
|
149
149
|
|
|
150
150
|
crypt_data = re.search(r"CryptoJS\.AES\.decrypt\(\"(.*)\",\"", istek.text)[1]
|
|
151
151
|
crypt_pass = re.search(r"\",\"(.*)\"\);", istek.text)[1]
|
|
@@ -161,7 +161,7 @@ class DiziBox(PluginBase):
|
|
|
161
161
|
while True:
|
|
162
162
|
await asyncio.sleep(.3)
|
|
163
163
|
with contextlib.suppress(Exception):
|
|
164
|
-
istek = await self.
|
|
164
|
+
istek = await self.httpx.get(iframe_link)
|
|
165
165
|
|
|
166
166
|
if atob_data := re.search(r"unescape\(\"(.*)\"\)", istek.text):
|
|
167
167
|
decoded_atob = urllib.parse.unquote(atob_data[1])
|
|
@@ -180,7 +180,7 @@ class DiziBox(PluginBase):
|
|
|
180
180
|
|
|
181
181
|
#@kekik_cache(ttl=15*60)
|
|
182
182
|
async def load_links(self, url: str) -> list[dict]:
|
|
183
|
-
istek = await self.
|
|
183
|
+
istek = await self.httpx.get(url)
|
|
184
184
|
secici = Selector(istek.text)
|
|
185
185
|
|
|
186
186
|
results = []
|
|
@@ -200,8 +200,8 @@ class DiziBox(PluginBase):
|
|
|
200
200
|
if not alt_link:
|
|
201
201
|
continue
|
|
202
202
|
|
|
203
|
-
self.
|
|
204
|
-
alt_istek = await self.
|
|
203
|
+
self.httpx.headers.update({"Referer": url})
|
|
204
|
+
alt_istek = await self.httpx.get(alt_link)
|
|
205
205
|
alt_istek.raise_for_status()
|
|
206
206
|
|
|
207
207
|
alt_secici = Selector(alt_istek.text)
|