KekikStream 0.7.1__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of KekikStream might be problematic. Click here for more details.
- KekikStream/CLI/__init__.py +4 -0
- KekikStream/CLI/pypi_kontrol.py +30 -0
- KekikStream/Core/ExtractorBase.py +42 -0
- KekikStream/Core/ExtractorLoader.py +82 -0
- KekikStream/Core/ExtractorModels.py +19 -0
- KekikStream/Core/MediaHandler.py +142 -0
- KekikStream/Core/PluginBase.py +80 -0
- KekikStream/Core/PluginLoader.py +61 -0
- KekikStream/Core/PluginModels.py +63 -0
- KekikStream/Core/__init__.py +9 -0
- KekikStream/Extractors/CloseLoad.py +31 -0
- KekikStream/Extractors/ContentX.py +80 -0
- KekikStream/Extractors/FourCX.py +7 -0
- KekikStream/Extractors/FourPichive.py +7 -0
- KekikStream/Extractors/FourPlayRu.py +7 -0
- KekikStream/Extractors/HDStreamAble.py +7 -0
- KekikStream/Extractors/Hotlinger.py +7 -0
- KekikStream/Extractors/MailRu.py +40 -0
- KekikStream/Extractors/MixPlayHD.py +42 -0
- KekikStream/Extractors/Odnoklassniki.py +106 -0
- KekikStream/Extractors/OkRuHTTP.py +7 -0
- KekikStream/Extractors/OkRuSSL.py +7 -0
- KekikStream/Extractors/PeaceMakerst.py +57 -0
- KekikStream/Extractors/Pichive.py +7 -0
- KekikStream/Extractors/PixelDrain.py +28 -0
- KekikStream/Extractors/PlayRu.py +7 -0
- KekikStream/Extractors/RapidVid.py +60 -0
- KekikStream/Extractors/SibNet.py +29 -0
- KekikStream/Extractors/Sobreatsesuyp.py +59 -0
- KekikStream/Extractors/TRsTX.py +67 -0
- KekikStream/Extractors/TauVideo.py +34 -0
- KekikStream/Extractors/TurboImgz.py +25 -0
- KekikStream/Extractors/VidMoly.py +85 -0
- KekikStream/Extractors/VidMoxy.py +50 -0
- KekikStream/Extractors/VideoSeyred.py +47 -0
- KekikStream/Managers/ExtractorManager.py +27 -0
- KekikStream/Managers/MediaManager.py +19 -0
- KekikStream/Managers/PluginManager.py +19 -0
- KekikStream/Managers/UIManager.py +49 -0
- KekikStream/Managers/__init__.py +6 -0
- KekikStream/Plugins/DiziBox.py +143 -0
- KekikStream/Plugins/DiziYou.py +127 -0
- KekikStream/Plugins/Dizilla.py +106 -0
- KekikStream/Plugins/FilmMakinesi.py +65 -0
- KekikStream/Plugins/FullHDFilmizlesene.py +78 -0
- KekikStream/Plugins/JetFilmizle.py +92 -0
- KekikStream/Plugins/RecTV.py +113 -0
- KekikStream/Plugins/SezonlukDizi.py +108 -0
- KekikStream/Plugins/SineWix.py +108 -0
- KekikStream/Plugins/UgurFilm.py +75 -0
- KekikStream/__init__.py +255 -0
- KekikStream/__main__.py +6 -0
- KekikStream/requirements.txt +10 -0
- KekikStream-0.7.1.dist-info/LICENSE +674 -0
- KekikStream-0.7.1.dist-info/METADATA +94 -0
- KekikStream-0.7.1.dist-info/RECORD +59 -0
- KekikStream-0.7.1.dist-info/WHEEL +5 -0
- KekikStream-0.7.1.dist-info/entry_points.txt +2 -0
- KekikStream-0.7.1.dist-info/top_level.txt +1 -0
@@ -0,0 +1,40 @@
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
2
|
+
|
3
|
+
from KekikStream.Core import ExtractorBase, ExtractResult
|
4
|
+
|
5
|
+
class MailRuExtractor(ExtractorBase):
|
6
|
+
name = "MailRu"
|
7
|
+
main_url = "https://my.mail.ru"
|
8
|
+
|
9
|
+
async def extract(self, url, referer=None) -> ExtractResult:
|
10
|
+
vid_id = url.split("video/embed/")[-1].strip()
|
11
|
+
video_meta_url = f"{self.main_url}/+/video/meta/{vid_id}"
|
12
|
+
|
13
|
+
if referer:
|
14
|
+
self.oturum.headers.update({"Referer": referer})
|
15
|
+
|
16
|
+
istek = await self.oturum.get(video_meta_url)
|
17
|
+
istek.raise_for_status()
|
18
|
+
|
19
|
+
video_key = istek.cookies.get("video_key")
|
20
|
+
if not video_key:
|
21
|
+
raise ValueError("Video key bulunamadı.")
|
22
|
+
|
23
|
+
video_data = istek.json()
|
24
|
+
videos = video_data.get("videos", [])
|
25
|
+
if not videos:
|
26
|
+
raise ValueError("Videolar bulunamadı.")
|
27
|
+
|
28
|
+
video = videos[0]
|
29
|
+
video_url = video["url"]
|
30
|
+
if video_url.startswith("//"):
|
31
|
+
video_url = f"https:{video_url}"
|
32
|
+
|
33
|
+
await self.close()
|
34
|
+
return ExtractResult(
|
35
|
+
name = self.name,
|
36
|
+
url = video_url,
|
37
|
+
referer = self.main_url,
|
38
|
+
subtitles = [],
|
39
|
+
headers = {"Cookie": f"video_key={video_key}"}
|
40
|
+
)
|
@@ -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
|
+
from Kekik.Sifreleme import AESManager
|
5
|
+
import re, json
|
6
|
+
|
7
|
+
class MixPlayHD(ExtractorBase):
|
8
|
+
name = "MixPlayHD"
|
9
|
+
main_url = "https://mixplayhd.com"
|
10
|
+
|
11
|
+
async def extract(self, url, referer=None) -> ExtractResult:
|
12
|
+
if referer:
|
13
|
+
self.oturum.headers.update({"Referer": referer})
|
14
|
+
|
15
|
+
istek = await self.oturum.get(url)
|
16
|
+
istek.raise_for_status()
|
17
|
+
|
18
|
+
be_player_match = re.search(r"bePlayer\('([^']+)',\s*'(\{[^\}]+\})'\);", istek.text)
|
19
|
+
if not be_player_match:
|
20
|
+
raise ValueError("bePlayer not found in the response.")
|
21
|
+
|
22
|
+
be_player_pass = be_player_match[1]
|
23
|
+
be_player_data = be_player_match[2]
|
24
|
+
|
25
|
+
try:
|
26
|
+
decrypted_data = AESManager.decrypt(be_player_data, be_player_pass).replace("\\", "")
|
27
|
+
decrypted_json = json.loads(decrypted_data)
|
28
|
+
except Exception as hata:
|
29
|
+
raise RuntimeError(f"Decryption failed: {hata}") from hata
|
30
|
+
|
31
|
+
if video_url_match := re.search(
|
32
|
+
pattern = r'"video_location":"([^"]+)"',
|
33
|
+
string = decrypted_json.get("schedule", {}).get("client", ""),
|
34
|
+
):
|
35
|
+
return ExtractResult(
|
36
|
+
name = self.name,
|
37
|
+
url = video_url_match[1],
|
38
|
+
referer = self.main_url,
|
39
|
+
subtitles = []
|
40
|
+
)
|
41
|
+
else:
|
42
|
+
raise ValueError("M3U8 video URL not found in the decrypted data.")
|
@@ -0,0 +1,106 @@
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
2
|
+
|
3
|
+
from KekikStream.Core import ExtractorBase, ExtractResult
|
4
|
+
import re, json
|
5
|
+
|
6
|
+
class Odnoklassniki(ExtractorBase):
|
7
|
+
name = "Odnoklassniki"
|
8
|
+
main_url = "https://odnoklassniki.ru"
|
9
|
+
|
10
|
+
async def extract(self, url, referer=None) -> ExtractResult:
|
11
|
+
if referer:
|
12
|
+
self.oturum.headers.update({"Referer": referer})
|
13
|
+
|
14
|
+
self.oturum.headers.update({
|
15
|
+
"User-Agent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Mobile Safari/537.36"
|
16
|
+
})
|
17
|
+
|
18
|
+
if "/video/" in url:
|
19
|
+
url = url.replace("/video/", "/videoembed/")
|
20
|
+
|
21
|
+
try:
|
22
|
+
istek = await self.fetch_with_redirects(url)
|
23
|
+
istek.raise_for_status()
|
24
|
+
except Exception as hata:
|
25
|
+
raise RuntimeError(f"Failed to fetch the URL: {url}, Error: {hata}") from hata
|
26
|
+
|
27
|
+
response_text = (
|
28
|
+
istek.text.replace("\\"", "\"")
|
29
|
+
.replace("\\\\", "\\")
|
30
|
+
.replace(r"\\u", "\\u")
|
31
|
+
)
|
32
|
+
response_text = re.sub(
|
33
|
+
r"\\u([0-9A-Fa-f]{4})",
|
34
|
+
lambda match: chr(int(match[1], 16)),
|
35
|
+
response_text
|
36
|
+
)
|
37
|
+
|
38
|
+
videos_match = re.search(r'"videos":(\[.*?\])', response_text)
|
39
|
+
if not videos_match:
|
40
|
+
raise ValueError("No video data found in the response.")
|
41
|
+
|
42
|
+
try:
|
43
|
+
videos = json.loads(videos_match[1])
|
44
|
+
except json.JSONDecodeError as hata:
|
45
|
+
raise ValueError("Failed to parse video data.") from hata
|
46
|
+
|
47
|
+
quality_order = {
|
48
|
+
"ULTRA": 6, # 4K veya daha yüksek
|
49
|
+
"QUAD": 5, # 1440p
|
50
|
+
"FULL": 4, # 1080p
|
51
|
+
"HD": 3, # 720p
|
52
|
+
"SD": 2, # 480p
|
53
|
+
"LOW": 1, # 360p
|
54
|
+
"MOBILE": 0 # 144p
|
55
|
+
}
|
56
|
+
|
57
|
+
# Kaliteye göre en iyi videoyu seçme
|
58
|
+
best_video = None
|
59
|
+
best_quality_score = -1
|
60
|
+
|
61
|
+
for video in videos:
|
62
|
+
video_url = video.get("url")
|
63
|
+
quality_name = video.get("name", "").upper()
|
64
|
+
|
65
|
+
if not video_url or not quality_name:
|
66
|
+
continue
|
67
|
+
|
68
|
+
# Kalite sıralamasına göre puanla
|
69
|
+
quality_score = quality_order.get(quality_name, -1)
|
70
|
+
if quality_score > best_quality_score:
|
71
|
+
best_quality_score = quality_score
|
72
|
+
best_video = video_url
|
73
|
+
|
74
|
+
if not best_video:
|
75
|
+
raise ValueError("No valid video URLs found.")
|
76
|
+
|
77
|
+
if best_video.startswith("//"):
|
78
|
+
best_video = f"https:{best_video}"
|
79
|
+
|
80
|
+
return ExtractResult(
|
81
|
+
name = self.name,
|
82
|
+
url = best_video,
|
83
|
+
referer = self.main_url,
|
84
|
+
subtitles = []
|
85
|
+
)
|
86
|
+
|
87
|
+
async def fetch_with_redirects(self, url, max_redirects=5):
|
88
|
+
"""Yönlendirmeleri takip eden bir fonksiyon"""
|
89
|
+
redirects = 0
|
90
|
+
while redirects < max_redirects:
|
91
|
+
istek = await self.oturum.get(url, follow_redirects=False)
|
92
|
+
|
93
|
+
if istek.status_code not in [301, 302]:
|
94
|
+
break # Yönlendirme yoksa çık
|
95
|
+
|
96
|
+
redirected_url = istek.headers.get("Location")
|
97
|
+
if not redirected_url:
|
98
|
+
raise ValueError("Redirect location not found.")
|
99
|
+
|
100
|
+
url = redirected_url if redirected_url.startswith("http") else f"https://{redirected_url}"
|
101
|
+
redirects += 1
|
102
|
+
|
103
|
+
if redirects == max_redirects:
|
104
|
+
raise RuntimeError(f"Max redirects ({max_redirects}) reached.")
|
105
|
+
|
106
|
+
return istek
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
2
|
+
|
3
|
+
from KekikStream.Core import ExtractorBase, ExtractResult
|
4
|
+
import re, json
|
5
|
+
|
6
|
+
class PeaceMakerst(ExtractorBase):
|
7
|
+
name = "PeaceMakerst"
|
8
|
+
main_url = "https://peacemakerst.com"
|
9
|
+
|
10
|
+
async def extract(self, url, referer=None) -> ExtractResult:
|
11
|
+
if referer:
|
12
|
+
self.oturum.headers.update({"Referer": referer})
|
13
|
+
|
14
|
+
self.oturum.headers.update({
|
15
|
+
"Content-Type" : "application/x-www-form-urlencoded; charset=UTF-8",
|
16
|
+
"X-Requested-With" : "XMLHttpRequest"
|
17
|
+
})
|
18
|
+
|
19
|
+
response = await self.oturum.post(
|
20
|
+
url = f"{url}?do=getVideo",
|
21
|
+
data = {
|
22
|
+
"hash" : url.split("video/")[-1],
|
23
|
+
"r" : referer or "",
|
24
|
+
"s" : ""
|
25
|
+
}
|
26
|
+
)
|
27
|
+
response.raise_for_status()
|
28
|
+
|
29
|
+
response_text = response.text
|
30
|
+
m3u_link = None
|
31
|
+
|
32
|
+
if "teve2.com.tr\\/embed\\/" in response_text:
|
33
|
+
teve2_id = re.search(r"teve2\.com\.tr\\\/embed\\\/(\d+)", response_text)[1]
|
34
|
+
teve2_url = f"https://www.teve2.com.tr/action/media/{teve2_id}"
|
35
|
+
|
36
|
+
teve2_response = await self.oturum.get(teve2_url, headers={"Referer": f"https://www.teve2.com.tr/embed/{teve2_id}"})
|
37
|
+
teve2_response.raise_for_status()
|
38
|
+
teve2_json = teve2_response.json()
|
39
|
+
|
40
|
+
m3u_link = f"{teve2_json['Media']['Link']['ServiceUrl']}//{teve2_json['Media']['Link']['SecurePath']}"
|
41
|
+
else:
|
42
|
+
try:
|
43
|
+
video_response = response.json()
|
44
|
+
if video_sources := video_response.get("videoSources", []):
|
45
|
+
m3u_link = video_sources[-1]["file"]
|
46
|
+
except (json.JSONDecodeError, KeyError) as hata:
|
47
|
+
raise ValueError("Peace response is invalid or null.") from hata
|
48
|
+
|
49
|
+
if not m3u_link:
|
50
|
+
raise ValueError("m3u link not found.")
|
51
|
+
|
52
|
+
return ExtractResult(
|
53
|
+
name = self.name,
|
54
|
+
url = m3u_link,
|
55
|
+
referer = url,
|
56
|
+
subtitles = []
|
57
|
+
)
|
@@ -0,0 +1,28 @@
|
|
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 PixelDrain(ExtractorBase):
|
7
|
+
name = "PixelDrain"
|
8
|
+
main_url = "https://pixeldrain.com"
|
9
|
+
|
10
|
+
async def extract(self, url, referer=None) -> ExtractResult:
|
11
|
+
if referer:
|
12
|
+
self.oturum.headers.update({"Referer": referer})
|
13
|
+
|
14
|
+
pixel_id_match = re.search(r"/u/([^/?]+)|([^\/]+)(?=\?download)", url)
|
15
|
+
if not pixel_id_match:
|
16
|
+
raise ValueError("PixelDrain bağlantısından ID çıkarılamadı.")
|
17
|
+
|
18
|
+
pixel_id = pixel_id_match[1]
|
19
|
+
download_link = f"{self.main_url}/api/file/{pixel_id}?download"
|
20
|
+
referer_link = f"{self.main_url}/u/{pixel_id}?download"
|
21
|
+
|
22
|
+
await self.close()
|
23
|
+
return ExtractResult(
|
24
|
+
name = f"{self.name} - {pixel_id}",
|
25
|
+
url = download_link,
|
26
|
+
referer = referer_link,
|
27
|
+
subtitles = []
|
28
|
+
)
|
@@ -0,0 +1,60 @@
|
|
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, HexCodec
|
5
|
+
import re
|
6
|
+
|
7
|
+
class RapidVid(ExtractorBase):
|
8
|
+
name = "RapidVid"
|
9
|
+
main_url = "https://rapidvid.net"
|
10
|
+
|
11
|
+
async def extract(self, url, referer=None) -> ExtractResult:
|
12
|
+
if referer:
|
13
|
+
self.oturum.headers.update({"Referer": referer})
|
14
|
+
|
15
|
+
istek = await self.oturum.get(url)
|
16
|
+
istek.raise_for_status()
|
17
|
+
|
18
|
+
subtitles = []
|
19
|
+
subtitle_matches = re.findall(r'captions\",\"file\":\"([^\"]+)\",\"label\":\"([^\"]+)\"', istek.text)
|
20
|
+
seen_subtitles = set()
|
21
|
+
|
22
|
+
for sub_url, sub_lang in subtitle_matches:
|
23
|
+
if sub_url in seen_subtitles:
|
24
|
+
continue
|
25
|
+
|
26
|
+
seen_subtitles.add(sub_url)
|
27
|
+
decoded_lang = (
|
28
|
+
sub_lang.replace("\\u0131", "ı")
|
29
|
+
.replace("\\u0130", "İ")
|
30
|
+
.replace("\\u00fc", "ü")
|
31
|
+
.replace("\\u00e7", "ç")
|
32
|
+
)
|
33
|
+
subtitles.append(Subtitle(name=decoded_lang, url=sub_url.replace("\\", "")))
|
34
|
+
|
35
|
+
try:
|
36
|
+
if extracted_value := re.search(r'file": "(.*)",', istek.text):
|
37
|
+
escaped_hex = extracted_value[1]
|
38
|
+
decoded_url = HexCodec.decode(escaped_hex)
|
39
|
+
else:
|
40
|
+
eval_jwsetup = re.search(r'\};\s*(eval\(function[\s\S]*?)var played = \d+;', istek.text)
|
41
|
+
if not eval_jwsetup:
|
42
|
+
raise ValueError("JWPlayer setup not found.")
|
43
|
+
|
44
|
+
unpacked_jwsetup = Packer.unpack(Packer.unpack(eval_jwsetup[1]))
|
45
|
+
extracted_value = re.search(r'file":"(.*)","label', unpacked_jwsetup)
|
46
|
+
if not extracted_value:
|
47
|
+
raise ValueError("File URL not found in unpacked JWPlayer setup.")
|
48
|
+
|
49
|
+
escaped_hex = extracted_value[1].replace("\\\\x", "")
|
50
|
+
decoded_url = bytes.fromhex(escaped_hex).decode("utf-8")
|
51
|
+
except Exception as hata:
|
52
|
+
raise RuntimeError(f"Extraction failed: {hata}") from hata
|
53
|
+
|
54
|
+
await self.close()
|
55
|
+
return ExtractResult(
|
56
|
+
name = self.name,
|
57
|
+
url = decoded_url,
|
58
|
+
referer = self.main_url,
|
59
|
+
subtitles = subtitles
|
60
|
+
)
|
@@ -0,0 +1,29 @@
|
|
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 SibNet(ExtractorBase):
|
7
|
+
name = "SibNet"
|
8
|
+
main_url = "https://video.sibnet.ru"
|
9
|
+
|
10
|
+
async def extract(self, url, referer=None) -> ExtractResult:
|
11
|
+
if referer:
|
12
|
+
self.oturum.headers.update({"Referer": referer})
|
13
|
+
|
14
|
+
response = await self.oturum.get(url)
|
15
|
+
response.raise_for_status()
|
16
|
+
|
17
|
+
match = re.search(r'player\.src\(\[\{src: \"([^\"]+)\"', response.text)
|
18
|
+
if not match:
|
19
|
+
raise ValueError("m3u bağlantısı bulunamadı.")
|
20
|
+
|
21
|
+
m3u_link = f"{self.main_url}{match[1]}"
|
22
|
+
|
23
|
+
await self.close()
|
24
|
+
return ExtractResult(
|
25
|
+
name = self.name,
|
26
|
+
url = m3u_link,
|
27
|
+
referer = url,
|
28
|
+
subtitles = []
|
29
|
+
)
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
2
|
+
|
3
|
+
from KekikStream.Core import ExtractorBase, ExtractResult
|
4
|
+
import re, json
|
5
|
+
|
6
|
+
class Sobreatsesuyp(ExtractorBase):
|
7
|
+
name = "Sobreatsesuyp"
|
8
|
+
main_url = "https://sobreatsesuyp.com"
|
9
|
+
|
10
|
+
async def extract(self, url, referer=None) -> ExtractResult:
|
11
|
+
if referer:
|
12
|
+
self.oturum.headers.update({"Referer": referer})
|
13
|
+
|
14
|
+
istek = await self.oturum.get(url)
|
15
|
+
istek.raise_for_status()
|
16
|
+
|
17
|
+
file_match = re.search(r'file\":\"([^\"]+)', istek.text)
|
18
|
+
if not file_match:
|
19
|
+
raise ValueError("File not found in response.")
|
20
|
+
|
21
|
+
file_path = file_match[1].replace("\\", "")
|
22
|
+
post_link = f"{self.main_url}/{file_path}"
|
23
|
+
|
24
|
+
post_istek = await self.oturum.post(post_link)
|
25
|
+
post_istek.raise_for_status()
|
26
|
+
|
27
|
+
try:
|
28
|
+
post_json = json.loads(post_istek.text)
|
29
|
+
except json.JSONDecodeError as hata:
|
30
|
+
raise ValueError("Failed to parse JSON response.") from hata
|
31
|
+
|
32
|
+
video_data_list = post_json[1:] if isinstance(post_json, list) else []
|
33
|
+
|
34
|
+
all_results = []
|
35
|
+
|
36
|
+
for item in video_data_list:
|
37
|
+
title = item.get("title")
|
38
|
+
file = item.get("file")
|
39
|
+
|
40
|
+
if not title or not file:
|
41
|
+
continue
|
42
|
+
|
43
|
+
playlist_url = f"{self.main_url}/playlist/{file.lstrip('/')}.txt"
|
44
|
+
playlist_request = await self.oturum.post(playlist_url, headers={"Referer": referer or self.main_url})
|
45
|
+
playlist_request.raise_for_status()
|
46
|
+
|
47
|
+
all_results.append(
|
48
|
+
ExtractResult(
|
49
|
+
name = f"{self.name} - {title}",
|
50
|
+
url = playlist_request.text,
|
51
|
+
referer = self.main_url,
|
52
|
+
subtitles = []
|
53
|
+
)
|
54
|
+
)
|
55
|
+
|
56
|
+
if not all_results:
|
57
|
+
raise ValueError("No videos found in response.")
|
58
|
+
|
59
|
+
return all_results[0] if len(all_results) == 1 else all_results
|
@@ -0,0 +1,67 @@
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
2
|
+
|
3
|
+
from KekikStream.Core import ExtractorBase, ExtractResult
|
4
|
+
import re, json
|
5
|
+
|
6
|
+
class TRsTX(ExtractorBase):
|
7
|
+
name = "TRsTX"
|
8
|
+
main_url = "https://trstx.org"
|
9
|
+
|
10
|
+
async def extract(self, url, referer=None) -> list[ExtractResult]:
|
11
|
+
if referer:
|
12
|
+
self.oturum.headers.update({"Referer": referer})
|
13
|
+
|
14
|
+
istek = await self.oturum.get(url)
|
15
|
+
istek.raise_for_status()
|
16
|
+
|
17
|
+
file_match = re.search(r'file\":\"([^\"]+)', istek.text)
|
18
|
+
if not file_match:
|
19
|
+
raise ValueError("File not found in response.")
|
20
|
+
|
21
|
+
file_path = file_match[1].replace("\\", "")
|
22
|
+
post_link = f"{self.main_url}/{file_path}"
|
23
|
+
|
24
|
+
post_istek = await self.oturum.post(post_link)
|
25
|
+
post_istek.raise_for_status()
|
26
|
+
|
27
|
+
try:
|
28
|
+
post_json = json.loads(post_istek.text)
|
29
|
+
except json.JSONDecodeError as hata:
|
30
|
+
raise ValueError("Failed to parse JSON response.") from hata
|
31
|
+
|
32
|
+
video_data_list = post_json[1:] if isinstance(post_json, list) else []
|
33
|
+
|
34
|
+
video_links = set()
|
35
|
+
all_results = []
|
36
|
+
|
37
|
+
for item in video_data_list:
|
38
|
+
title = item.get("title")
|
39
|
+
file = item.get("file")
|
40
|
+
|
41
|
+
if not title or not file:
|
42
|
+
continue
|
43
|
+
|
44
|
+
playlist_url = f"{self.main_url}/playlist/{file.lstrip('/')}.txt"
|
45
|
+
playlist_request = await self.oturum.post(playlist_url, headers={"Referer": referer or self.main_url})
|
46
|
+
playlist_request.raise_for_status()
|
47
|
+
|
48
|
+
video_data = playlist_request.text
|
49
|
+
|
50
|
+
if video_data in video_links:
|
51
|
+
continue
|
52
|
+
|
53
|
+
video_links.add(video_data)
|
54
|
+
|
55
|
+
all_results.append(
|
56
|
+
ExtractResult(
|
57
|
+
name = f"{self.name} - {title}",
|
58
|
+
url = video_data,
|
59
|
+
referer = self.main_url,
|
60
|
+
subtitles = []
|
61
|
+
)
|
62
|
+
)
|
63
|
+
|
64
|
+
if not all_results:
|
65
|
+
raise ValueError("No videos found in response.")
|
66
|
+
|
67
|
+
return all_results[0] if len(all_results) == 1 else all_results
|
@@ -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
|
4
|
+
|
5
|
+
class TauVideo(ExtractorBase):
|
6
|
+
name = "TauVideo"
|
7
|
+
main_url = "https://tau-video.xyz"
|
8
|
+
|
9
|
+
async def extract(self, url, referer=None) -> list[ExtractResult]:
|
10
|
+
if referer:
|
11
|
+
self.oturum.headers.update({"Referer": referer})
|
12
|
+
|
13
|
+
video_key = url.split("/")[-1]
|
14
|
+
api_url = f"{self.main_url}/api/video/{video_key}"
|
15
|
+
|
16
|
+
response = await self.oturum.get(api_url)
|
17
|
+
response.raise_for_status()
|
18
|
+
|
19
|
+
api_data = response.json()
|
20
|
+
|
21
|
+
if "urls" not in api_data:
|
22
|
+
raise ValueError("API yanıtında 'urls' bulunamadı.")
|
23
|
+
|
24
|
+
results = [
|
25
|
+
ExtractResult(
|
26
|
+
name = f"{self.name} - {video['label']}",
|
27
|
+
url = video["url"],
|
28
|
+
referer = referer or self.main_url,
|
29
|
+
subtitles = []
|
30
|
+
)
|
31
|
+
for video in api_data["urls"]
|
32
|
+
]
|
33
|
+
|
34
|
+
return results[0] if len(results) == 1 else results
|
@@ -0,0 +1,25 @@
|
|
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 TurboImgz(ExtractorBase):
|
7
|
+
name = "TurboImgz"
|
8
|
+
main_url = "https://turbo.imgz.me"
|
9
|
+
|
10
|
+
async def extract(self, url, referer=None) -> ExtractResult:
|
11
|
+
if referer:
|
12
|
+
self.oturum.headers.update({"Referer": referer})
|
13
|
+
|
14
|
+
istek = await self.oturum.get(url)
|
15
|
+
istek.raise_for_status()
|
16
|
+
|
17
|
+
if video_match := re.search(r'file: "(.*)",', istek.text):
|
18
|
+
return ExtractResult(
|
19
|
+
name = self.name,
|
20
|
+
url = video_match[1],
|
21
|
+
referer = referer or self.main_url,
|
22
|
+
subtitles = []
|
23
|
+
)
|
24
|
+
else:
|
25
|
+
raise ValueError("File not found in response.")
|