KekikStream 2.3.3__py3-none-any.whl → 2.3.5__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. KekikStream/Core/HTMLHelper.py +134 -0
  2. KekikStream/Core/Plugin/PluginBase.py +12 -2
  3. KekikStream/Core/__init__.py +2 -0
  4. KekikStream/Extractors/CloseLoad.py +12 -13
  5. KekikStream/Extractors/ContentX.py +33 -31
  6. KekikStream/Extractors/DonilasPlay.py +10 -10
  7. KekikStream/Extractors/DzenRu.py +3 -3
  8. KekikStream/Extractors/ExPlay.py +10 -10
  9. KekikStream/Extractors/Filemoon.py +11 -16
  10. KekikStream/Extractors/JetTv.py +4 -4
  11. KekikStream/Extractors/MixPlayHD.py +10 -11
  12. KekikStream/Extractors/MolyStream.py +15 -9
  13. KekikStream/Extractors/Odnoklassniki.py +4 -4
  14. KekikStream/Extractors/PeaceMakerst.py +3 -3
  15. KekikStream/Extractors/PixelDrain.py +6 -5
  16. KekikStream/Extractors/PlayerFilmIzle.py +6 -10
  17. KekikStream/Extractors/RapidVid.py +8 -7
  18. KekikStream/Extractors/SetPlay.py +10 -10
  19. KekikStream/Extractors/SetPrime.py +3 -6
  20. KekikStream/Extractors/SibNet.py +4 -5
  21. KekikStream/Extractors/Sobreatsesuyp.py +5 -5
  22. KekikStream/Extractors/TRsTX.py +5 -5
  23. KekikStream/Extractors/TurboImgz.py +3 -4
  24. KekikStream/Extractors/TurkeyPlayer.py +5 -5
  25. KekikStream/Extractors/VidHide.py +4 -7
  26. KekikStream/Extractors/VidMoly.py +24 -25
  27. KekikStream/Extractors/VidMoxy.py +8 -9
  28. KekikStream/Extractors/VidPapi.py +5 -7
  29. KekikStream/Extractors/VideoSeyred.py +3 -3
  30. KekikStream/Plugins/BelgeselX.py +40 -51
  31. KekikStream/Plugins/DiziBox.py +53 -81
  32. KekikStream/Plugins/DiziPal.py +41 -74
  33. KekikStream/Plugins/DiziWatch.py +217 -0
  34. KekikStream/Plugins/DiziYou.py +95 -88
  35. KekikStream/Plugins/Dizilla.py +54 -72
  36. KekikStream/Plugins/FilmBip.py +24 -49
  37. KekikStream/Plugins/FilmMakinesi.py +35 -52
  38. KekikStream/Plugins/FilmModu.py +27 -41
  39. KekikStream/Plugins/FullHDFilm.py +50 -72
  40. KekikStream/Plugins/FullHDFilmizlesene.py +35 -51
  41. KekikStream/Plugins/HDFilmCehennemi.py +48 -62
  42. KekikStream/Plugins/JetFilmizle.py +32 -50
  43. KekikStream/Plugins/KultFilmler.py +42 -67
  44. KekikStream/Plugins/RecTV.py +7 -4
  45. KekikStream/Plugins/RoketDizi.py +30 -50
  46. KekikStream/Plugins/SelcukFlix.py +15 -29
  47. KekikStream/Plugins/SetFilmIzle.py +41 -70
  48. KekikStream/Plugins/SezonlukDizi.py +47 -65
  49. KekikStream/Plugins/Sinefy.py +39 -50
  50. KekikStream/Plugins/SinemaCX.py +31 -55
  51. KekikStream/Plugins/Sinezy.py +27 -54
  52. KekikStream/Plugins/SuperFilmGeldi.py +25 -44
  53. KekikStream/Plugins/UgurFilm.py +23 -48
  54. KekikStream/Plugins/YabanciDizi.py +274 -0
  55. {kekikstream-2.3.3.dist-info → kekikstream-2.3.5.dist-info}/METADATA +1 -1
  56. kekikstream-2.3.5.dist-info/RECORD +85 -0
  57. kekikstream-2.3.3.dist-info/RECORD +0 -82
  58. {kekikstream-2.3.3.dist-info → kekikstream-2.3.5.dist-info}/WHEEL +0 -0
  59. {kekikstream-2.3.3.dist-info → kekikstream-2.3.5.dist-info}/entry_points.txt +0 -0
  60. {kekikstream-2.3.3.dist-info → kekikstream-2.3.5.dist-info}/licenses/LICENSE +0 -0
  61. {kekikstream-2.3.3.dist-info → kekikstream-2.3.5.dist-info}/top_level.txt +0 -0
@@ -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
4
- import re, json
3
+ from KekikStream.Core import ExtractorBase, ExtractResult, HTMLHelper
4
+ import json
5
5
 
6
6
  class PeaceMakerst(ExtractorBase):
7
7
  name = "PeaceMakerst"
@@ -36,7 +36,7 @@ class PeaceMakerst(ExtractorBase):
36
36
  m3u_link = None
37
37
 
38
38
  if "teve2.com.tr\\/embed\\/" in response_text:
39
- teve2_id = re.search(r"teve2\.com\.tr\\\/embed\\\/(\d+)", response_text)[1]
39
+ teve2_id = HTMLHelper(response_text).regex_first(r"teve2\.com\.tr\\\/embed\\\/(\d+)")
40
40
  teve2_url = f"https://www.teve2.com.tr/action/media/{teve2_id}"
41
41
 
42
42
  teve2_response = await self.httpx.get(teve2_url, headers={"Referer": f"https://www.teve2.com.tr/embed/{teve2_id}"})
@@ -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
4
- import re
3
+ from KekikStream.Core import ExtractorBase, ExtractResult, HTMLHelper
5
4
 
6
5
  class PixelDrain(ExtractorBase):
7
6
  name = "PixelDrain"
@@ -11,11 +10,13 @@ class PixelDrain(ExtractorBase):
11
10
  if referer:
12
11
  self.httpx.headers.update({"Referer": referer})
13
12
 
14
- pixel_id_match = re.search(r"/u/([^/?]+)|([^\/]+)(?=\?download)", url)
15
- if not pixel_id_match:
13
+ hp = HTMLHelper(url)
14
+ matches = hp.regex_all(r"/u/([^/?]+)|([^\/]+)(?=\?download)")
15
+ if not matches:
16
16
  raise ValueError("PixelDrain bağlantısından ID çıkarılamadı.")
17
17
 
18
- pixel_id = pixel_id_match[1]
18
+ m = matches[0]
19
+ pixel_id = next((g for g in m if g), None)
19
20
  download_link = f"{self.main_url}/api/file/{pixel_id}?download"
20
21
  referer_link = f"{self.main_url}/u/{pixel_id}?download"
21
22
 
@@ -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"
@@ -20,11 +19,10 @@ class PlayerFilmIzle(ExtractorBase):
20
19
  video_req = istek.text
21
20
 
22
21
  subtitles = []
23
- if sub_match := re.search(r'playerjsSubtitle = "([^"]*)"', video_req, re.IGNORECASE):
24
- sub_yakala = sub_match.group(1)
22
+ hp = HTMLHelper(video_req)
23
+ sub_yakala = hp.regex_first(r'(?i)playerjsSubtitle = "([^"]*)"')
24
+ if sub_yakala:
25
25
  # Format örneği: [dil]url
26
- # Kotlin kodunda: subYakala.substringAfter("]") -> url
27
- # subYakala.substringBefore("]").removePrefix("[") -> lang
28
26
  if "]" in sub_yakala:
29
27
  sub_lang_raw, sub_url = sub_yakala.split("]", 1)
30
28
  sub_lang = sub_lang_raw.replace("[", "")
@@ -34,8 +32,7 @@ class PlayerFilmIzle(ExtractorBase):
34
32
  unpacked = Packer.unpack(video_req) if Packer.detect_packed(video_req) else video_req
35
33
 
36
34
  # 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
35
+ data_val = HTMLHelper(unpacked).regex_first(r'(?i)FirePlayer\s*\(\s*["\']([a-f0-9]+)["\']')
39
36
 
40
37
  if not data_val:
41
38
  raise ValueError("PlayerFilmIzle: Data bulunamadı")
@@ -54,8 +51,7 @@ class PlayerFilmIzle(ExtractorBase):
54
51
  get_url = response.text.replace("\\", "")
55
52
 
56
53
  m3u8_url = ""
57
- if url_yakala := re.search(r'"securedLink":"([^"]*)"', get_url, re.IGNORECASE):
58
- m3u8_url = url_yakala.group(1)
54
+ m3u8_url = HTMLHelper(get_url).regex_first(r'(?i)"securedLink":"([^\\"]*)"') or m3u8_url
59
55
 
60
56
  if not m3u8_url:
61
57
  raise ValueError("PlayerFilmIzle: M3U8 linki bulunamadı")
@@ -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"
@@ -22,7 +22,8 @@ class RapidVid(ExtractorBase):
22
22
  istek.raise_for_status()
23
23
 
24
24
  subtitles = []
25
- subtitle_matches = re.findall(r'captions\",\"file\":\"([^\"]+)\",\"label\":\"([^\"]+)\"', istek.text)
25
+ hp = HTMLHelper(istek.text)
26
+ subtitle_matches = hp.regex_all(r'captions\",\"file\":\"([^\"]+)\",\"label\":\"([^\"]+)\"')
26
27
  seen_subtitles = set()
27
28
 
28
29
  for sub_url, sub_lang in subtitle_matches:
@@ -42,13 +43,13 @@ class RapidVid(ExtractorBase):
42
43
  decoded_url = None
43
44
 
44
45
  # Method 1: file": "..." pattern (HexCodec)
45
- if extracted_value := re.search(r'file": "(.*)",', istek.text):
46
- escaped_hex = extracted_value[1]
46
+ if extracted_value := hp.regex_first(r'file": "(.*)",'):
47
+ escaped_hex = extracted_value
47
48
  decoded_url = HexCodec.decode(escaped_hex)
48
49
 
49
50
  # Method 2: av('...') pattern
50
- elif av_encoded := re.search(r"av\('([^']+)'\)", istek.text):
51
- decoded_url = self.decode_secret(av_encoded[1])
51
+ elif av_encoded := hp.regex_first(r"av\('([^']+)'\)"):
52
+ decoded_url = self.decode_secret(av_encoded)
52
53
 
53
54
  # Method 3: Packed script with dc_* function (StreamDecoder)
54
55
  elif Packer.detect_packed(istek.text):
@@ -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 SetPlay(ExtractorBase):
8
7
  name = "SetPlay"
@@ -26,21 +25,22 @@ class SetPlay(ExtractorBase):
26
25
  istek = await self.httpx.get(url)
27
26
  istek.raise_for_status()
28
27
 
28
+ hp = HTMLHelper(istek.text)
29
+
29
30
  # videoUrl çıkar
30
- video_url_match = re.search(r'videoUrl":"([^",]+)"', istek.text)
31
- if not video_url_match:
31
+ video_url = hp.regex_first(r'videoUrl":"([^",]+)"')
32
+ if not video_url:
32
33
  raise ValueError("videoUrl not found")
33
- video_url = video_url_match[1].replace("\\", "")
34
+ video_url = video_url.replace("\\", "")
34
35
 
35
36
  # videoServer çıkar
36
- video_server_match = re.search(r'videoServer":"([^",]+)"', istek.text)
37
- if not video_server_match:
37
+ video_server = hp.regex_first(r'videoServer":"([^",]+)"')
38
+ if not video_server:
38
39
  raise ValueError("videoServer not found")
39
- video_server = video_server_match[1]
40
40
 
41
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"
42
+ title_base = hp.regex_first(r'title":"([^",]+)"')
43
+ title_base = title_base.split(".")[-1] if title_base else "Unknown"
44
44
 
45
45
  # partKey logic
46
46
  parsed = urlparse(url)
@@ -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,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
4
- import re
3
+ from KekikStream.Core import ExtractorBase, ExtractResult, HTMLHelper
5
4
 
6
5
  class SibNet(ExtractorBase):
7
6
  name = "SibNet"
@@ -14,11 +13,11 @@ class SibNet(ExtractorBase):
14
13
  response = await self.httpx.get(url)
15
14
  response.raise_for_status()
16
15
 
17
- match = re.search(r'player\.src\(\[\{src: \"([^\"]+)\"', response.text)
18
- if not match:
16
+ m3u_suffix = HTMLHelper(response.text).regex_first(r'player\.src\(\[\{src: "([^\"]+)"')
17
+ if not m3u_suffix:
19
18
  raise ValueError("m3u bağlantısı bulunamadı.")
20
19
 
21
- m3u_link = f"{self.main_url}{match[1]}"
20
+ m3u_link = f"{self.main_url}{m3u_suffix}"
22
21
 
23
22
  return ExtractResult(
24
23
  name = self.name,
@@ -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
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"
@@ -14,11 +14,11 @@ class Sobreatsesuyp(ExtractorBase):
14
14
  istek = await self.httpx.get(url)
15
15
  istek.raise_for_status()
16
16
 
17
- file_match = re.search(r'file\":\"([^\"]+)', istek.text)
18
- if not file_match:
17
+ file_path = HTMLHelper(istek.text).regex_first(r'file":"([^\"]+)')
18
+ if not file_path:
19
19
  raise ValueError("File not found in response.")
20
20
 
21
- file_path = file_match[1].replace("\\", "")
21
+ file_path = file_path.replace("\\", "")
22
22
  post_link = f"{self.main_url}/{file_path}"
23
23
 
24
24
  post_istek = await self.httpx.post(post_link)
@@ -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
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"
@@ -14,11 +14,11 @@ class TRsTX(ExtractorBase):
14
14
  istek = await self.httpx.get(url)
15
15
  istek.raise_for_status()
16
16
 
17
- file_match = re.search(r'file\":\"([^\"]+)', istek.text)
18
- if not file_match:
17
+ file_path = HTMLHelper(istek.text).regex_first(r'file":"([^\"]+)')
18
+ if not file_path:
19
19
  raise ValueError("File not found in response.")
20
20
 
21
- file_path = file_match[1].replace("\\", "")
21
+ file_path = file_path.replace("\\", "")
22
22
  post_link = f"{self.main_url}/{file_path}"
23
23
 
24
24
  post_istek = await self.httpx.post(post_link)
@@ -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
4
- import re
3
+ from KekikStream.Core import ExtractorBase, ExtractResult, HTMLHelper
5
4
 
6
5
  class TurboImgz(ExtractorBase):
7
6
  name = "TurboImgz"
@@ -14,10 +13,10 @@ class TurboImgz(ExtractorBase):
14
13
  istek = await self.httpx.get(url)
15
14
  istek.raise_for_status()
16
15
 
17
- if video_match := re.search(r'file: "(.*)",', istek.text):
16
+ if video := HTMLHelper(istek.text).regex_first(r'file: "(.*)",'):
18
17
  return ExtractResult(
19
18
  name = self.name,
20
- url = video_match[1],
19
+ url = video,
21
20
  referer = referer or self.main_url,
22
21
  subtitles = []
23
22
  )
@@ -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")
@@ -1,6 +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
3
+ from KekikStream.Core import ExtractorBase, ExtractResult, Subtitle, HTMLHelper
4
4
  from Kekik.Sifreleme import Packer
5
5
  import re
6
6
 
@@ -54,19 +54,16 @@ class VidHide(ExtractorBase):
54
54
  pass
55
55
 
56
56
  if not script:
57
- if matches := re.search(r'sources:\s*(\[.*?\])', response, re.DOTALL):
58
- script = matches.group(1)
57
+ script = HTMLHelper(response).regex_first(r'(?s)sources:\s*(\[.*?\])')
59
58
 
60
59
  m3u8_url = None
61
60
  if script:
62
61
  # m3u8 urls could be prefixed by 'file:', 'hls2:' or 'hls4:', so we just match ':'
63
- if match := re.search(r':\s*"([^"]*?m3u8[^"]*?)"', script):
64
- m3u8_url = match.group(1)
62
+ m3u8_url = HTMLHelper(script).regex_first(r':\s*"([^\"]*?m3u8[^\"]*?)"')
65
63
 
66
64
  if not m3u8_url:
67
65
  # Fallback direct search in response if unpacking failed or structure changed
68
- if match := re.search(r'file:"(.*?\.m3u8.*?)"', response):
69
- m3u8_url = match.group(1)
66
+ m3u8_url = HTMLHelper(response).regex_first(r'file:"(.*?\.m3u8.*?)"')
70
67
 
71
68
  if not m3u8_url:
72
69
  raise ValueError(f"VidHide: Video URL bulunamadı. {url}")
@@ -1,8 +1,7 @@
1
1
  # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
2
  # ! https://github.com/recloudstream/cloudstream/blob/master/library/src/commonMain/kotlin/com/lagradost/cloudstream3/extractors/Vidmoly.kt
3
3
 
4
- from KekikStream.Core import ExtractorBase, ExtractResult, Subtitle
5
- from selectolax.parser import HTMLParser
4
+ from KekikStream.Core import ExtractorBase, ExtractResult, Subtitle, HTMLHelper
6
5
  import re, contextlib, json
7
6
 
8
7
  class VidMoly(ExtractorBase):
@@ -29,24 +28,24 @@ class VidMoly(ExtractorBase):
29
28
  # VidMoly bazen redirect ediyor, takip et
30
29
  response = await self.httpx.get(url, follow_redirects=True)
31
30
  if "Select number" in response.text:
32
- secici = HTMLParser(response.text)
31
+ secici = HTMLHelper(response.text)
33
32
 
34
- op_el = secici.css_first("input[name='op']")
35
- file_code_el = secici.css_first("input[name='file_code']")
36
- answer_el = secici.css_first("div.vhint b")
37
- ts_el = secici.css_first("input[name='ts']")
38
- nonce_el = secici.css_first("input[name='nonce']")
39
- ctok_el = secici.css_first("input[name='ctok']")
33
+ op_val = secici.select_attr("input[name='op']", "value")
34
+ file_code_val = secici.select_attr("input[name='file_code']", "value")
35
+ answer_val = secici.select_text("div.vhint b")
36
+ ts_val = secici.select_attr("input[name='ts']", "value")
37
+ nonce_val = secici.select_attr("input[name='nonce']", "value")
38
+ ctok_val = secici.select_attr("input[name='ctok']", "value")
40
39
 
41
40
  response = await self.httpx.post(
42
41
  url = url,
43
42
  data = {
44
- "op" : op_el.attrs.get("value") if op_el else None,
45
- "file_code" : file_code_el.attrs.get("value") if file_code_el else None,
46
- "answer" : answer_el.text(strip=True) if answer_el else None,
47
- "ts" : ts_el.attrs.get("value") if ts_el else None,
48
- "nonce" : nonce_el.attrs.get("value") if nonce_el else None,
49
- "ctok" : ctok_el.attrs.get("value") if ctok_el else None
43
+ "op" : op_val,
44
+ "file_code" : file_code_val,
45
+ "answer" : answer_val,
46
+ "ts" : ts_val,
47
+ "nonce" : nonce_val,
48
+ "ctok" : ctok_val
50
49
  },
51
50
  follow_redirects=True
52
51
  )
@@ -54,8 +53,9 @@ class VidMoly(ExtractorBase):
54
53
 
55
54
  # Altyazı kaynaklarını ayrıştır
56
55
  subtitles = []
57
- if subtitle_match := re.search(r"tracks:\s*\[(.*?)\]", response.text, re.DOTALL):
58
- subtitle_data = self._add_marks(subtitle_match[1], "file")
56
+ resp_sec = HTMLHelper(response.text)
57
+ if subtitle_str := resp_sec.regex_first(r"tracks:\s*\[(.*?)\]", flags= re.DOTALL):
58
+ subtitle_data = self._add_marks(subtitle_str, "file")
59
59
  subtitle_data = self._add_marks(subtitle_data, "label")
60
60
  subtitle_data = self._add_marks(subtitle_data, "kind")
61
61
 
@@ -70,9 +70,8 @@ class VidMoly(ExtractorBase):
70
70
  if sub.get("kind") == "captions"
71
71
  ]
72
72
 
73
- script_match = re.search(r"sources:\s*\[(.*?)\],", response.text, re.DOTALL)
74
- if script_match:
75
- script_content = script_match[1]
73
+ if script_str := resp_sec.regex_first(r"sources:\s*\[(.*?)\],", flags= re.DOTALL):
74
+ script_content = script_str
76
75
  # Video kaynaklarını ayrıştır
77
76
  video_data = self._add_marks(script_content, "file")
78
77
  try:
@@ -91,17 +90,17 @@ class VidMoly(ExtractorBase):
91
90
 
92
91
  # Fallback: Doğrudan file regex ile ara (Kotlin mantığı)
93
92
  # file:"..." veya file: "..."
94
- if file_match := re.search(r'file\s*:\s*["\']([^"\']+\.m3u8[^"\']*)["\']', response.text):
93
+ if file_match := resp_sec.regex_first(r'file\s*:\s*["\']([^"\']+\.m3u8[^"\']*)["\']'):
95
94
  return ExtractResult(
96
95
  name = self.name,
97
- url = file_match.group(1),
96
+ url = file_match,
98
97
  referer = self.main_url,
99
98
  subtitles = subtitles
100
99
  )
101
100
 
102
101
  # Fallback 2: Herhangi bir file (m3u8 olma şartı olmadan ama tercihen)
103
- if file_match := re.search(r'file\s*:\s*["\']([^"\']+)["\']', response.text):
104
- url_candidate = file_match.group(1)
102
+ if file_match := resp_sec.regex_first(r'file\s*:\s*["\']([^"\']+)["\']'):
103
+ url_candidate = file_match
105
104
  # Resim dosyalarını hariç tut
106
105
  if not url_candidate.endswith(('.jpg', '.png', '.jpeg')):
107
106
  return ExtractResult(
@@ -117,4 +116,4 @@ class VidMoly(ExtractorBase):
117
116
  """
118
117
  Verilen alanı çift tırnak içine alır.
119
118
  """
120
- return re.sub(rf"\"?{field}\"?", f"\"{field}\"", text)
119
+ return HTMLHelper(text).regex_replace(rf"\"?{field}\"?", f"\"{field}\"")
@@ -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, HexCodec
5
- import re
6
5
 
7
6
  class VidMoxy(ExtractorBase):
8
7
  name = "VidMoxy"
@@ -16,7 +15,7 @@ class VidMoxy(ExtractorBase):
16
15
  istek.raise_for_status()
17
16
 
18
17
  subtitles = []
19
- subtitle_matches = re.findall(r'captions","file":"([^"]+)","label":"([^"]+)"', istek.text)
18
+ subtitle_matches = HTMLHelper(istek.text).regex_all(r'captions","file":"([^\"]+)","label":"([^\"]+)"')
20
19
  seen_subtitles = set()
21
20
 
22
21
  for sub_url, sub_lang in subtitle_matches:
@@ -32,12 +31,12 @@ class VidMoxy(ExtractorBase):
32
31
  )
33
32
  subtitles.append(Subtitle(name=decoded_lang, url=sub_url.replace("\\", "")))
34
33
 
35
- try:
36
- escaped_hex = re.findall(r'file": "(.*)",', istek.text)[0]
37
- except Exception:
38
- eval_jwsetup = re.compile(r'\};\s*(eval\(function[\s\S]*?)var played = \d+;').findall(istek.text)[0]
39
- jwsetup = Packer.unpack(Packer.unpack(eval_jwsetup))
40
- escaped_hex = re.findall(r'file":"(.*)","label', jwsetup)[0]
34
+ escaped_hex = HTMLHelper(istek.text).regex_first(r'file": "(.*)",')
35
+ if not escaped_hex:
36
+ eval_jwsetup = HTMLHelper(istek.text).regex_first(r'\};\s*(eval\(function[\s\S]*?)var played = \d+;')
37
+ jwsetup = Packer.unpack(Packer.unpack(eval_jwsetup)) if eval_jwsetup else None
38
+ if jwsetup:
39
+ escaped_hex = HTMLHelper(jwsetup).regex_first(r'file":"(.*)","label')
41
40
 
42
41
  m3u_link = HexCodec.decode(escaped_hex)
43
42
 
@@ -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
3
+ from KekikStream.Core import ExtractorBase, ExtractResult, Subtitle, HTMLHelper
4
+
5
5
 
6
6
  class VidPapi(ExtractorBase):
7
7
  name = "VidApi"
@@ -33,11 +33,9 @@ class VidPapi(ExtractorBase):
33
33
  data = {"hash": vid_id, "r": "https://kultfilmler.pro/"}
34
34
  )
35
35
 
36
- subtitle_match = re.search(r'var playerjsSubtitle = "([^"]*)"', sub_istek.text, re.IGNORECASE)
37
- if subtitle_match and subtitle_match.group(1):
38
- raw_subs = subtitle_match.group(1)
39
-
40
- found_subs = re.findall(r'\[(.*?)\](.*?)(?:,|$)', raw_subs)
36
+ raw_subs = HTMLHelper(sub_istek.text).regex_first(r'var playerjsSubtitle\s*=\s*"([^"]*)"', flags=0)
37
+ if raw_subs:
38
+ found_subs = HTMLHelper(raw_subs).regex_all(r'\[(.*?)\](.*?)(?:,|$)')
41
39
  for lang, sub_link in found_subs:
42
40
  lang = lang.strip()
43
41
  if "Türkçe" in lang:
@@ -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 json, re
3
+ from KekikStream.Core import ExtractorBase, ExtractResult, Subtitle, HTMLHelper
4
+ import json
5
5
 
6
6
  class VideoSeyred(ExtractorBase):
7
7
  name = "VideoSeyred"
@@ -16,7 +16,7 @@ class VideoSeyred(ExtractorBase):
16
16
  kontrol = await self.httpx.get(url)
17
17
  kontrol.raise_for_status()
18
18
 
19
- video_id = re.search(r"playlist\/(.*)\.json", kontrol.text)[1]
19
+ video_id = HTMLHelper(kontrol.text).regex_first(r"playlist\/(.*)\.json")
20
20
 
21
21
  video_url = f"{self.main_url}/playlist/{video_id}.json"
22
22