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.
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,7 +1,6 @@
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
3
+ from KekikStream.Core import ExtractorBase, ExtractResult, Subtitle, HTMLHelper
5
4
 
6
5
  class ContentX(ExtractorBase):
7
6
  name = "ContentX"
@@ -20,78 +19,36 @@ class ContentX(ExtractorBase):
20
19
  def can_handle_url(self, url: str) -> bool:
21
20
  return any(domain in url for domain in self.supported_domains)
22
21
 
23
- async def extract(self, url, referer=None) -> list[ExtractResult]:
24
- if referer:
25
- self.httpx.headers.update({"Referer": referer})
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})
26
25
 
27
- # Dinamik base URL kullan
28
- base_url = self.get_base_url(url)
26
+ resp = await self.httpx.get(url)
27
+ sel = HTMLHelper(resp.text)
29
28
 
30
- istek = await self.httpx.get(url)
31
- istek.raise_for_status()
32
- i_source = istek.text
33
-
34
- i_extract = re.search(r"window\.openPlayer\('([^']+)'", i_source)
35
- if not i_extract:
36
- raise ValueError("i_extract is null")
37
- i_extract_value = i_extract[1]
29
+ v_id = sel.regex_first(r"window\.openPlayer\('([^']+)'")
30
+ if not v_id:
31
+ raise ValueError(f"ContentX: ID bulunamadı. {url}")
38
32
 
39
33
  subtitles = []
40
- sub_urls = set()
41
- for match in re.finditer(r'"file":"([^"]+)","label":"([^"]+)"', i_source):
42
- sub_url, sub_lang = match.groups()
43
-
44
- if sub_url in sub_urls:
45
- continue
46
-
47
- sub_urls.add(sub_url)
48
- subtitles.append(
49
- Subtitle(
50
- name = sub_lang.replace("\\u0131", "ı")
51
- .replace("\\u0130", "İ")
52
- .replace("\\u00fc", "ü")
53
- .replace("\\u00e7", "ç"),
54
- url = self.fix_url(sub_url.replace("\\", ""))
55
- )
56
- )
57
-
58
- # base_url kullan (contentx.me yerine)
59
- vid_source_request = await self.httpx.get(f"{base_url}/source2.php?v={i_extract_value}", headers={"Referer": referer or base_url})
60
- vid_source_request.raise_for_status()
61
-
62
- vid_source = vid_source_request.text
63
- vid_extract = re.search(r'file":"([^"]+)"', vid_source)
64
- if not vid_extract:
65
- raise ValueError("vidExtract is null")
66
-
67
- m3u_link = vid_extract[1].replace("\\", "")
68
- results = [
69
- ExtractResult(
70
- name = self.name,
71
- url = m3u_link,
72
- referer = url,
73
- subtitles = subtitles
74
- )
75
- ]
76
-
77
- if i_dublaj := re.search(r',\"([^"]+)\",\"Türkçe"', i_source):
78
- dublaj_value = i_dublaj[1]
79
- dublaj_source_request = await self.httpx.get(f"{base_url}/source2.php?v={dublaj_value}", headers={"Referer": referer or base_url})
80
- dublaj_source_request.raise_for_status()
81
-
82
- dublaj_source = dublaj_source_request.text
83
- dublaj_extract = re.search(r'file":"([^"]+)"', dublaj_source)
84
- if not dublaj_extract:
85
- raise ValueError("dublajExtract is null")
86
-
87
- dublaj_link = dublaj_extract[1].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
- )
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}")
96
53
 
97
54
  return results[0] if len(results) == 1 else results
@@ -1,86 +1,42 @@
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 AESManager
5
- import re, 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
- if referer:
13
- self.httpx.headers.update({"Referer": referer})
14
-
15
- istek = await self.httpx.get(url)
16
- istek.raise_for_status()
17
- i_source = istek.text
18
-
19
- m3u_link = None
20
- subtitles = []
21
-
22
- # bePlayer pattern
23
- be_player_match = re.search(r"bePlayer\('([^']+)',\s*'(\{[^}]+\})'\);", i_source)
24
- if be_player_match:
25
- be_player_pass = be_player_match.group(1)
26
- be_player_data = be_player_match.group(2)
27
-
28
- try:
29
- # AES decrypt
30
- decrypted = AESManager.decrypt(be_player_data, be_player_pass)
31
- data = json.loads(decrypted)
32
-
33
- m3u_link = data.get("video_location")
34
-
35
- # Altyazıları işle
36
- str_subtitles = data.get("strSubtitles", [])
37
- if str_subtitles:
38
- for sub in str_subtitles:
39
- label = sub.get("label", "")
40
- file = sub.get("file", "")
41
- # Forced altyazıları hariç tut
42
- if "Forced" in label:
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 = re.search(r'file:"([^"]+)"', i_source)
58
- if file_match:
59
- m3u_link = file_match.group(1)
60
-
61
- # tracks pattern for subtitles
62
- tracks_match = re.search(r'tracks:\[([^\]]+)', i_source)
63
- if tracks_match:
64
- try:
65
- tracks_str = f"[{tracks_match.group(1)}]"
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)
@@ -1,38 +1,24 @@
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 DzenRu(ExtractorBase):
7
6
  name = "DzenRu"
8
7
  main_url = "https://dzen.ru"
9
8
 
10
- async def extract(self, url, referer=None) -> ExtractResult:
9
+ async def extract(self, url: str, referer: str = None) -> ExtractResult:
11
10
  video_key = url.split("/")[-1]
12
- video_url = f"{self.main_url}/embed/{video_key}"
11
+ v_url = f"{self.main_url}/embed/{video_key}"
13
12
 
14
13
  if referer:
15
14
  self.httpx.headers.update({"Referer": referer})
16
15
 
17
- istek = await self.httpx.get(video_url)
18
- istek.raise_for_status()
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}")
19
23
 
20
- # okcdn.ru linklerini bul
21
- matches = re.findall(r'https://vd\d+\.okcdn\.ru/\?[^"\'\\\s]+', istek.text)
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)
@@ -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, Subtitle
4
- import re
3
+ from KekikStream.Core import ExtractorBase, ExtractResult, HTMLHelper
5
4
  from urllib.parse import urlparse, parse_qs
6
5
 
7
6
  class ExPlay(ExtractorBase):
8
7
  name = "ExPlay"
9
8
  main_url = "https://explay.store"
10
9
 
11
- async def extract(self, url, referer=None) -> ExtractResult:
12
- ext_ref = referer or ""
10
+ async def extract(self, url: str, referer: str = None) -> ExtractResult:
11
+ self.httpx.headers.update({"Referer": referer or url})
13
12
 
14
- # URL parsing for partKey
15
- parsed = urlparse(url)
16
- params = parse_qs(parsed.query)
17
- part_key = params.get("partKey", [""])[0]
18
- clean_url = url.split("?partKey=")[0]
19
-
20
- if referer:
21
- self.httpx.headers.update({"Referer": referer})
22
-
23
- istek = await self.httpx.get(clean_url)
24
- istek.raise_for_status()
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)
25
17
 
26
- # videoUrl çıkar
27
- video_url_match = re.search(r'videoUrl":"([^",]+)"', istek.text)
28
- if not video_url_match:
29
- raise ValueError("videoUrl not found")
30
- video_url = video_url_match[1].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}")
31
22
 
32
- # videoServer çıkar
33
- video_server_match = re.search(r'videoServer":"([^",]+)"', istek.text)
34
- if not video_server_match:
35
- raise ValueError("videoServer not found")
36
- video_server = video_server_match[1]
37
-
38
- # title çıkar
39
- title_match = re.search(r'title":"([^",]+)"', istek.text)
40
- title = title_match[1].split(".")[-1] if title_match else "Unknown"
23
+ params = parse_qs(urlparse(url).query)
24
+ part_key = params.get("partKey", [""])[0]
41
25
 
42
- if part_key and "turkce" in part_key.lower():
43
- title = part_key # Or nicer formatting like SetPlay
44
-
45
- # M3U8 link oluştur
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 = f"{self.name} - {title}",
50
- url = m3u_link,
51
- referer = clean_url,
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
  )
@@ -1,9 +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 Kekik.Sifreleme import Packer
5
- from selectolax.parser import HTMLParser
6
- import re
7
5
 
8
6
  class Filemoon(ExtractorBase):
9
7
  name = "Filemoon"
@@ -15,7 +13,8 @@ class Filemoon(ExtractorBase):
15
13
  "filemoon.in",
16
14
  "filemoon.sx",
17
15
  "filemoon.nl",
18
- "filemoon.com"
16
+ "filemoon.com",
17
+ "bysejikuar.com"
19
18
  ]
20
19
 
21
20
  def can_handle_url(self, url: str) -> bool:
@@ -32,63 +31,34 @@ class Filemoon(ExtractorBase):
32
31
  self.httpx.headers.update(default_headers)
33
32
 
34
33
  # İlk sayfayı al
35
- istek = await self.httpx.get(url)
36
- response = istek.text
37
- secici = HTMLParser(response)
34
+ istek = await self.httpx.get(url)
35
+ secici = HTMLHelper(istek.text)
38
36
 
39
37
  # Eğer iframe varsa, iframe'e git
40
- iframe_el = secici.css_first("iframe")
41
- iframe_src = iframe_el.attrs.get("src") if iframe_el else None
38
+ iframe_src = secici.select_attr("iframe", "src")
39
+ m3u8_url = None
42
40
 
43
- m3u8_url = None
44
-
45
- if not iframe_src:
46
- # Fallback: Script içinde ara (Kotlin: selectFirst("script:containsData(function(p,a,c,k,e,d))"))
47
- script_data = ""
48
- for script in secici.css("script"):
49
- if "function(p,a,c,k,e,d)" in script.text():
50
- script_data = script.text()
51
- break
52
-
53
- if script_data:
54
- unpacked = Packer.unpack(script_data)
55
- if match := re.search(r'sources:\[\{file:"(.*?)"', unpacked):
56
- m3u8_url = match.group(1)
57
- else:
58
- # Iframe varsa devam et
59
- iframe_url = self.fix_url(iframe_src)
60
- iframe_headers = default_headers.copy()
61
- iframe_headers["Accept-Language"] = "en-US,en;q=0.5"
62
-
63
- istek = await self.httpx.get(iframe_url, headers=iframe_headers)
64
- response = istek.text
65
- secici = HTMLParser(response)
66
-
67
- script_data = ""
68
- for script in secici.css("script"):
69
- if "function(p,a,c,k,e,d)" in script.text():
70
- script_data = script.text()
71
- break
72
-
73
- if script_data:
74
- unpacked = Packer.unpack(script_data)
75
- if match := re.search(r'sources:\[\{file:"(.*?)"', unpacked):
76
- m3u8_url = match.group(1)
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:"(.*?)"')
77
51
 
78
52
  if not m3u8_url:
79
- # Son çare: Normal response içinde ara
80
- if match := re.search(r'sources:\s*\[\s*\{\s*file:\s*"([^"]+)"', response):
81
- m3u8_url = match.group(1)
82
- elif match := re.search(r'file:\s*"([^"]*?\.m3u8[^"]*)"', response):
83
- m3u8_url = match.group(1)
53
+ # Fallback
54
+ m3u8_url = secici.regex_first(r'sources:\s*\[\s*\{\s*file:\s*"([^"]+)"') or secici.regex_first(r'file:\s*"([^\"]*?\.m3u8[^"]*)"')
84
55
 
85
56
  if not m3u8_url:
86
57
  raise ValueError(f"Filemoon: Video URL bulunamadı. {url}")
87
58
 
88
59
  return ExtractResult(
89
- name = self.name,
90
- url = self.fix_url(m3u8_url),
91
- referer = f"{self.main_url}/",
92
- user_agent = default_headers["User-Agent"],
93
- 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"]
94
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
- 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
- }
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
- response.raise_for_status()
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
- 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 = 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)
@@ -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
- if referer:
21
- self.httpx.headers.update({"Referer": referer})
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)