KekikStream 2.2.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.

Potentially problematic release.


This version of KekikStream might be problematic. Click here for more details.

Files changed (88) hide show
  1. KekikStream/Core/Extractor/ExtractorBase.py +3 -2
  2. KekikStream/Core/Extractor/ExtractorLoader.py +8 -14
  3. KekikStream/Core/HTMLHelper.py +205 -0
  4. KekikStream/Core/Plugin/PluginBase.py +48 -12
  5. KekikStream/Core/Plugin/PluginLoader.py +13 -14
  6. KekikStream/Core/Plugin/PluginManager.py +2 -2
  7. KekikStream/Core/Plugin/PluginModels.py +0 -3
  8. KekikStream/Core/__init__.py +2 -0
  9. KekikStream/Extractors/Abstream.py +27 -0
  10. KekikStream/Extractors/CloseLoad.py +31 -56
  11. KekikStream/Extractors/ContentX.py +28 -71
  12. KekikStream/Extractors/DonilasPlay.py +34 -78
  13. KekikStream/Extractors/DzenRu.py +11 -25
  14. KekikStream/Extractors/ExPlay.py +20 -38
  15. KekikStream/Extractors/Filemoon.py +23 -53
  16. KekikStream/Extractors/HDMomPlayer.py +30 -0
  17. KekikStream/Extractors/HDPlayerSystem.py +13 -31
  18. KekikStream/Extractors/HotStream.py +27 -0
  19. KekikStream/Extractors/JFVid.py +3 -24
  20. KekikStream/Extractors/JetTv.py +21 -34
  21. KekikStream/Extractors/JetV.py +55 -0
  22. KekikStream/Extractors/MailRu.py +11 -29
  23. KekikStream/Extractors/MixPlayHD.py +17 -31
  24. KekikStream/Extractors/MixTiger.py +17 -40
  25. KekikStream/Extractors/MolyStream.py +25 -22
  26. KekikStream/Extractors/Odnoklassniki.py +41 -105
  27. KekikStream/Extractors/PeaceMakerst.py +20 -47
  28. KekikStream/Extractors/PixelDrain.py +9 -16
  29. KekikStream/Extractors/PlayerFilmIzle.py +23 -46
  30. KekikStream/Extractors/RapidVid.py +23 -36
  31. KekikStream/Extractors/SetPlay.py +19 -44
  32. KekikStream/Extractors/SetPrime.py +3 -6
  33. KekikStream/Extractors/SibNet.py +8 -19
  34. KekikStream/Extractors/Sobreatsesuyp.py +25 -47
  35. KekikStream/Extractors/TRsTX.py +25 -55
  36. KekikStream/Extractors/TurboImgz.py +8 -16
  37. KekikStream/Extractors/TurkeyPlayer.py +5 -5
  38. KekikStream/Extractors/VCTPlay.py +10 -28
  39. KekikStream/Extractors/Veev.py +145 -0
  40. KekikStream/Extractors/VidBiz.py +62 -0
  41. KekikStream/Extractors/VidHide.py +59 -34
  42. KekikStream/Extractors/VidMoly.py +67 -89
  43. KekikStream/Extractors/VidMoxy.py +17 -29
  44. KekikStream/Extractors/VidPapi.py +26 -58
  45. KekikStream/Extractors/VideoSeyred.py +21 -42
  46. KekikStream/Extractors/Videostr.py +58 -0
  47. KekikStream/Extractors/Vidoza.py +18 -0
  48. KekikStream/Extractors/Vtbe.py +38 -0
  49. KekikStream/Extractors/YTDLP.py +2 -2
  50. KekikStream/Extractors/YildizKisaFilm.py +13 -31
  51. KekikStream/Extractors/Zeus.py +61 -0
  52. KekikStream/Plugins/BelgeselX.py +108 -99
  53. KekikStream/Plugins/DiziBox.py +61 -106
  54. KekikStream/Plugins/DiziMom.py +179 -0
  55. KekikStream/Plugins/DiziPal.py +104 -192
  56. KekikStream/Plugins/DiziYou.py +66 -149
  57. KekikStream/Plugins/Dizilla.py +93 -126
  58. KekikStream/Plugins/FilmBip.py +102 -72
  59. KekikStream/Plugins/FilmEkseni.py +199 -0
  60. KekikStream/Plugins/FilmMakinesi.py +101 -64
  61. KekikStream/Plugins/FilmModu.py +35 -59
  62. KekikStream/Plugins/Filmatek.py +184 -0
  63. KekikStream/Plugins/FilmciBaba.py +155 -0
  64. KekikStream/Plugins/FullHDFilmizlesene.py +32 -78
  65. KekikStream/Plugins/HDFilm.py +243 -0
  66. KekikStream/Plugins/HDFilmCehennemi.py +261 -222
  67. KekikStream/Plugins/JetFilmizle.py +117 -98
  68. KekikStream/Plugins/KultFilmler.py +153 -143
  69. KekikStream/Plugins/RecTV.py +53 -49
  70. KekikStream/Plugins/RoketDizi.py +92 -123
  71. KekikStream/Plugins/SelcukFlix.py +86 -95
  72. KekikStream/Plugins/SetFilmIzle.py +105 -143
  73. KekikStream/Plugins/SezonlukDizi.py +106 -128
  74. KekikStream/Plugins/Sinefy.py +194 -166
  75. KekikStream/Plugins/SinemaCX.py +159 -113
  76. KekikStream/Plugins/Sinezy.py +44 -73
  77. KekikStream/Plugins/SuperFilmGeldi.py +28 -52
  78. KekikStream/Plugins/UgurFilm.py +94 -72
  79. KekikStream/Plugins/Watch32.py +160 -0
  80. KekikStream/Plugins/YabanciDizi.py +250 -0
  81. {kekikstream-2.2.9.dist-info → kekikstream-2.5.3.dist-info}/METADATA +1 -1
  82. kekikstream-2.5.3.dist-info/RECORD +99 -0
  83. {kekikstream-2.2.9.dist-info → kekikstream-2.5.3.dist-info}/WHEEL +1 -1
  84. KekikStream/Plugins/FullHDFilm.py +0 -254
  85. kekikstream-2.2.9.dist-info/RECORD +0 -82
  86. {kekikstream-2.2.9.dist-info → kekikstream-2.5.3.dist-info}/entry_points.txt +0 -0
  87. {kekikstream-2.2.9.dist-info → kekikstream-2.5.3.dist-info}/licenses/LICENSE +0 -0
  88. {kekikstream-2.2.9.dist-info → kekikstream-2.5.3.dist-info}/top_level.txt +0 -0
@@ -1,8 +1,7 @@
1
1
  # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
2
 
3
- from KekikStream.Core import ExtractorBase, ExtractResult, Subtitle
3
+ from KekikStream.Core import ExtractorBase, ExtractResult, Subtitle, HTMLHelper
4
4
  from Kekik.Sifreleme import Packer
5
- import re
6
5
 
7
6
  class PlayerFilmIzle(ExtractorBase):
8
7
  name = "PlayerFilmIzle"
@@ -12,58 +11,36 @@ class PlayerFilmIzle(ExtractorBase):
12
11
  return "filmizle.in" in url or "fireplayer" in url.lower()
13
12
 
14
13
  async def extract(self, url: str, referer: str = None) -> ExtractResult:
15
- # Kotlin tarafında referer mainUrl olarak zorlanmış
16
- ext_ref = self.main_url
17
- self.httpx.headers.update({"Referer": ext_ref})
14
+ ref = referer or self.main_url
15
+ self.httpx.headers.update({"Referer": ref})
18
16
 
19
- istek = await self.httpx.get(url)
20
- video_req = istek.text
17
+ resp = await self.httpx.get(url)
18
+ sel = HTMLHelper(resp.text)
21
19
 
22
20
  subtitles = []
23
- if sub_match := re.search(r'playerjsSubtitle = "([^"]*)"', video_req, re.IGNORECASE):
24
- sub_yakala = sub_match.group(1)
25
- # Format örneği: [dil]url
26
- # Kotlin kodunda: subYakala.substringAfter("]") -> url
27
- # subYakala.substringBefore("]").removePrefix("[") -> lang
28
- if "]" in sub_yakala:
29
- sub_lang_raw, sub_url = sub_yakala.split("]", 1)
30
- sub_lang = sub_lang_raw.replace("[", "")
31
- subtitles.append(Subtitle(name=sub_lang, url=sub_url))
21
+ if raw_subs := sel.regex_first(r'playerjsSubtitle\s*=\s*"([^"]*)"'):
22
+ for lang, link in HTMLHelper(raw_subs).regex_all(r'\[(.*?)\](https?://[^\s\",]+)'):
23
+ subtitles.append(Subtitle(name=lang.strip(), url=link.strip()))
32
24
 
33
- # Packed script varsa unpack et
34
- unpacked = Packer.unpack(video_req) if Packer.detect_packed(video_req) else video_req
35
-
36
- # Data yakalama: FirePlayer("DATA", ...) formatından
37
- data_match = re.search(r'FirePlayer\s*\(\s*["\']([a-f0-9]+)["\']', unpacked, re.IGNORECASE)
38
- data_val = data_match.group(1) if data_match else None
25
+ content = Packer.unpack(resp.text) if Packer.detect_packed(resp.text) else resp.text
26
+ data_val = HTMLHelper(content).regex_first(r'FirePlayer\s*\(\s*["\']([a-f0-9]+)["\']')
39
27
 
40
28
  if not data_val:
41
- raise ValueError("PlayerFilmIzle: Data bulunamadı")
42
-
43
- url_post = f"{self.main_url}/player/index.php?data={data_val}&do=getVideo"
44
-
45
- post_headers = {
46
- "Referer": ext_ref,
47
- "X-Requested-With": "XMLHttpRequest"
48
- }
49
-
50
- # Kotlin'de post data: "hash" -> data, "r" -> ""
51
- post_data = {"hash": data_val, "r": ""}
52
-
53
- response = await self.httpx.post(url_post, data=post_data, headers=post_headers)
54
- get_url = response.text.replace("\\", "")
55
-
56
- m3u8_url = ""
57
- if url_yakala := re.search(r'"securedLink":"([^"]*)"', get_url, re.IGNORECASE):
58
- m3u8_url = url_yakala.group(1)
29
+ raise ValueError(f"PlayerFilmIzle: Data bulunamadı. {url}")
59
30
 
31
+ resp_vid = await self.httpx.post(
32
+ f"{self.main_url}/player/index.php?data={data_val}&do=getVideo",
33
+ data = {"hash": data_val, "r": ""},
34
+ headers = {"X-Requested-With": "XMLHttpRequest"}
35
+ )
36
+
37
+ m3u8_url = HTMLHelper(resp_vid.text).regex_first(r'"securedLink":"([^"]+)"')
60
38
  if not m3u8_url:
61
- raise ValueError("PlayerFilmIzle: M3U8 linki bulunamadı")
39
+ raise ValueError(f"PlayerFilmIzle: Video URL bulunamadı. {url}")
62
40
 
63
41
  return ExtractResult(
64
- name = self.name,
65
- url = m3u8_url,
66
- referer = ext_ref,
67
- user_agent = self.httpx.headers.get("User-Agent", None),
68
- subtitles = subtitles
42
+ name = self.name,
43
+ url = m3u8_url.replace("\\", ""),
44
+ referer = ref,
45
+ subtitles = subtitles
69
46
  )
@@ -1,8 +1,8 @@
1
1
  # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
2
 
3
- from KekikStream.Core import ExtractorBase, ExtractResult, Subtitle
3
+ from KekikStream.Core import ExtractorBase, ExtractResult, Subtitle, HTMLHelper
4
4
  from Kekik.Sifreleme import Packer, HexCodec, StreamDecoder
5
- import re, base64
5
+ import base64
6
6
 
7
7
  class RapidVid(ExtractorBase):
8
8
  name = "RapidVid"
@@ -14,56 +14,43 @@ class RapidVid(ExtractorBase):
14
14
  def can_handle_url(self, url: str) -> bool:
15
15
  return any(domain in url for domain in self.supported_domains)
16
16
 
17
- async def extract(self, url, referer=None) -> ExtractResult:
17
+ async def extract(self, url: str, referer: str = None) -> ExtractResult:
18
18
  if referer:
19
19
  self.httpx.headers.update({"Referer": referer})
20
20
 
21
- istek = await self.httpx.get(url)
22
- istek.raise_for_status()
21
+ resp = await self.httpx.get(url)
22
+ sel = HTMLHelper(resp.text)
23
23
 
24
- subtitles = []
25
- subtitle_matches = re.findall(r'captions\",\"file\":\"([^\"]+)\",\"label\":\"([^\"]+)\"', istek.text)
26
- seen_subtitles = set()
27
-
28
- for sub_url, sub_lang in subtitle_matches:
29
- if sub_url in seen_subtitles:
30
- continue
31
-
32
- seen_subtitles.add(sub_url)
33
- decoded_lang = (
34
- sub_lang.replace("\\u0131", "ı")
35
- .replace("\\u0130", "İ")
36
- .replace("\\u00fc", "ü")
37
- .replace("\\u00e7", "ç")
38
- )
39
- subtitles.append(Subtitle(name=decoded_lang, url=sub_url.replace("\\", "")))
24
+ subtitles = []
25
+ for s_url, s_lang in sel.regex_all(r'captions","file":"([^\"]+)","label":"([^\"]+)"'):
26
+ decoded_lang = s_lang.encode().decode('unicode_escape')
27
+ subtitles.append(Subtitle(name=decoded_lang, url=s_url.replace("\\", "")))
40
28
 
41
29
  try:
42
- decoded_url = None
30
+ video_url = None
43
31
 
44
- # Method 1: file": "..." pattern (HexCodec)
45
- if extracted_value := re.search(r'file": "(.*)",', istek.text):
46
- escaped_hex = extracted_value[1]
47
- decoded_url = HexCodec.decode(escaped_hex)
32
+ # Method 1: HexCodec pattern
33
+ if hex_data := sel.regex_first(r'file": "(.*)",'):
34
+ video_url = HexCodec.decode(hex_data)
48
35
 
49
36
  # Method 2: av('...') pattern
50
- elif av_encoded := re.search(r"av\('([^']+)'\)", istek.text):
51
- decoded_url = self.decode_secret(av_encoded[1])
37
+ elif av_data := sel.regex_first(r"av\('([^']+)'\)"):
38
+ video_url = self.decode_secret(av_data)
52
39
 
53
- # Method 3: Packed script with dc_* function (StreamDecoder)
54
- elif Packer.detect_packed(istek.text):
55
- unpacked = Packer.unpack(istek.text)
56
- decoded_url = StreamDecoder.extract_stream_url(unpacked)
40
+ # Method 3: Packed dc_*
41
+ elif Packer.detect_packed(resp.text):
42
+ unpacked = Packer.unpack(resp.text)
43
+ video_url = StreamDecoder.extract_stream_url(unpacked)
57
44
 
58
- if not decoded_url:
59
- raise ValueError("No valid video URL pattern found.")
45
+ if not video_url:
46
+ raise ValueError(f"RapidVid: Video URL bulunamadı. {url}")
60
47
 
61
48
  except Exception as hata:
62
- raise RuntimeError(f"Extraction failed: {hata}") from hata
49
+ raise RuntimeError(f"RapidVid: Extraction failed: {hata}") from hata
63
50
 
64
51
  return ExtractResult(
65
52
  name = self.name,
66
- url = decoded_url,
53
+ url = video_url,
67
54
  referer = self.main_url,
68
55
  subtitles = subtitles
69
56
  )
@@ -1,66 +1,41 @@
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
- import re
6
5
 
7
6
  class SetPlay(ExtractorBase):
8
7
  name = "SetPlay"
9
8
  main_url = "https://setplay.shop"
10
9
 
11
- # Birden fazla domain destekle
12
10
  supported_domains = ["setplay.cfd", "setplay.shop", "setplay.site"]
13
11
 
14
12
  def can_handle_url(self, url: str) -> bool:
15
13
  return any(domain in url for domain in self.supported_domains)
16
14
 
17
- async def extract(self, url, referer=None) -> ExtractResult:
18
- ext_ref = referer or ""
19
-
20
- if referer:
21
- self.httpx.headers.update({"Referer": referer})
22
-
23
- # Dinamik base URL kullan
15
+ async def extract(self, url: str, referer: str = None) -> ExtractResult:
16
+ self.httpx.headers.update({"Referer": referer or url})
24
17
  base_url = self.get_base_url(url)
25
18
 
26
- istek = await self.httpx.get(url)
27
- istek.raise_for_status()
28
-
29
- # videoUrl çıkar
30
- video_url_match = re.search(r'videoUrl":"([^",]+)"', istek.text)
31
- if not video_url_match:
32
- raise ValueError("videoUrl not found")
33
- video_url = video_url_match[1].replace("\\", "")
19
+ resp = await self.httpx.get(url)
20
+ sel = HTMLHelper(resp.text)
34
21
 
35
- # videoServer çıkar
36
- video_server_match = re.search(r'videoServer":"([^",]+)"', istek.text)
37
- if not video_server_match:
38
- raise ValueError("videoServer not found")
39
- video_server = video_server_match[1]
22
+ v_url = sel.regex_first(r'videoUrl":"([^",]+)"')
23
+ v_srv = sel.regex_first(r'videoServer":"([^",]+)"')
24
+ if not v_url or not v_srv:
25
+ raise ValueError(f"SetPlay: Video url/server bulunamadı. {url}")
40
26
 
41
- # title çıkar (opsiyonel)
42
- title_match = re.search(r'title":"([^",]+)"', istek.text)
43
- title_base = title_match[1].split(".")[-1] if title_match else "Unknown"
27
+ params = parse_qs(urlparse(url).query)
28
+ part_key = params.get("partKey", [""])[0].lower()
44
29
 
45
- # partKey logic
46
- parsed = urlparse(url)
47
- params = parse_qs(parsed.query)
48
- part_key = params.get("partKey", [""])[0]
49
-
50
- name_suffix = ""
51
- if "turkcedublaj" in part_key.lower():
52
- name_suffix = "Dublaj"
53
- elif "turkcealtyazi" in part_key.lower():
54
- name_suffix = "Altyazı"
30
+ suffix = "Bilinmiyor"
31
+ if "turkcedublaj" in part_key: suffix = "Dublaj"
32
+ elif "turkcealtyazi" in part_key: suffix = "Altyazı"
55
33
  else:
56
- name_suffix = title_base
57
-
58
- # M3U8 link oluştur - base_url kullan (main_url yerine)
59
- m3u_link = f"{base_url}{video_url}?s={video_server}"
34
+ title = sel.regex_first(r'title":"([^",]+)"')
35
+ if title: suffix = title.split(".")[-1]
60
36
 
61
37
  return ExtractResult(
62
- name = f"{self.name} - {name_suffix}",
63
- url = m3u_link,
64
- referer = url,
65
- subtitles = []
38
+ name = f"{self.name} - {suffix}",
39
+ url = f"{base_url}{v_url.replace('\\', '')}?s={v_srv}",
40
+ referer = url
66
41
  )
@@ -1,8 +1,7 @@
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
- import re
6
5
 
7
6
  class SetPrime(ExtractorBase):
8
7
  name = "SetPrime"
@@ -25,11 +24,9 @@ class SetPrime(ExtractorBase):
25
24
  response.raise_for_status()
26
25
 
27
26
  # Links parse
28
- links_match = re.search(r'Links":\["([^"\]]+)"', response.text)
29
- if not links_match:
27
+ link_suffix = HTMLHelper(response.text).regex_first(r'Links":\["([^"\]]+)"')
28
+ if not link_suffix:
30
29
  raise ValueError("Links not found in SetPrime response")
31
-
32
- link_suffix = links_match.group(1)
33
30
  if not link_suffix.startswith("/"):
34
31
  raise ValueError("Links not valid (must start with /)")
35
32
 
@@ -1,28 +1,17 @@
1
1
  # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
2
 
3
- from KekikStream.Core import ExtractorBase, ExtractResult
4
- import re
3
+ from KekikStream.Core import ExtractorBase, ExtractResult, HTMLHelper
5
4
 
6
5
  class SibNet(ExtractorBase):
7
6
  name = "SibNet"
8
7
  main_url = "https://video.sibnet.ru"
9
8
 
10
- async def extract(self, url, referer=None) -> ExtractResult:
11
- if referer:
12
- self.httpx.headers.update({"Referer": referer})
9
+ async def extract(self, url: str, referer: str = None) -> ExtractResult:
10
+ self.httpx.headers.update({"Referer": referer or url})
13
11
 
14
- response = await self.httpx.get(url)
15
- response.raise_for_status()
12
+ resp = await self.httpx.get(url)
13
+ path = HTMLHelper(resp.text).regex_first(r'player\.src\(\[\{src: "([^\"]+)"')
14
+ if not path:
15
+ raise ValueError(f"SibNet: Video yolu bulunamadı. {url}")
16
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
- return ExtractResult(
24
- name = self.name,
25
- url = m3u_link,
26
- referer = url,
27
- subtitles = []
28
- )
17
+ return ExtractResult(name=self.name, url=f"{self.main_url}{path}", referer=url)
@@ -1,59 +1,37 @@
1
1
  # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
2
 
3
- from KekikStream.Core import ExtractorBase, ExtractResult
4
- import re, json
3
+ from KekikStream.Core import ExtractorBase, ExtractResult, HTMLHelper
4
+ import json
5
5
 
6
6
  class Sobreatsesuyp(ExtractorBase):
7
7
  name = "Sobreatsesuyp"
8
8
  main_url = "https://sobreatsesuyp.com"
9
9
 
10
- async def extract(self, url, referer=None) -> ExtractResult:
11
- if referer:
12
- self.httpx.headers.update({"Referer": referer})
10
+ async def extract(self, url: str, referer: str = None) -> list[ExtractResult] | ExtractResult:
11
+ ref = referer or self.main_url
12
+ self.httpx.headers.update({"Referer": ref})
13
13
 
14
- istek = await self.httpx.get(url)
15
- istek.raise_for_status()
14
+ resp = await self.httpx.get(url)
15
+ path = HTMLHelper(resp.text).regex_first(r'file":"([^\"]+)')
16
+ if not path:
17
+ raise ValueError(f"Sobreatsesuyp: File path bulunamadı. {url}")
16
18
 
17
- file_match = re.search(r'file\":\"([^\"]+)', istek.text)
18
- if not file_match:
19
- raise ValueError("File not found in response.")
19
+ post_resp = await self.httpx.post(f"{self.main_url}/{path.replace('\\', '')}")
20
+ data_list = post_resp.json()[1:] if isinstance(post_resp.json(), list) else []
20
21
 
21
- file_path = file_match[1].replace("\\", "")
22
- post_link = f"{self.main_url}/{file_path}"
23
-
24
- post_istek = await self.httpx.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:
22
+ results = []
23
+ for item in data_list:
37
24
  title = item.get("title")
38
25
  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.httpx.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
26
+ if title and file:
27
+ playlist_resp = await self.httpx.post(f"{self.main_url}/playlist/{file.lstrip('/')}.txt")
28
+ results.append(ExtractResult(
29
+ name = f"{self.name} - {title}",
30
+ url = playlist_resp.text,
31
+ referer = self.main_url
32
+ ))
33
+
34
+ if not results:
35
+ raise ValueError(f"Sobreatsesuyp: Video bulunamadı. {url}")
36
+
37
+ return results[0] if len(results) == 1 else results
@@ -1,67 +1,37 @@
1
1
  # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
2
 
3
- from KekikStream.Core import ExtractorBase, ExtractResult
4
- import re, json
3
+ from KekikStream.Core import ExtractorBase, ExtractResult, HTMLHelper
4
+ import json
5
5
 
6
6
  class TRsTX(ExtractorBase):
7
7
  name = "TRsTX"
8
8
  main_url = "https://trstx.org"
9
9
 
10
- async def extract(self, url, referer=None) -> list[ExtractResult]:
11
- if referer:
12
- self.httpx.headers.update({"Referer": referer})
10
+ async def extract(self, url: str, referer: str = None) -> list[ExtractResult] | ExtractResult:
11
+ ref = referer or self.main_url
12
+ self.httpx.headers.update({"Referer": ref})
13
13
 
14
- istek = await self.httpx.get(url)
15
- istek.raise_for_status()
14
+ resp = await self.httpx.get(url)
15
+ path = HTMLHelper(resp.text).regex_first(r'file":"([^\"]+)')
16
+ if not path:
17
+ raise ValueError(f"TRsTX: File path bulunamadı. {url}")
16
18
 
17
- file_match = re.search(r'file\":\"([^\"]+)', istek.text)
18
- if not file_match:
19
- raise ValueError("File not found in response.")
19
+ post_resp = await self.httpx.post(f"{self.main_url}/{path.replace('\\', '')}")
20
+ data_list = post_resp.json()[1:] if isinstance(post_resp.json(), list) else []
20
21
 
21
- file_path = file_match[1].replace("\\", "")
22
- post_link = f"{self.main_url}/{file_path}"
23
-
24
- post_istek = await self.httpx.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:
22
+ results = []
23
+ for item in data_list:
38
24
  title = item.get("title")
39
25
  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.httpx.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
26
+ if title and file:
27
+ playlist_resp = await self.httpx.post(f"{self.main_url}/playlist/{file.lstrip('/')}.txt")
28
+ results.append(ExtractResult(
29
+ name = f"{self.name} - {title}",
30
+ url = playlist_resp.text,
31
+ referer = self.main_url
32
+ ))
33
+
34
+ if not results:
35
+ raise ValueError(f"TRsTX: Video bulunamadı. {url}")
36
+
37
+ return results[0] if len(results) == 1 else results
@@ -1,25 +1,17 @@
1
1
  # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
2
 
3
- from KekikStream.Core import ExtractorBase, ExtractResult
4
- import re
3
+ from KekikStream.Core import ExtractorBase, ExtractResult, HTMLHelper
5
4
 
6
5
  class TurboImgz(ExtractorBase):
7
6
  name = "TurboImgz"
8
7
  main_url = "https://turbo.imgz.me"
9
8
 
10
- async def extract(self, url, referer=None) -> ExtractResult:
11
- if referer:
12
- self.httpx.headers.update({"Referer": referer})
9
+ async def extract(self, url: str, referer: str = None) -> ExtractResult:
10
+ self.httpx.headers.update({"Referer": referer or url})
13
11
 
14
- istek = await self.httpx.get(url)
15
- istek.raise_for_status()
12
+ resp = await self.httpx.get(url)
13
+ v_url = HTMLHelper(resp.text).regex_first(r'file: "(.*)",')
14
+ if not v_url:
15
+ raise ValueError(f"TurboImgz: Video bulunamadı. {url}")
16
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.")
17
+ return ExtractResult(name=self.name, url=v_url, referer=referer or self.main_url)
@@ -1,7 +1,7 @@
1
1
  # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
2
 
3
- from KekikStream.Core import ExtractorBase, ExtractResult, Subtitle
4
- import re, json
3
+ from KekikStream.Core import ExtractorBase, ExtractResult, Subtitle, HTMLHelper
4
+ import json
5
5
 
6
6
  class TurkeyPlayer(ExtractorBase):
7
7
  name = "TurkeyPlayer"
@@ -14,11 +14,11 @@ class TurkeyPlayer(ExtractorBase):
14
14
  istek = await self.httpx.get(url)
15
15
  page_content = istek.text
16
16
 
17
- video_json_match = re.search(r'var\s+video\s*=\s*(\{.*?\});', page_content, re.DOTALL)
18
- if not video_json_match:
17
+ video_json_str = HTMLHelper(page_content).regex_first(r'(?s)var\s+video\s*=\s*(\{.*?\});')
18
+ if not video_json_str:
19
19
  raise ValueError("TurkeyPlayer: Video JSON bulunamadı")
20
20
 
21
- video_data = json.loads(video_json_match.group(1))
21
+ video_data = json.loads(video_json_str)
22
22
 
23
23
  video_id = video_data.get("id")
24
24
  video_md5 = video_data.get("md5")
@@ -7,35 +7,17 @@ class VCTPlay(ExtractorBase):
7
7
  name = "VCTPlay"
8
8
  main_url = "https://vctplay.site"
9
9
 
10
- async def extract(self, url, referer=None) -> ExtractResult:
11
- if referer:
12
- self.httpx.headers.update({"Referer": referer})
10
+ async def extract(self, url: str, referer: str = None) -> ExtractResult:
11
+ v_id = url.split("/")[-1].split("?")[0]
12
+ params = parse_qs(urlparse(url).query)
13
+ part_key = params.get("partKey", [""])[0].lower()
13
14
 
14
- # URL'den video ID'sini çıkar
15
- # https://vctplay.site/video/2hjDGco5exdv -> 2hjDGco5exdv
16
- video_id = url.split("/")[-1]
17
- if "?" in video_id:
18
- video_id = video_id.split("?")[0]
19
-
20
- # Manifests URL oluştur
21
- master_url = f"{self.main_url}/manifests/{video_id}/master.txt"
22
-
23
- # partKey'den isim belirle
24
- parsed = urlparse(url)
25
- params = parse_qs(parsed.query)
26
- part_key = params.get("partKey", [""])[0]
27
-
28
- name_suffix = ""
29
- if "turkcedublaj" in part_key.lower():
30
- name_suffix = "Dublaj"
31
- elif "turkcealtyazi" in part_key.lower():
32
- name_suffix = "Altyazı"
33
-
34
- display_name = f"{self.name} - {name_suffix}" if name_suffix else self.name
15
+ suffix = ""
16
+ if "turkcedublaj" in part_key: suffix = "Dublaj"
17
+ elif "turkcealtyazi" in part_key: suffix = "Altyazı"
35
18
 
36
19
  return ExtractResult(
37
- name = display_name,
38
- url = master_url,
39
- referer = f"{self.main_url}/",
40
- subtitles = []
20
+ name = f"{self.name} - {suffix}" if suffix else self.name,
21
+ url = f"{self.main_url}/manifests/{v_id}/master.txt",
22
+ referer = f"{self.main_url}/"
41
23
  )