KekikStream 2.4.2__py3-none-any.whl → 2.4.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 (72) hide show
  1. KekikStream/Core/Extractor/ExtractorBase.py +3 -2
  2. KekikStream/Core/HTMLHelper.py +134 -40
  3. KekikStream/Core/Plugin/PluginBase.py +3 -2
  4. KekikStream/Extractors/CloseLoad.py +30 -54
  5. KekikStream/Extractors/ContentX.py +27 -72
  6. KekikStream/Extractors/DonilasPlay.py +33 -77
  7. KekikStream/Extractors/DzenRu.py +10 -24
  8. KekikStream/Extractors/ExPlay.py +20 -38
  9. KekikStream/Extractors/Filemoon.py +19 -45
  10. KekikStream/Extractors/HDMomPlayer.py +24 -56
  11. KekikStream/Extractors/HDPlayerSystem.py +13 -31
  12. KekikStream/Extractors/HotStream.py +14 -32
  13. KekikStream/Extractors/JFVid.py +3 -24
  14. KekikStream/Extractors/JetTv.py +21 -34
  15. KekikStream/Extractors/MailRu.py +11 -29
  16. KekikStream/Extractors/MixPlayHD.py +15 -28
  17. KekikStream/Extractors/MixTiger.py +17 -40
  18. KekikStream/Extractors/MolyStream.py +17 -21
  19. KekikStream/Extractors/Odnoklassniki.py +28 -104
  20. KekikStream/Extractors/PeaceMakerst.py +18 -45
  21. KekikStream/Extractors/PixelDrain.py +8 -16
  22. KekikStream/Extractors/PlayerFilmIzle.py +22 -41
  23. KekikStream/Extractors/RapidVid.py +21 -35
  24. KekikStream/Extractors/SetPlay.py +18 -43
  25. KekikStream/Extractors/SibNet.py +7 -17
  26. KekikStream/Extractors/Sobreatsesuyp.py +23 -45
  27. KekikStream/Extractors/TRsTX.py +23 -53
  28. KekikStream/Extractors/TurboImgz.py +7 -14
  29. KekikStream/Extractors/VCTPlay.py +10 -28
  30. KekikStream/Extractors/VidHide.py +10 -31
  31. KekikStream/Extractors/VidMoly.py +65 -99
  32. KekikStream/Extractors/VidMoxy.py +16 -27
  33. KekikStream/Extractors/VidPapi.py +24 -54
  34. KekikStream/Extractors/VideoSeyred.py +19 -40
  35. KekikStream/Extractors/Videostr.py +42 -99
  36. KekikStream/Extractors/Vidoza.py +8 -15
  37. KekikStream/Extractors/YildizKisaFilm.py +13 -31
  38. KekikStream/Plugins/BelgeselX.py +63 -69
  39. KekikStream/Plugins/DiziBox.py +16 -36
  40. KekikStream/Plugins/DiziMom.py +37 -129
  41. KekikStream/Plugins/DiziPal.py +26 -75
  42. KekikStream/Plugins/DiziYou.py +44 -152
  43. KekikStream/Plugins/Dizilla.py +18 -44
  44. KekikStream/Plugins/FilmBip.py +10 -24
  45. KekikStream/Plugins/FilmEkseni.py +12 -32
  46. KekikStream/Plugins/FilmMakinesi.py +24 -77
  47. KekikStream/Plugins/FilmModu.py +11 -18
  48. KekikStream/Plugins/Filmatek.py +13 -39
  49. KekikStream/Plugins/Full4kizle.py +33 -133
  50. KekikStream/Plugins/FullHDFilm.py +23 -93
  51. KekikStream/Plugins/FullHDFilmizlesene.py +10 -29
  52. KekikStream/Plugins/HDFilmCehennemi.py +27 -66
  53. KekikStream/Plugins/JetFilmizle.py +19 -20
  54. KekikStream/Plugins/KultFilmler.py +16 -50
  55. KekikStream/Plugins/RecTV.py +47 -85
  56. KekikStream/Plugins/SelcukFlix.py +29 -47
  57. KekikStream/Plugins/SetFilmIzle.py +28 -84
  58. KekikStream/Plugins/SezonlukDizi.py +27 -59
  59. KekikStream/Plugins/Sinefy.py +37 -100
  60. KekikStream/Plugins/SinemaCX.py +12 -18
  61. KekikStream/Plugins/Sinezy.py +11 -12
  62. KekikStream/Plugins/SuperFilmGeldi.py +8 -13
  63. KekikStream/Plugins/UgurFilm.py +14 -14
  64. KekikStream/Plugins/Watch32.py +42 -74
  65. KekikStream/Plugins/YabanciDizi.py +33 -87
  66. {kekikstream-2.4.2.dist-info → kekikstream-2.4.3.dist-info}/METADATA +1 -1
  67. kekikstream-2.4.3.dist-info/RECORD +93 -0
  68. kekikstream-2.4.2.dist-info/RECORD +0 -93
  69. {kekikstream-2.4.2.dist-info → kekikstream-2.4.3.dist-info}/WHEEL +0 -0
  70. {kekikstream-2.4.2.dist-info → kekikstream-2.4.3.dist-info}/entry_points.txt +0 -0
  71. {kekikstream-2.4.2.dist-info → kekikstream-2.4.3.dist-info}/licenses/LICENSE +0 -0
  72. {kekikstream-2.4.2.dist-info → kekikstream-2.4.3.dist-info}/top_level.txt +0 -0
@@ -6,33 +6,19 @@ class DzenRu(ExtractorBase):
6
6
  name = "DzenRu"
7
7
  main_url = "https://dzen.ru"
8
8
 
9
- async def extract(self, url, referer=None) -> ExtractResult:
9
+ async def extract(self, url: str, referer: str = None) -> ExtractResult:
10
10
  video_key = url.split("/")[-1]
11
- video_url = f"{self.main_url}/embed/{video_key}"
11
+ v_url = f"{self.main_url}/embed/{video_key}"
12
12
 
13
13
  if referer:
14
14
  self.httpx.headers.update({"Referer": referer})
15
15
 
16
- istek = await self.httpx.get(video_url)
17
- 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}")
18
23
 
19
- # okcdn.ru linklerini bul
20
- hp = HTMLHelper(istek.text)
21
- matches = hp.regex_all(r'https://vd\d+\.okcdn\.ru/\?[^"\'\\\s]+')
22
-
23
- if not matches:
24
- raise ValueError("DzenRu video link not found")
25
-
26
- # Benzersiz linkleri al, son kaliteyi kullan
27
- unique_links = list(set(matches))
28
- best_link = unique_links[-1] if unique_links else None
29
-
30
- if not best_link:
31
- raise ValueError("No valid video URL found")
32
-
33
- return ExtractResult(
34
- name = self.name,
35
- url = best_link,
36
- referer = self.main_url,
37
- subtitles = []
38
- )
24
+ return ExtractResult(name=self.name, url=list(set(links))[-1], referer=self.main_url)
@@ -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, HTMLHelper
3
+ from KekikStream.Core import ExtractorBase, ExtractResult, HTMLHelper
4
4
  from urllib.parse import urlparse, parse_qs
5
5
 
6
6
  class ExPlay(ExtractorBase):
7
7
  name = "ExPlay"
8
8
  main_url = "https://explay.store"
9
9
 
10
- async def extract(self, url, referer=None) -> ExtractResult:
11
- ext_ref = referer or ""
10
+ async def extract(self, url: str, referer: str = None) -> ExtractResult:
11
+ self.httpx.headers.update({"Referer": referer or url})
12
12
 
13
- # URL parsing for partKey
14
- parsed = urlparse(url)
15
- params = parse_qs(parsed.query)
16
- part_key = params.get("partKey", [""])[0]
17
- clean_url = url.split("?partKey=")[0]
18
-
19
- if referer:
20
- self.httpx.headers.update({"Referer": referer})
21
-
22
- istek = await self.httpx.get(clean_url)
23
- istek.raise_for_status()
24
-
25
- hp = HTMLHelper(istek.text)
13
+ # Clean URL from partKey for initial request
14
+ clean_url = url.split("?")[0]
15
+ resp = await self.httpx.get(clean_url)
16
+ sel = HTMLHelper(resp.text)
26
17
 
27
- # videoUrl çıkar
28
- video_url = hp.regex_first(r'videoUrl":"([^",]+)"')
29
- if not video_url:
30
- raise ValueError("videoUrl not found")
31
- video_url = video_url.replace("\\", "")
18
+ v_url = sel.regex_first(r'videoUrl":"([^",]+)"')
19
+ v_srv = sel.regex_first(r'videoServer":"([^",]+)"')
20
+ if not v_url or not v_srv:
21
+ raise ValueError(f"ExPlay: Video url/server bulunamadı. {url}")
32
22
 
33
- # videoServer çıkar
34
- video_server = hp.regex_first(r'videoServer":"([^",]+)"')
35
- if not video_server:
36
- raise ValueError("videoServer not found")
37
-
38
- # title çıkar
39
- title = hp.regex_first(r'title":"([^",]+)"')
40
- title = title.split(".")[-1] if title else "Unknown"
23
+ params = parse_qs(urlparse(url).query)
24
+ part_key = params.get("partKey", [""])[0]
41
25
 
42
- 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
  )
@@ -30,60 +30,34 @@ class Filemoon(ExtractorBase):
30
30
  self.httpx.headers.update(default_headers)
31
31
 
32
32
  # İlk sayfayı al
33
- istek = await self.httpx.get(url)
34
- response = istek.text
35
- secici = HTMLHelper(response)
33
+ istek = await self.httpx.get(url)
34
+ secici = HTMLHelper(istek.text)
36
35
 
37
36
  # Eğer iframe varsa, iframe'e git
38
37
  iframe_src = secici.select_attr("iframe", "src")
38
+ m3u8_url = None
39
39
 
40
- m3u8_url = None
41
-
42
- if not iframe_src:
43
- # Fallback: Script içinde ara (Kotlin: selectFirst("script:containsData(function(p,a,c,k,e,d))"))
44
- script_data = ""
45
- for script in secici.css("script"):
46
- if "function(p,a,c,k,e,d)" in script.text():
47
- script_data = script.text()
48
- break
49
-
50
- if script_data:
51
- unpacked = Packer.unpack(script_data)
52
- unpacked_sec = HTMLHelper(unpacked)
53
- m3u8_url = unpacked_sec.regex_first(r'sources:\[\{file:"(.*?)"')
54
- else:
55
- # Iframe varsa devam et
56
- iframe_url = self.fix_url(iframe_src)
57
- iframe_headers = default_headers.copy()
58
- iframe_headers["Accept-Language"] = "en-US,en;q=0.5"
59
-
60
- istek = await self.httpx.get(iframe_url, headers=iframe_headers)
61
- response = istek.text
62
- secici = HTMLHelper(response)
63
-
64
- script_data = ""
65
- for script in secici.select("script"):
66
- if "function(p,a,c,k,e,d)" in script.text():
67
- script_data = script.text()
68
- break
69
-
70
- if script_data:
71
- unpacked = Packer.unpack(script_data)
72
- unpacked_sec = HTMLHelper(unpacked)
73
- m3u8_url = unpacked_sec.regex_first(r'sources:\[\{file:"(.*?)"')
40
+ if iframe_src:
41
+ url = self.fix_url(iframe_src)
42
+ istek = await self.httpx.get(url)
43
+ secici = HTMLHelper(istek.text)
44
+
45
+ # script p,a,c,k,e,d içinde ara
46
+ script_data = secici.regex_first(r"(eval\(function\(p,a,c,k,e,d\).+?)\s*</script>")
47
+ if script_data:
48
+ unpacked = Packer.unpack(script_data)
49
+ m3u8_url = HTMLHelper(unpacked).regex_first(r'sources:\[\{file:"(.*?)"')
74
50
 
75
51
  if not m3u8_url:
76
- # Son çare: Normal response içinde ara
77
- resp_sec = HTMLHelper(response)
78
- m3u8_url = resp_sec.regex_first(r'sources:\s*\[\s*\{\s*file:\s*"([^"]+)"') or resp_sec.regex_first(r'file:\s*"([^\"]*?\.m3u8[^"]*)"')
52
+ # Fallback
53
+ m3u8_url = secici.regex_first(r'sources:\s*\[\s*\{\s*file:\s*"([^"]+)"') or secici.regex_first(r'file:\s*"([^\"]*?\.m3u8[^"]*)"')
79
54
 
80
55
  if not m3u8_url:
81
56
  raise ValueError(f"Filemoon: Video URL bulunamadı. {url}")
82
57
 
83
58
  return ExtractResult(
84
- name = self.name,
85
- url = self.fix_url(m3u8_url),
86
- referer = f"{self.main_url}/",
87
- user_agent = default_headers["User-Agent"],
88
- subtitles = []
59
+ name = self.name,
60
+ url = self.fix_url(m3u8_url),
61
+ referer = f"{self.get_base_url(url)}/",
62
+ user_agent = default_headers["User-Agent"]
89
63
  )
@@ -1,62 +1,30 @@
1
1
  # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
2
 
3
- from KekikStream.Core import ExtractorBase, ExtractResult, Subtitle, HTMLHelper
3
+ from KekikStream.Core import ExtractorBase, ExtractResult, HTMLHelper
4
4
  from Kekik.Sifreleme import AESManager
5
- import re
6
- import json
5
+ import contextlib, json
7
6
 
8
7
  class HDMomPlayer(ExtractorBase):
9
8
  name = "HDMomPlayer"
10
- main_url = "hdmomplayer.com"
11
-
12
- async def extract(self, url: str, referer: str = None) -> ExtractResult | None:
13
- if referer:
14
- self.httpx.headers.update({"Referer": referer})
15
-
16
- try:
17
- response = await self.httpx.get(url)
18
- page_source = response.text
19
-
20
- m3u_link = None
21
-
22
- # Regex for bePlayer matches
23
- # Matches: bePlayer('PASS', '{DATA}');
24
- helper = HTMLHelper(page_source)
25
- be_matches = helper.regex_all(r"bePlayer\('([^']+)',\s*'(\{[^\}]+\})'\);")
26
-
27
- if be_matches:
28
- pass_val, data_val = be_matches[0]
29
-
30
- try:
31
- # Use Kekik.Sifreleme.AESManager as requested
32
- decrypted = AESManager.decrypt(data_val, pass_val).replace("\\", "")
33
-
34
- # Search for video_location in decrypted string
35
- # Kotlin: video_location":"([^"]+)
36
- m_loc = re.search(r'video_location":"([^"]+)"', decrypted)
37
- if m_loc:
38
- m3u_link = m_loc.group(1).replace(r"\/", "/")
39
- except Exception:
40
- pass
41
-
42
- if not m3u_link:
43
- # Fallback regex
44
- # file:"..."
45
- m_file = re.search(r'file:"([^"]+)"', page_source)
46
- if m_file:
47
- m3u_link = m_file.group(1)
48
-
49
- if not m3u_link:
50
- return None
51
-
52
- # Fix URL if needed
53
- if m3u_link.startswith("//"):
54
- m3u_link = "https:" + m3u_link
55
-
56
- return ExtractResult(
57
- name = "HDMomPlayer",
58
- url = m3u_link,
59
- referer = url,
60
- )
61
- except Exception:
62
- return None
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)
@@ -2,44 +2,26 @@
2
2
 
3
3
  from KekikStream.Core import ExtractorBase, ExtractResult, HTMLHelper
4
4
  from Kekik.Sifreleme import AESManager
5
- import re
6
- import json
5
+ import contextlib
7
6
 
8
7
  class HotStream(ExtractorBase):
9
8
  name = "HotStream"
10
9
  main_url = "https://hotstream.club"
11
10
 
12
- async def extract(self, url: str, referer: str = None) -> ExtractResult | None:
13
- if referer:
14
- self.httpx.headers.update({"Referer": referer})
11
+ async def extract(self, url: str, referer: str = None) -> ExtractResult:
12
+ self.httpx.headers.update({"Referer": referer or url})
15
13
 
16
- istek = await self.httpx.get(url)
17
- html = istek.text
18
- helper = HTMLHelper(html)
14
+ resp = await self.httpx.get(url)
15
+ sel = HTMLHelper(resp.text)
19
16
 
20
- m = re.search(r"bePlayer\('([^']+)',\s*'(\{[^']+\})'\)", html)
21
- if not m:
22
- # Try double quotes just in case
23
- m = re.search(r'bePlayer\("([^"]+)",\s*"(\{[^"]+\})"\)', html)
24
-
25
- if m:
26
- pass_val = m.group(1)
27
- data_val = m.group(2)
28
-
29
- try:
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):
30
21
  decrypted = AESManager.decrypt(data_val, pass_val)
31
- if decrypted:
32
- decrypted = decrypted.replace("\\", "")
33
- # Search for video_location in decrypted string
34
- m_loc = re.search(r'"video_location":"([^"]+)"', decrypted)
35
- if m_loc:
36
- video_url = m_loc.group(1).replace(r"\/", "/")
37
- return ExtractResult(
38
- name = self.name,
39
- url = video_url,
40
- referer = url
41
- )
42
- except Exception:
43
- pass
22
+ m3u8_url = HTMLHelper(decrypted).regex_first(r'"video_location":"([^"]+)"')
44
23
 
45
- return None
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)
@@ -1,45 +1,32 @@
1
1
  # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
2
 
3
- from KekikStream.Core import ExtractorBase, ExtractResult, Subtitle, HTMLHelper
4
- import json
3
+ from KekikStream.Core import ExtractorBase, ExtractResult, HTMLHelper
4
+ import contextlib
5
5
 
6
6
  class JetTv(ExtractorBase):
7
7
  name = "JetTv"
8
8
  main_url = "https://jetv.xyz"
9
9
 
10
10
  async def extract(self, url: str, referer: str = None) -> ExtractResult:
11
- istek = await self.httpx.get(url)
12
- document = istek.text
11
+ resp = await self.httpx.get(url)
12
+ sel = HTMLHelper(resp.text)
13
13
 
14
- # 1. Yöntem: API üzerinden alma
15
- master_url = ""
16
- final_ref = f"{self.main_url}/"
14
+ m3u8_url = None
15
+ final_ref = self.main_url
17
16
 
18
17
  if "id=" in url:
19
- vid_id = url.split("id=")[-1]
20
- api_url = f"https://jetv.xyz/apollo/get_video.php?id={vid_id}"
21
- try:
22
- # Referer olarak video sayfasının kendisi gönderilmeli
23
- api_resp = await self.httpx.get(api_url, headers={"Referer": url})
24
- api_json = api_resp.json()
25
-
26
- if api_json.get("success"):
27
- master_url = api_json.get("masterUrl", "")
28
- final_ref = api_json.get("referrerUrl") or final_ref
29
- except Exception:
30
- pass
31
-
32
- # 2. Yöntem: Regex Fallback
33
- if not master_url:
34
- hp = HTMLHelper(document)
35
- master_url = hp.regex_first(r"(?i)file: '([^']*)'") or master_url
36
-
37
- if not master_url:
38
- raise ValueError(f"JetTv: Video kaynağı bulunamadı. {url}")
39
-
40
- return ExtractResult(
41
- name = self.name,
42
- url = master_url,
43
- referer = final_ref,
44
- subtitles = []
45
- )
18
+ v_id = url.split("id=")[-1]
19
+ with contextlib.suppress(Exception):
20
+ api_resp = await self.httpx.get(f"{self.main_url}/apollo/get_video.php?id={v_id}", headers={"Referer": url})
21
+ data = api_resp.json()
22
+ if data.get("success"):
23
+ m3u8_url = data.get("masterUrl")
24
+ final_ref = data.get("referrerUrl") or final_ref
25
+
26
+ if not m3u8_url:
27
+ m3u8_url = sel.regex_first(r"(?i)file: '([^']*)'")
28
+
29
+ if not m3u8_url:
30
+ raise ValueError(f"JetTv: Video URL bulunamadı. {url}")
31
+
32
+ return ExtractResult(name=self.name, url=m3u8_url, referer=final_ref)
@@ -2,37 +2,19 @@
2
2
 
3
3
  from KekikStream.Core import ExtractorBase, ExtractResult
4
4
 
5
- class MailRuExtractor(ExtractorBase):
5
+ class MailRu(ExtractorBase):
6
6
  name = "MailRu"
7
7
  main_url = "https://my.mail.ru"
8
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}"
9
+ async def extract(self, url: str, referer: str = None) -> ExtractResult:
10
+ v_id = url.split("video/embed/")[-1].strip()
11
+ if referer: self.httpx.headers.update({"Referer": referer})
12
12
 
13
- if referer:
14
- self.httpx.headers.update({"Referer": referer})
13
+ resp = await self.httpx.get(f"{self.main_url}/+/video/meta/{v_id}")
14
+ data = resp.json()
15
+
16
+ v_url = data.get("videos", [{}])[0].get("url")
17
+ if not v_url:
18
+ raise ValueError(f"MailRu: Video URL bulunamadı. {url}")
15
19
 
16
- istek = await self.httpx.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
- return ExtractResult(
34
- name = self.name,
35
- url = video_url,
36
- referer = self.main_url,
37
- subtitles = []
38
- )
20
+ return ExtractResult(name=self.name, url=self.fix_url(v_url), referer=self.main_url)
@@ -8,34 +8,21 @@ class MixPlayHD(ExtractorBase):
8
8
  name = "MixPlayHD"
9
9
  main_url = "https://mixplayhd.com"
10
10
 
11
- async def extract(self, url, referer=None) -> ExtractResult:
12
- if referer:
13
- self.httpx.headers.update({"Referer": referer})
11
+ async def extract(self, url: str, referer: str = None) -> ExtractResult:
12
+ self.httpx.headers.update({"Referer": referer or self.main_url})
14
13
 
15
- istek = await self.httpx.get(url)
16
- istek.raise_for_status()
17
-
18
- hp = HTMLHelper(istek.text)
19
- be_player_matches = hp.regex_all(r"bePlayer\('([^']+)',\s*'(\{[^\}]+\})'\);")
20
- if not be_player_matches:
21
- raise ValueError("bePlayer not found in the response.")
22
-
23
- be_player_pass, be_player_data = be_player_matches[0]
14
+ resp = await self.httpx.get(url)
15
+ match = HTMLHelper(resp.text).regex_first(r"bePlayer\('([^']+)',\s*'(\{[^\}]+\})'\);", group=None)
16
+ if not match:
17
+ raise ValueError(f"MixPlayHD: bePlayer bulunamadı. {url}")
24
18
 
19
+ pass_val, data_val = match
25
20
  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
- client_str = decrypted_json.get("schedule", {}).get("client", "")
32
- video_url = HTMLHelper(client_str).regex_first(r'"video_location":"([^"]+)"')
33
- if video_url:
34
- return ExtractResult(
35
- name = self.name,
36
- url = video_url,
37
- referer = self.main_url,
38
- subtitles = []
39
- )
40
- else:
41
- raise ValueError("M3U8 video URL not found in the decrypted data.")
21
+ data = json.loads(AESManager.decrypt(data_val, pass_val))
22
+ v_url = HTMLHelper(data.get("schedule", {}).get("client", "")).regex_first(r'"video_location":"([^"]+)"')
23
+ if v_url:
24
+ return ExtractResult(name=self.name, url=v_url, referer=self.main_url)
25
+ except Exception as e:
26
+ raise ValueError(f"MixPlayHD: Decryption failed. {e}")
27
+
28
+ raise ValueError(f"MixPlayHD: Video URL bulunamadı. {url}")