KekikStream 2.4.7__tar.gz → 2.4.9__tar.gz

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 (107) hide show
  1. kekikstream-2.4.9/KekikStream/Extractors/JetV.py +55 -0
  2. kekikstream-2.4.9/KekikStream/Extractors/Veev.py +145 -0
  3. kekikstream-2.4.9/KekikStream/Extractors/VidBiz.py +62 -0
  4. kekikstream-2.4.9/KekikStream/Extractors/VidHide.py +105 -0
  5. kekikstream-2.4.9/KekikStream/Extractors/Vtbe.py +38 -0
  6. kekikstream-2.4.9/KekikStream/Extractors/Zeus.py +61 -0
  7. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Plugins/BelgeselX.py +3 -4
  8. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Plugins/DiziBox.py +3 -3
  9. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Plugins/DiziMom.py +48 -42
  10. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Plugins/DiziPal.py +1 -1
  11. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Plugins/Dizilla.py +2 -2
  12. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Plugins/FilmBip.py +4 -11
  13. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Plugins/FilmEkseni.py +59 -55
  14. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Plugins/FilmMakinesi.py +42 -5
  15. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Plugins/FilmModu.py +0 -1
  16. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Plugins/Filmatek.py +4 -11
  17. kekikstream-2.4.7/KekikStream/Plugins/Full4kizle.py → kekikstream-2.4.9/KekikStream/Plugins/FilmciBaba.py +55 -74
  18. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Plugins/FullHDFilmizlesene.py +6 -7
  19. kekikstream-2.4.9/KekikStream/Plugins/HDFilm.py +243 -0
  20. kekikstream-2.4.9/KekikStream/Plugins/HDFilmCehennemi.py +357 -0
  21. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Plugins/JetFilmizle.py +82 -49
  22. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream.egg-info/PKG-INFO +1 -1
  23. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream.egg-info/SOURCES.txt +7 -2
  24. {kekikstream-2.4.7 → kekikstream-2.4.9}/PKG-INFO +1 -1
  25. {kekikstream-2.4.7 → kekikstream-2.4.9}/setup.py +1 -1
  26. kekikstream-2.4.7/KekikStream/Extractors/VidHide.py +0 -56
  27. kekikstream-2.4.7/KekikStream/Plugins/FullHDFilm.py +0 -179
  28. kekikstream-2.4.7/KekikStream/Plugins/HDFilmCehennemi.py +0 -265
  29. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/CLI/__init__.py +0 -0
  30. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/CLI/pypi_kontrol.py +0 -0
  31. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Core/Extractor/ExtractorBase.py +0 -0
  32. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Core/Extractor/ExtractorLoader.py +0 -0
  33. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Core/Extractor/ExtractorManager.py +0 -0
  34. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Core/Extractor/ExtractorModels.py +0 -0
  35. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Core/Extractor/YTDLPCache.py +0 -0
  36. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Core/HTMLHelper.py +0 -0
  37. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Core/Media/MediaHandler.py +0 -0
  38. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Core/Media/MediaManager.py +0 -0
  39. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Core/Plugin/PluginBase.py +0 -0
  40. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Core/Plugin/PluginLoader.py +0 -0
  41. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Core/Plugin/PluginManager.py +0 -0
  42. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Core/Plugin/PluginModels.py +0 -0
  43. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Core/UI/UIManager.py +0 -0
  44. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Core/__init__.py +0 -0
  45. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/CloseLoad.py +0 -0
  46. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/ContentX.py +0 -0
  47. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/DonilasPlay.py +0 -0
  48. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/DzenRu.py +0 -0
  49. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/ExPlay.py +0 -0
  50. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/Filemoon.py +0 -0
  51. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/HDMomPlayer.py +0 -0
  52. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/HDPlayerSystem.py +0 -0
  53. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/HotStream.py +0 -0
  54. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/JFVid.py +0 -0
  55. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/JetTv.py +0 -0
  56. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/MailRu.py +0 -0
  57. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/MixPlayHD.py +0 -0
  58. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/MixTiger.py +0 -0
  59. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/MolyStream.py +0 -0
  60. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/Odnoklassniki.py +0 -0
  61. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/PeaceMakerst.py +0 -0
  62. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/PixelDrain.py +0 -0
  63. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/PlayerFilmIzle.py +0 -0
  64. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/RapidVid.py +0 -0
  65. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/SetPlay.py +0 -0
  66. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/SetPrime.py +0 -0
  67. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/SibNet.py +0 -0
  68. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/Sobreatsesuyp.py +0 -0
  69. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/TRsTX.py +0 -0
  70. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/TauVideo.py +0 -0
  71. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/TurboImgz.py +0 -0
  72. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/TurkeyPlayer.py +0 -0
  73. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/VCTPlay.py +0 -0
  74. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/VidMoly.py +0 -0
  75. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/VidMoxy.py +0 -0
  76. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/VidPapi.py +0 -0
  77. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/VideoSeyred.py +0 -0
  78. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/Videostr.py +0 -0
  79. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/Vidoza.py +0 -0
  80. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/YTDLP.py +0 -0
  81. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Extractors/YildizKisaFilm.py +0 -0
  82. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Plugins/DiziYou.py +0 -0
  83. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Plugins/KultFilmler.py +0 -0
  84. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Plugins/RecTV.py +0 -0
  85. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Plugins/RoketDizi.py +0 -0
  86. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Plugins/SelcukFlix.py +0 -0
  87. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Plugins/SetFilmIzle.py +0 -0
  88. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Plugins/SezonlukDizi.py +0 -0
  89. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Plugins/SineWix.py +0 -0
  90. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Plugins/Sinefy.py +0 -0
  91. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Plugins/SinemaCX.py +0 -0
  92. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Plugins/Sinezy.py +0 -0
  93. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Plugins/SuperFilmGeldi.py +0 -0
  94. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Plugins/UgurFilm.py +0 -0
  95. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Plugins/Watch32.py +0 -0
  96. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/Plugins/YabanciDizi.py +0 -0
  97. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/__init__.py +0 -0
  98. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/__main__.py +0 -0
  99. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream/requirements.txt +0 -0
  100. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream.egg-info/dependency_links.txt +0 -0
  101. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream.egg-info/entry_points.txt +0 -0
  102. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream.egg-info/requires.txt +0 -0
  103. {kekikstream-2.4.7 → kekikstream-2.4.9}/KekikStream.egg-info/top_level.txt +0 -0
  104. {kekikstream-2.4.7 → kekikstream-2.4.9}/LICENSE +0 -0
  105. {kekikstream-2.4.7 → kekikstream-2.4.9}/MANIFEST.in +0 -0
  106. {kekikstream-2.4.7 → kekikstream-2.4.9}/README.md +0 -0
  107. {kekikstream-2.4.7 → kekikstream-2.4.9}/setup.cfg +0 -0
@@ -0,0 +1,55 @@
1
+ # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
+
3
+ from KekikStream.Core import ExtractorBase, ExtractResult, HTMLHelper
4
+ import json, re
5
+
6
+ class JetV(ExtractorBase):
7
+ name = "JetV"
8
+ main_url = "https://jetv.xyz"
9
+
10
+ async def extract(self, url: str, referer: str = None) -> list[ExtractResult]:
11
+ istek = await self.httpx.get(url, headers={"Referer": referer} if referer else None)
12
+ text = istek.text
13
+
14
+ # Script içindeki sources kısmını bul
15
+ # "sources": [ ... ]
16
+ sources_str = HTMLHelper(text).regex_first(r'"sources":\s*(\[.*?\])')
17
+ if not sources_str:
18
+ # Altenatif: sources: [ ... ] (tırnaksız sources)
19
+ sources_str = HTMLHelper(text).regex_first(r'sources:\s*(\[.*?\])')
20
+
21
+ if not sources_str:
22
+ raise ValueError(f"JetV: Sources bulunamadı. {url}")
23
+
24
+ # file: -> "file":
25
+ clean_json = re.sub(r'(\w+):', r'"\1":', sources_str)
26
+ # ' -> "
27
+ clean_json = clean_json.replace("'", '"')
28
+
29
+ try:
30
+ sources = json.loads(clean_json)
31
+ except:
32
+ # Basit parser yetmediyse, manuel parse deneyelim (tek kaynak varsa)
33
+ file_url = HTMLHelper(sources_str).regex_first(r'file["\']?:\s*["\']([^"\']+)["\']')
34
+ label = HTMLHelper(sources_str).regex_first(r'label["\']?:\s*["\']([^"\']+)["\']')
35
+ if file_url:
36
+ sources = [{"file": file_url, "label": label or "Unknown"}]
37
+ else:
38
+ raise ValueError("JetV: JSON parse hatası")
39
+
40
+ results = []
41
+ for source in sources:
42
+ file_path = source.get("file")
43
+ label = source.get("label", "Unknown")
44
+
45
+ if not file_path:
46
+ continue
47
+
48
+ results.append(ExtractResult(
49
+ name = f"{self.name} | {label}",
50
+ url = self.fix_url(file_path),
51
+ referer = url,
52
+ user_agent = self.httpx.headers.get("User-Agent", "")
53
+ ))
54
+
55
+ return results
@@ -0,0 +1,145 @@
1
+ # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
+
3
+ from KekikStream.Core import ExtractorBase, ExtractResult, HTMLHelper
4
+ from contextlib import suppress
5
+
6
+ class Veev(ExtractorBase):
7
+ name = "Veev"
8
+ main_url = "https://veev.to"
9
+
10
+ supported_domains = ["veev.to", "kinoger.to", "poophq.com", "doods.pro", "dood.so", "dood.li", "dood.wf", "dood.cx", "dood.sh", "dood.watch", "dood.pm", "dood.to", "dood.ws"]
11
+
12
+ def can_handle_url(self, url: str) -> bool:
13
+ return any(domain in url for domain in self.supported_domains)
14
+
15
+ def veev_decode(self, encoded: str) -> str:
16
+ if not encoded:
17
+ return ""
18
+
19
+ result = []
20
+ # Python dictionary key integer, value string
21
+ # Başlangıçta 0-255 ascii karakterleri
22
+ lut = {i: chr(i) for i in range(256)}
23
+ n = 256
24
+
25
+ c = encoded[0]
26
+ result.append(c)
27
+
28
+ for char in encoded[1:]:
29
+ code = ord(char)
30
+ if code < 256:
31
+ nc = char
32
+ else:
33
+ nc = lut.get(code, c + c[0])
34
+
35
+ result.append(nc)
36
+ lut[n] = c + nc[0]
37
+ n += 1
38
+ c = nc
39
+
40
+ return "".join(result)
41
+
42
+ def build_array(self, encoded: str) -> list[list[int]]:
43
+ result = []
44
+ iterator = iter(encoded)
45
+
46
+ def next_int_or_zero():
47
+ try:
48
+ char = next(iterator)
49
+ if char.isdigit():
50
+ return int(char)
51
+ return 0
52
+ except StopIteration:
53
+ return 0
54
+
55
+ count = next_int_or_zero()
56
+ while count != 0:
57
+ row = []
58
+ for _ in range(count):
59
+ row.append(next_int_or_zero())
60
+ result.append(list(reversed(row)))
61
+ count = next_int_or_zero()
62
+
63
+ return result
64
+
65
+ def decode_url(self, encoded: str, rules: list[int]) -> str:
66
+ text = encoded
67
+ for r in rules:
68
+ if r == 1:
69
+ text = text[::-1]
70
+
71
+ # Hex decode
72
+ with suppress(Exception):
73
+ # remove optional whitespace just in case
74
+ clean_hex = "".join(text.split())
75
+ arr = bytes.fromhex(clean_hex)
76
+ # utf-8 decode, replace errors
77
+ text = arr.decode('utf-8', errors='replace')
78
+
79
+ text = text.replace("dXRmOA==", "")
80
+
81
+ return text
82
+
83
+ async def extract(self, url: str, referer: str = None) -> ExtractResult:
84
+ # URL'den ID çıkar
85
+ # https://veev.to/e/lla8v3k6arev
86
+ video_id = url.split("/")[-1]
87
+
88
+ # Sayfayı al
89
+ # Referer lazım mı? Genelde lazım olabilir.
90
+ page_url = f"{self.main_url}/e/{video_id}"
91
+ resp = await self.httpx.get(page_url, headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"})
92
+ html = resp.text
93
+
94
+ # Regex ile şifreli stringleri bul
95
+ # Regex: [.\s'](?:fc|_vvto\[[^]]*)(?:['\]]*)?\s*[:=]\s*['"]([^'"]+)
96
+ # Python regex için düzenleme gerekebilir.
97
+ found_values = HTMLHelper(html).regex_all(r"[.\s'](?:fc|_vvto\[[^]]*)(?:['\]]*)?\s*[:=]\s*['\"]([^'\"]+)")
98
+
99
+ if not found_values:
100
+ raise ValueError(f"Veev: Token bulunamadı. {url}")
101
+
102
+ # Kotlin kodunda sondan başlayıp deniyor (reversed)
103
+ for f in reversed(found_values):
104
+ try:
105
+ ch = self.veev_decode(f)
106
+ if ch == f:
107
+ continue # Decode olmadıysa geç
108
+
109
+ # API Call
110
+ dl_url = f"{self.main_url}/dl?op=player_api&cmd=gi&file_code={video_id}&r={self.main_url}&ch={ch}&ie=1"
111
+ api_resp = await self.httpx.get(dl_url, headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"})
112
+
113
+ data = api_resp.json()
114
+ file_obj = data.get("file")
115
+ if not file_obj or file_obj.get("file_status") != "OK":
116
+ continue
117
+
118
+ dv = file_obj.get("dv")
119
+ # dv json string içinde s key'inde olabilir (Kotlin: getString("s"))
120
+ # Ancak api yanıtını görmeden emin olamayız, json yapısına göre file->dv bir string mi object mi?
121
+ # Kotlin: file.getJSONArray("dv").getJSONObject(0).getString("s")
122
+ # Demek ki dv bir array
123
+
124
+ encoded_dv = None
125
+ if isinstance(dv, list) and len(dv) > 0:
126
+ if isinstance(dv[0], dict):
127
+ encoded_dv = dv[0].get("s")
128
+
129
+ if not encoded_dv:
130
+ continue
131
+
132
+ # Decode
133
+ # rules = buildArray(ch)[0]
134
+ rules = self.build_array(ch)[0]
135
+
136
+ final_url = self.decode_url(self.veev_decode(encoded_dv), rules)
137
+
138
+ if final_url.startswith("http"):
139
+ return ExtractResult(name=self.name, url=self.fix_url(final_url), referer=self.main_url)
140
+
141
+ except Exception as e:
142
+ # print(f"Veev Error: {e}")
143
+ continue
144
+
145
+ raise ValueError(f"Veev: Video URL'si çözülemedi. {url}")
@@ -0,0 +1,62 @@
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 Packer
5
+
6
+ class VidBiz(ExtractorBase):
7
+ name = "VidBiz"
8
+ main_url = "https://videolar.biz"
9
+
10
+ async def extract(self, url: str, referer: str = None) -> list[ExtractResult]:
11
+ istek = await self.httpx.get(url, headers={"Referer": referer} if referer else None)
12
+ text = istek.text
13
+
14
+ # Eval script bul (kaken içeriyor olmalı)
15
+ eval_script = HTMLHelper(text).regex_first(r'(eval\(function[\s\S]+?)<\/script>') or \
16
+ HTMLHelper(text).regex_first(r'(eval\(function[\s\S]+)')
17
+ if not eval_script:
18
+ raise ValueError(f"VidBiz: Packed script bulunamadı. {url}")
19
+
20
+ unpacked = ""
21
+ try:
22
+ unpacked = Packer.unpack(eval_script)
23
+ except:
24
+ raise ValueError("VidBiz: Unpack hatası")
25
+
26
+ # window.kaken="..."
27
+ kaken = HTMLHelper(unpacked).regex_first(r'window\.kaken\s*=\s*"([^"]+)"')
28
+ if not kaken:
29
+ raise ValueError("VidBiz: Kaken token bulunamadı")
30
+
31
+ # API POST
32
+ # Content-Type: text/plain önemli olabilir
33
+ resp = await self.httpx.post(
34
+ url = "https://s2.videolar.biz/api/",
35
+ content = kaken, # data yerine content=raw string
36
+ headers = {"Content-Type": "text/plain", "Referer": url}
37
+ )
38
+
39
+ try:
40
+ data = resp.json()
41
+ except:
42
+ raise ValueError("VidBiz: API yanıtı JSON değil")
43
+
44
+ if data.get("status") != "ok":
45
+ raise ValueError(f"VidBiz: API hatası {data}")
46
+
47
+ results = []
48
+ for source in data.get("sources", []):
49
+ file_url = source.get("file")
50
+ label = source.get("label", "Unknown")
51
+
52
+ if not file_url:
53
+ continue
54
+
55
+ results.append(ExtractResult(
56
+ name = f"{self.name} | {label}",
57
+ url = self.fix_url(file_url),
58
+ referer = url,
59
+ user_agent = self.httpx.headers.get("User-Agent", "")
60
+ ))
61
+
62
+ return results
@@ -0,0 +1,105 @@
1
+ # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
+
3
+ from KekikStream.Core import ExtractorBase, ExtractResult, Subtitle, HTMLHelper
4
+ from Kekik.Sifreleme import Packer
5
+ import re
6
+
7
+ class VidHide(ExtractorBase):
8
+ name = "VidHide"
9
+ main_url = "https://vidhidepro.com"
10
+
11
+ # Birden fazla domain destekle
12
+ supported_domains = [
13
+ "vidhidepro.com", "vidhide.com", "rubyvidhub.com",
14
+ "vidhidevip.com", "vidhideplus.com", "vidhidepre.com",
15
+ "movearnpre.com", "oneupload.to",
16
+ "filelions.live", "filelions.online", "filelions.to",
17
+ "kinoger.be",
18
+ "smoothpre.com",
19
+ "dhtpre.com",
20
+ "peytonepre.com"
21
+ ]
22
+
23
+ def can_handle_url(self, url: str) -> bool:
24
+ return any(domain in url for domain in self.supported_domains)
25
+
26
+ def get_embed_url(self, url: str) -> str:
27
+ if "/d/" in url:
28
+ return url.replace("/d/", "/v/")
29
+ elif "/download/" in url:
30
+ return url.replace("/download/", "/v/")
31
+ elif "/file/" in url:
32
+ return url.replace("/file/", "/v/")
33
+ elif "/embed/" in url:
34
+ return url.replace("/embed/", "/v/")
35
+ else:
36
+ return url.replace("/f/", "/v/")
37
+
38
+ async def extract(self, url: str, referer: str = None) -> ExtractResult:
39
+ base_url = self.get_base_url(url)
40
+ self.httpx.headers.update({
41
+ "Referer" : referer or base_url,
42
+ "Origin" : base_url,
43
+ })
44
+
45
+ embed_url = self.get_embed_url(url)
46
+ istek = await self.httpx.get(embed_url, follow_redirects=True)
47
+ text = istek.text
48
+
49
+ # Silinmiş dosya kontrolü
50
+ if "File is no longer available" in text or "File Not Found" in text:
51
+ raise ValueError(f"VidHide: Video silinmiş. {url}")
52
+
53
+ # JS Redirect Kontrolü (OneUpload vb.)
54
+ if js_redirect := HTMLHelper(text).regex_first(r"window\.location\.replace\(['\"]([^'\"]+)['\"]\)") or \
55
+ HTMLHelper(text).regex_first(r"window\.location\.href\s*=\s*['\"]([^'\"]+)['\"]"):
56
+ # Redirect url'i al
57
+ target_url = js_redirect
58
+ # Bazen path relative olabilir ama genelde full url
59
+ if not target_url.startswith("http"):
60
+ # urljoin gerekebilir ama şimdilik doğrudan deneyelim veya fix_url
61
+ target_url = self.fix_url(target_url) # fix_url base'e göre düzeltebilir mi? ExtractorBase.fix_url genelde şema ekler.
62
+ pass
63
+
64
+ # Yeniden istek at
65
+ istek = await self.httpx.get(target_url, headers={"Referer": embed_url}, follow_redirects=True)
66
+ text = istek.text
67
+
68
+ sel = HTMLHelper(text)
69
+
70
+ unpacked = ""
71
+ # Eval script bul (regex ile daha sağlam)
72
+ if eval_match := sel.regex_first(r'(eval\s*\(\s*function[\s\S]+?)<\/script>'):
73
+ try:
74
+ unpacked = Packer.unpack(eval_match)
75
+ if "var links" in unpacked:
76
+ unpacked = unpacked.split("var links")[1]
77
+ except:
78
+ pass
79
+
80
+ content = unpacked or text
81
+
82
+ # Regex: Kotlin mantığı (: "url")
83
+ # Ayrıca sources: [...] mantığını da ekle
84
+ m3u8_url = HTMLHelper(content).regex_first(r'sources:\s*\[\s*\{\s*file:\s*"([^"]+)"')
85
+
86
+ if not m3u8_url:
87
+ # Genel arama (hls:, file: vb.)
88
+ # Kotlin Regex: :\s*"(.*?m3u8.*?)"
89
+ match = HTMLHelper(content).regex_first(r':\s*["\']([^"\']+\.m3u8[^"\']*)["\']')
90
+ if match:
91
+ m3u8_url = match
92
+
93
+ if not m3u8_url:
94
+ # Son şans: herhangi bir m3u8 linki
95
+ m3u8_url = HTMLHelper(content).regex_first(r'["\']([^"\']+\.m3u8[^"\']*)["\']')
96
+
97
+ if not m3u8_url:
98
+ raise ValueError(f"VidHide: Video URL bulunamadı. {url}")
99
+
100
+ return ExtractResult(
101
+ name = self.name,
102
+ url = self.fix_url(m3u8_url),
103
+ referer = f"{base_url}/",
104
+ user_agent = self.httpx.headers.get("User-Agent", "")
105
+ )
@@ -0,0 +1,38 @@
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 Packer
5
+
6
+ class Vtbe(ExtractorBase):
7
+ name = "Vtbe"
8
+ main_url = "https://vtbe.to"
9
+
10
+ async def extract(self, url: str, referer: str = None) -> list[ExtractResult]:
11
+ # Iframe ise embed url'i düzeltmek gerekebilir ama genelde embed-xxxx.html formatı
12
+ istek = await self.httpx.get(url, headers={"Referer": referer or self.main_url})
13
+ text = istek.text
14
+
15
+ # Packed script bul: function(p,a,c,k,e,d)
16
+ packed = HTMLHelper(text).regex_first(r'(eval\s*\(\s*function[\s\S]+?)<\/script>')
17
+
18
+ if not packed:
19
+ raise ValueError(f"Vtbe: Packed script bulunamadı. {url}")
20
+
21
+ unpacked = ""
22
+ try:
23
+ unpacked = Packer.unpack(packed)
24
+ except:
25
+ raise ValueError("Vtbe: Unpack hatası")
26
+
27
+ # sources:[{file:"..."
28
+ file_url = HTMLHelper(unpacked).regex_first(r'sources:\s*\[\s*\{\s*file:\s*"([^"]+)"')
29
+
30
+ if not file_url:
31
+ raise ValueError("Vtbe: Video URL (file) bulunamadı")
32
+
33
+ return ExtractResult(
34
+ name = self.name,
35
+ url = self.fix_url(file_url),
36
+ referer = url,
37
+ user_agent = self.httpx.headers.get("User-Agent", "")
38
+ )
@@ -0,0 +1,61 @@
1
+ # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
+
3
+ from KekikStream.Core import ExtractorBase, ExtractResult, HTMLHelper
4
+
5
+ class Zeus(ExtractorBase):
6
+ name = "Zeus"
7
+ main_url = "https://d2rs.com"
8
+
9
+ async def extract(self, url: str, referer: str = None) -> list[ExtractResult]:
10
+ # Iframe içeriğini al
11
+ istek = await self.httpx.get(url, headers={"Referer": referer} if referer else None)
12
+ text = istek.text
13
+
14
+ # 'q' parametresini bul
15
+ # form.append("q", "...")
16
+ q_param = HTMLHelper(text).regex_first(r'form\.append\("q",\s*"([^"]+)"\)')
17
+
18
+ if not q_param:
19
+ raise ValueError(f"Zeus: 'q' parametresi bulunamadı. {url}")
20
+
21
+ # API'ye POST at
22
+ resp = await self.httpx.post(
23
+ url = "https://d2rs.com/zeus/api.php",
24
+ data = {"q": q_param},
25
+ headers = {"Referer": url}
26
+ )
27
+
28
+ try:
29
+ sources = resp.json()
30
+ except:
31
+ raise ValueError("Zeus: API yanıtı geçersiz JSON")
32
+
33
+ results = []
34
+ # [{"file": "...", "label": "Full HD", "type": "video/mp4"}, ...]
35
+ for i, source in enumerate(sources, 1):
36
+ file_path = source.get("file")
37
+ label = source.get("label") or ""
38
+ type_ = source.get("type", "")
39
+
40
+ if not file_path:
41
+ continue
42
+
43
+ full_url = f"https://d2rs.com/zeus/{file_path}"
44
+
45
+ # İsimlendirme
46
+ if label:
47
+ source_name = f"{self.name} | {label}"
48
+ else:
49
+ source_name = f"{self.name} | Kaynak {i}"
50
+
51
+ results.append(ExtractResult(
52
+ name = source_name,
53
+ url = self.fix_url(full_url),
54
+ referer = url,
55
+ user_agent = self.httpx.headers.get("User-Agent", "")
56
+ ))
57
+
58
+ if not results:
59
+ raise ValueError("Zeus: Kaynak bulunamadı")
60
+
61
+ return results
@@ -1,6 +1,7 @@
1
1
  # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
2
 
3
3
  from KekikStream.Core import PluginBase, MainPageResult, SearchResult, SeriesInfo, Episode, ExtractResult, HTMLHelper
4
+ from contextlib import suppress
4
5
 
5
6
  class BelgeselX(PluginBase):
6
7
  name = "BelgeselX"
@@ -209,12 +210,10 @@ class BelgeselX(PluginBase):
209
210
 
210
211
  # belgeselx.php redirect'ini çöz
211
212
  if "belgeselx.php" in video_url or "belgeselx2.php" in video_url:
212
- try:
213
+ with suppress(Exception):
213
214
  # HEAD isteği ile lokasyonu alalım
214
- resp = await self.httpx.head(video_url, headers={"Referer": main_url}, follow_redirects=True)
215
+ resp = await self.httpx.head(video_url, headers={"Referer": main_url}, follow_redirects=True)
215
216
  video_url = str(resp.url)
216
- except:
217
- pass
218
217
 
219
218
  links.append(ExtractResult(
220
219
  url = video_url,
@@ -52,8 +52,8 @@ class DiziBox(PluginBase):
52
52
 
53
53
  results = []
54
54
  for veri in secici.select("article.detailed-article"):
55
- title = secici.select_text("h3 a", veri)
56
- href = secici.select_attr("h3 a", "href", veri)
55
+ title = secici.select_text("h3 a", veri)
56
+ href = secici.select_attr("h3 a", "href", veri)
57
57
  poster = secici.select_attr("img", "src", veri)
58
58
 
59
59
  if title and href:
@@ -185,7 +185,7 @@ class DiziBox(PluginBase):
185
185
  # Aktif kaynağın adını bul (DBX Pro vs.)
186
186
  current_source_name = secici.select_text("div.video-toolbar option[selected]") or self.name
187
187
 
188
- results = []
188
+ results = []
189
189
  main_iframe = secici.select_attr("div#video-area iframe", "src")
190
190
 
191
191
  if main_iframe:
@@ -10,24 +10,32 @@ class DiziMom(PluginBase):
10
10
  description = "Binlerce yerli yabancı dizi arşivi, tüm sezonlar, kesintisiz bölümler. Sadece dizi izle, Dizimom heryerde seninle!"
11
11
 
12
12
  main_page = {
13
- f"{main_url}/tum-bolumler/page" : "Son Bölümler",
14
- f"{main_url}/yerli-dizi-izle/page" : "Yerli Diziler",
15
- f"{main_url}/yabanci-dizi-izle/page" : "Yabancı Diziler",
16
- f"{main_url}/tv-programlari-izle/page" : "TV Programları",
13
+ f"{main_url}/tum-bolumler/page" : "Son Bölümler",
14
+ f"{main_url}/yerli-dizi-izle/page" : "Yerli Diziler",
15
+ f"{main_url}/yabanci-dizi-izle/page" : "Yabancı Diziler",
16
+ f"{main_url}/tv-programlari-izle/page" : "TV Programları",
17
+ f"{main_url}/netflix-dizileri-izle/page" : "Netflix Dizileri",
18
+ f"{main_url}/turkce-dublaj-diziler-hd/page" : "Dublajlı Diziler",
19
+ f"{main_url}/yerli-dizi-izle/page" : "Yerli Diziler",
20
+ f"{main_url}/anime-izle/page" : "Animeler",
21
+ f"{main_url}/yabanci-dizi-izle/page" : "Yabancı Diziler",
22
+ f"{main_url}/kore-dizileri-izle-hd/page" : "Kore Dizileri",
23
+ f"{main_url}/full-hd-hint-dizileri-izle/page" : "Hint Dizileri",
24
+ f"{main_url}/pakistan-dizileri-izle/page" : "Pakistan Dizileri",
25
+ f"{main_url}/tv-programlari-izle/page" : "Tv Programları",
17
26
  }
18
27
 
19
28
  async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
20
- full_url = f"{url}/{page}/"
21
- istek = await self.httpx.get(full_url)
22
- helper = HTMLHelper(istek.text)
29
+ istek = await self.httpx.get(f"{url}/{page}/")
30
+ secici = HTMLHelper(istek.text)
23
31
 
24
32
  results = []
25
33
  # Eğer "tum-bolumler" ise Episode kutularını, değilse Dizi kutularını tara
26
34
  if "/tum-bolumler/" in url:
27
- for item in helper.select("div.episode-box"):
28
- title = helper.select_text("div.episode-name a", item)
29
- href = helper.select_attr("div.episode-name a", "href", item)
30
- img = helper.select_poster("div.cat-img img", item)
35
+ for item in secici.select("div.episode-box"):
36
+ title = secici.select_text("div.episode-name a", item)
37
+ href = secici.select_attr("div.episode-name a", "href", item)
38
+ img = secici.select_poster("div.cat-img img", item)
31
39
  if title and href:
32
40
  results.append(MainPageResult(
33
41
  category = category,
@@ -36,10 +44,10 @@ class DiziMom(PluginBase):
36
44
  poster = self.fix_url(img)
37
45
  ))
38
46
  else:
39
- for item in helper.select("div.single-item"):
40
- title = helper.select_text("div.categorytitle a", item)
41
- href = helper.select_attr("div.categorytitle a", "href", item)
42
- img = helper.select_poster("div.cat-img img", item)
47
+ for item in secici.select("div.single-item"):
48
+ title = secici.select_text("div.categorytitle a", item)
49
+ href = secici.select_attr("div.categorytitle a", "href", item)
50
+ img = secici.select_poster("div.cat-img img", item)
43
51
  if title and href:
44
52
  results.append(MainPageResult(
45
53
  category = category,
@@ -51,38 +59,37 @@ class DiziMom(PluginBase):
51
59
  return results
52
60
 
53
61
  async def search(self, query: str) -> list[SearchResult]:
54
- url = f"{self.main_url}/?s={query}"
55
- istek = await self.httpx.get(url)
56
- helper = HTMLHelper(istek.text)
57
- items = helper.select("div.single-item")
62
+ istek = await self.httpx.get(f"{self.main_url}/?s={query}")
63
+ secici = HTMLHelper(istek.text)
64
+ items = secici.select("div.single-item")
58
65
 
59
66
  return [
60
67
  SearchResult(
61
- title = helper.select_text("div.categorytitle a", item).split(" izle")[0],
62
- url = self.fix_url(helper.select_attr("div.categorytitle a", "href", item)),
63
- poster = self.fix_url(helper.select_attr("div.cat-img img", "src", item))
68
+ title = secici.select_text("div.categorytitle a", item).split(" izle")[0],
69
+ url = self.fix_url(secici.select_attr("div.categorytitle a", "href", item)),
70
+ poster = self.fix_url(secici.select_attr("div.cat-img img", "src", item))
64
71
  )
65
72
  for item in items
66
73
  ]
67
74
 
68
75
  async def load_item(self, url: str) -> SeriesInfo:
69
76
  istek = await self.httpx.get(url)
70
- helper = HTMLHelper(istek.text)
77
+ secici = HTMLHelper(istek.text)
71
78
 
72
- title = self.clean_title(helper.select_text("div.title h1"))
73
- poster = helper.select_poster("div.category_image img")
74
- description = helper.select_direct_text("div.category_desc")
75
- tags = helper.select_texts("div.genres a")
76
- rating = helper.regex_first(r"(?s)IMDB\s*:\s*(?:</span>)?\s*([\d\.]+)", helper.html)
77
- year = helper.extract_year("div.category_text")
78
- actors = helper.meta_list("Oyuncular", container_selector="div#icerikcat2")
79
+ title = self.clean_title(secici.select_text("div.title h1"))
80
+ poster = secici.select_poster("div.category_image img")
81
+ description = secici.select_direct_text("div.category_desc")
82
+ tags = secici.select_texts("div.genres a")
83
+ rating = secici.regex_first(r"(?s)IMDB\s*:\s*(?:</span>)?\s*([\d\.]+)", secici.html)
84
+ year = secici.extract_year("div.category_text")
85
+ actors = secici.meta_list("Oyuncular", container_selector="div#icerikcat2")
79
86
 
80
87
  episodes = []
81
- for item in helper.select("div.bolumust"):
82
- name = helper.select_text("div.baslik", item)
83
- href = helper.select_attr("a", "href", item)
88
+ for item in secici.select("div.bolumust"):
89
+ name = secici.select_text("div.baslik", item)
90
+ href = secici.select_attr("a", "href", item)
84
91
  if name and href:
85
- s, e = helper.extract_season_episode(name)
92
+ s, e = secici.extract_season_episode(name)
86
93
  episodes.append(Episode(
87
94
  season = s or 1,
88
95
  episode = e or 1,
@@ -120,27 +127,26 @@ class DiziMom(PluginBase):
120
127
  )
121
128
 
122
129
  istek = await self.httpx.get(url)
123
- helper = HTMLHelper(istek.text)
130
+ secici = HTMLHelper(istek.text)
124
131
 
125
132
  iframe_data = []
126
133
 
127
134
  # Aktif kaynağın (main iframe) adını bul
128
- current_name = helper.select_text("div.sources span.current_dil") or ""
129
- main_iframe = helper.select_attr("iframe[src]", "src")
135
+ current_name = secici.select_text("div.sources span.current_dil") or ""
136
+ main_iframe = secici.select_attr("iframe[src]", "src")
130
137
 
131
138
  # Bazen iframe doğrudan video p içinde olabilir
132
139
  if not main_iframe:
133
- main_iframe = helper.select_attr("div.video p iframe", "src")
140
+ main_iframe = secici.select_attr("div.video p iframe", "src")
134
141
 
135
142
  if main_iframe:
136
143
  iframe_data.append((main_iframe, current_name))
137
144
 
138
145
  # Diğer kaynakları (Partlar) gez
139
- sources = helper.select("div.sources a.post-page-numbers")
146
+ sources = secici.select("div.sources a.post-page-numbers")
140
147
  for source in sources:
141
- href = helper.select_attr(None, "href", source)
142
- name = helper.select_text("span.dil", source)
143
-
148
+ href = secici.select_attr(None, "href", source)
149
+ name = secici.select_text("span.dil", source)
144
150
  if href:
145
151
  # Part sayfasına git
146
152
  sub_istek = await self.httpx.get(href)