KekikStream 2.4.6__py3-none-any.whl → 2.4.8__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

Files changed (38) hide show
  1. KekikStream/Core/HTMLHelper.py +2 -2
  2. KekikStream/Core/Plugin/PluginBase.py +15 -4
  3. KekikStream/Extractors/Odnoklassniki.py +14 -2
  4. KekikStream/Extractors/YTDLP.py +2 -2
  5. KekikStream/Plugins/BelgeselX.py +30 -23
  6. KekikStream/Plugins/DiziBox.py +14 -11
  7. KekikStream/Plugins/DiziMom.py +110 -86
  8. KekikStream/Plugins/DiziPal.py +37 -23
  9. KekikStream/Plugins/DiziYou.py +23 -11
  10. KekikStream/Plugins/Dizilla.py +35 -30
  11. KekikStream/Plugins/FilmBip.py +83 -18
  12. KekikStream/Plugins/FilmEkseni.py +100 -58
  13. KekikStream/Plugins/FilmMakinesi.py +71 -19
  14. KekikStream/Plugins/FilmModu.py +17 -20
  15. KekikStream/Plugins/Filmatek.py +103 -98
  16. KekikStream/Plugins/{Full4kizle.py → FilmciBaba.py} +61 -80
  17. KekikStream/Plugins/FullHDFilmizlesene.py +12 -14
  18. KekikStream/Plugins/HDFilm.py +243 -0
  19. KekikStream/Plugins/HDFilmCehennemi.py +194 -125
  20. KekikStream/Plugins/JetFilmizle.py +5 -5
  21. KekikStream/Plugins/KultFilmler.py +6 -6
  22. KekikStream/Plugins/RoketDizi.py +5 -5
  23. KekikStream/Plugins/SelcukFlix.py +2 -2
  24. KekikStream/Plugins/SetFilmIzle.py +5 -5
  25. KekikStream/Plugins/SezonlukDizi.py +4 -4
  26. KekikStream/Plugins/Sinefy.py +5 -5
  27. KekikStream/Plugins/SinemaCX.py +5 -5
  28. KekikStream/Plugins/Sinezy.py +5 -5
  29. KekikStream/Plugins/SuperFilmGeldi.py +5 -5
  30. KekikStream/Plugins/UgurFilm.py +4 -4
  31. KekikStream/Plugins/YabanciDizi.py +5 -5
  32. {kekikstream-2.4.6.dist-info → kekikstream-2.4.8.dist-info}/METADATA +1 -1
  33. {kekikstream-2.4.6.dist-info → kekikstream-2.4.8.dist-info}/RECORD +37 -37
  34. KekikStream/Plugins/FullHDFilm.py +0 -179
  35. {kekikstream-2.4.6.dist-info → kekikstream-2.4.8.dist-info}/WHEEL +0 -0
  36. {kekikstream-2.4.6.dist-info → kekikstream-2.4.8.dist-info}/entry_points.txt +0 -0
  37. {kekikstream-2.4.6.dist-info → kekikstream-2.4.8.dist-info}/licenses/LICENSE +0 -0
  38. {kekikstream-2.4.6.dist-info → kekikstream-2.4.8.dist-info}/top_level.txt +0 -0
@@ -1,11 +1,11 @@
1
1
  # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
2
 
3
- from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, SeriesInfo, Episode, Subtitle, ExtractResult, HTMLHelper
3
+ from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, SeriesInfo, Episode, Subtitle, ExtractResult, HTMLHelper
4
4
 
5
5
  class DiziPal(PluginBase):
6
6
  name = "DiziPal"
7
7
  language = "tr"
8
- main_url = "https://dizipal.cc"
8
+ main_url = "https://dizipal.uk"
9
9
  favicon = f"https://www.google.com/s2/favicons?domain={main_url}&sz=64"
10
10
  description = "dizipal güncel, dizipal yeni ve gerçek adresi. dizipal en yeni dizi ve filmleri güvenli ve hızlı şekilde sunar."
11
11
 
@@ -46,7 +46,7 @@ class DiziPal(PluginBase):
46
46
  category = category,
47
47
  title = title,
48
48
  url = self.fix_url(href),
49
- poster = self.fix_url(poster) if poster else None,
49
+ poster = self.fix_url(poster),
50
50
  ))
51
51
 
52
52
  return results
@@ -65,7 +65,7 @@ class DiziPal(PluginBase):
65
65
  results.append(SearchResult(
66
66
  title = title,
67
67
  url = self.fix_url(href),
68
- poster = self.fix_url(poster) if poster else None,
68
+ poster = self.fix_url(poster),
69
69
  ))
70
70
 
71
71
  return results
@@ -82,8 +82,8 @@ class DiziPal(PluginBase):
82
82
  rating = secici.meta_value("IMDB Puanı")
83
83
  duration_raw = secici.meta_value("Süre")
84
84
  if duration_raw:
85
- parts = duration_raw.split()
86
- saat = 0
85
+ parts = duration_raw.split()
86
+ saat = 0
87
87
  dakika = 0
88
88
 
89
89
  for p in parts:
@@ -95,7 +95,7 @@ class DiziPal(PluginBase):
95
95
  duration = saat * 60 + dakika
96
96
  else:
97
97
  duration = None
98
-
98
+
99
99
  tags = secici.meta_list("Tür")
100
100
  actors = secici.meta_list("Oyuncular")
101
101
  if not actors:
@@ -104,36 +104,50 @@ class DiziPal(PluginBase):
104
104
  if "/dizi/" in url:
105
105
  episodes = []
106
106
  for ep in secici.select("div.episode-item"):
107
- name = secici.select_text("h4 a", ep)
108
- href = secici.select_attr("a", "href", ep)
107
+ name = secici.select_text("h4 a", ep)
108
+ href = secici.select_attr("a", "href", ep)
109
109
  link_title = secici.select_attr("a", "title", ep)
110
-
110
+
111
111
  h4_texts = secici.select_texts("h4", ep)
112
- text = h4_texts[1] if len(h4_texts) > 1 else (h4_texts[0] if h4_texts else "")
112
+ text = h4_texts[1] if len(h4_texts) > 1 else (h4_texts[0] if h4_texts else "")
113
113
 
114
114
  full_text = f"{text} {link_title}" if link_title else text
115
115
 
116
116
  if name and href:
117
117
  s, e = secici.extract_season_episode(full_text or "")
118
- episodes.append(Episode(season=s, episode=e, title=name, url=self.fix_url(href)))
118
+ episodes.append(Episode(
119
+ season = s,
120
+ episode = e,
121
+ title = name,
122
+ url = self.fix_url(href)
123
+ ))
119
124
 
120
125
  return SeriesInfo(
121
- url=url, poster=poster.replace("https://test4test.online", self.main_url), title=title, description=description, tags=tags,
122
- rating=rating, year=year, duration=duration, episodes=episodes or None, actors=actors
126
+ url = url,
127
+ poster = poster.replace("https://test4test.online", self.main_url),
128
+ title = title,
129
+ description = description,
130
+ tags = tags,
131
+ rating = rating,
132
+ year = year,
133
+ duration = duration,
134
+ episodes = episodes,
135
+ actors = actors
123
136
  )
124
-
137
+
125
138
  return MovieInfo(
126
- url=url, poster=poster.replace("https://test4test.online", self.main_url), title=title, description=description, tags=tags,
127
- rating=rating, year=year, duration=duration, actors=actors
139
+ url = url,
140
+ poster = poster.replace("https://test4test.online", self.main_url),
141
+ title = title,
142
+ description = description,
143
+ tags = tags,
144
+ rating = rating,
145
+ year = year,
146
+ duration = duration,
147
+ actors = actors
128
148
  )
129
149
 
130
150
  async def load_links(self, url: str) -> list[ExtractResult]:
131
- # Reset headers to get HTML response
132
- self.httpx.headers.update({
133
- "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
134
- })
135
- self.httpx.headers.pop("X-Requested-With", None)
136
-
137
151
  istek = await self.httpx.get(url)
138
152
  secici = HTMLHelper(istek.text)
139
153
 
@@ -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 PluginBase, MainPageResult, SearchResult, SeriesInfo, Episode, Subtitle, ExtractResult, HTMLHelper
3
+ from KekikStream.Core import PluginBase, MainPageResult, SearchResult, SeriesInfo, Episode, Subtitle, ExtractResult, HTMLHelper
4
4
 
5
5
  class DiziYou(PluginBase):
6
6
  name = "DiziYou"
@@ -42,7 +42,7 @@ class DiziYou(PluginBase):
42
42
  category = category,
43
43
  title = title,
44
44
  url = self.fix_url(href),
45
- poster = self.fix_url(poster) if poster else None,
45
+ poster = self.fix_url(poster),
46
46
  ))
47
47
 
48
48
  return results
@@ -61,7 +61,7 @@ class DiziYou(PluginBase):
61
61
  results.append(SearchResult(
62
62
  title = title,
63
63
  url = self.fix_url(href),
64
- poster = self.fix_url(poster) if poster else None,
64
+ poster = self.fix_url(poster),
65
65
  ))
66
66
 
67
67
  return results
@@ -76,8 +76,8 @@ class DiziYou(PluginBase):
76
76
  tags = secici.select_texts("div.genres a")
77
77
  rating = secici.regex_first(r"(?is)IMDB\s*:\s*</span>([0-9.]+)", secici.html)
78
78
  year = secici.extract_year("div#icerikcat2")
79
- actors = secici.meta_value("Oyuncular", container_selector="div#icerikcat2")
80
- actors = [a.strip() for a in actors.split(",")] if actors else []
79
+ raw_actors = secici.meta_value("Oyuncular", container_selector="div#icerikcat2")
80
+ actors = [x.strip() for x in raw_actors.split(",")] if raw_actors else None
81
81
 
82
82
  episodes = []
83
83
  for link in secici.select("div#scrollbar-container a"):
@@ -86,23 +86,35 @@ class DiziYou(PluginBase):
86
86
  name = secici.select_text("div.bolumismi", link).strip("()")
87
87
  s, e = secici.extract_season_episode(f"{name} {href}")
88
88
  if e:
89
- episodes.append(Episode(season=s or 1, episode=e, title=name, url=self.fix_url(href)))
89
+ episodes.append(Episode(
90
+ season = s or 1,
91
+ episode = e,
92
+ title = name,
93
+ url = self.fix_url(href)
94
+ ))
90
95
 
91
96
  return SeriesInfo(
92
- url=url, poster=poster, title=title or "Bilinmiyor", description=description,
93
- tags=tags, rating=rating, year=str(year) if year else None, episodes=episodes, actors=actors
97
+ url = url,
98
+ poster = poster,
99
+ title = title,
100
+ description = description,
101
+ tags = tags,
102
+ rating = rating,
103
+ year = year,
104
+ episodes = episodes,
105
+ actors = actors
94
106
  )
95
107
 
96
108
  async def load_links(self, url: str) -> list[ExtractResult]:
97
109
  istek = await self.httpx.get(url)
98
110
  secici = HTMLHelper(istek.text)
99
-
111
+
100
112
  # Player iframe'inden ID'yi yakala
101
113
  iframe_src = secici.select_attr("iframe#diziyouPlayer", "src") or secici.select_attr("iframe[src*='/player/']", "src")
102
114
  if not iframe_src:
103
115
  return []
104
116
 
105
- item_id = iframe_src.split("/")[-1].replace(".html", "")
117
+ item_id = iframe_src.split("/")[-1].replace(".html", "")
106
118
  base_storage = self.main_url.replace("www", "storage")
107
119
 
108
120
  subtitles = []
@@ -132,4 +144,4 @@ class DiziYou(PluginBase):
132
144
  subtitles = subtitles
133
145
  ))
134
146
 
135
- return results
147
+ return results
@@ -1,10 +1,10 @@
1
1
  # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
2
 
3
- from KekikStream.Core import PluginBase, MainPageResult, SearchResult, SeriesInfo, Episode, ExtractResult, HTMLHelper
4
- from json import loads
5
- from urllib.parse import urlparse, urlunparse
6
- from Crypto.Cipher import AES
7
- from base64 import b64decode
3
+ from KekikStream.Core import PluginBase, MainPageResult, SearchResult, SeriesInfo, Episode, ExtractResult, HTMLHelper
4
+ from json import loads
5
+ from urllib.parse import urlparse, urlunparse
6
+ from Crypto.Cipher import AES
7
+ from base64 import b64decode
8
8
 
9
9
  class Dizilla(PluginBase):
10
10
  name = "Dizilla"
@@ -44,7 +44,7 @@ class Dizilla(PluginBase):
44
44
  category = category,
45
45
  title = veri.get("original_title"),
46
46
  url = self.fix_url(f"{self.main_url}/{veri.get('used_slug')}"),
47
- poster = self.fix_poster_url(self.fix_url(veri.get("object_poster_url"))),
47
+ poster = self.fix_poster_url(self.fix_url(veri.get("poster_url"))),
48
48
  )
49
49
  for veri in veriler
50
50
  ])
@@ -54,21 +54,21 @@ class Dizilla(PluginBase):
54
54
 
55
55
  # Genel olarak dizi sayfalarına giden linkleri al
56
56
  for veri in secici.select('a[href*="/dizi/"]'):
57
- href = secici.select_attr('a', 'href', veri)
57
+ href = secici.select_attr('a', 'href', veri)
58
58
  title = secici.select_text(None, veri)
59
59
  if not href or not title:
60
60
  continue
61
61
 
62
62
  # Detay sayfasından poster vb. bilgileri al
63
- ep_req = await self.httpx.get(self.fix_url(href))
63
+ ep_req = await self.httpx.get(self.fix_url(href))
64
64
  ep_secici = HTMLHelper(ep_req.text)
65
- poster = ep_secici.select_poster('img.imgt') or ep_secici.select_poster('img')
65
+ poster = ep_secici.select_poster('img.imgt') or ep_secici.select_poster('img')
66
66
 
67
67
  ana_sayfa.append(MainPageResult(
68
68
  category = category,
69
69
  title = title,
70
70
  url = self.fix_url(href),
71
- poster = self.fix_url(poster) if poster else None
71
+ poster = self.fix_url(poster)
72
72
  ))
73
73
 
74
74
  return ana_sayfa
@@ -138,15 +138,18 @@ class Dizilla(PluginBase):
138
138
  secici = HTMLHelper(istek.text)
139
139
 
140
140
  next_data_text = secici.select_text("script#__NEXT_DATA__")
141
- if not next_data_text: return None
141
+ if not next_data_text:
142
+ return None
142
143
 
143
144
  next_data = loads(next_data_text)
144
145
  secure_data = next_data.get("props", {}).get("pageProps", {}).get("secureData")
145
- if not secure_data: return None
146
+ if not secure_data:
147
+ return None
146
148
 
147
149
  decrypted = await self.decrypt_response(secure_data)
148
150
  content = decrypted.get("contentItem", {})
149
- if not content: return None
151
+ if not content:
152
+ return None
150
153
 
151
154
  title = content.get("original_title") or content.get("used_title")
152
155
  description = content.get("description") or content.get("used_description")
@@ -165,29 +168,34 @@ class Dizilla(PluginBase):
165
168
  slug = ep.get("used_slug")
166
169
  name = ep.get("episode_text") or ""
167
170
  if not any(e.season == s_no and e.episode == e_no for e in episodes):
168
- episodes.append(Episode(season=s_no, episode=e_no, title=name, url=self.fix_url(f"{self.main_url}/{slug}")))
171
+ episodes.append(Episode(
172
+ season = s_no,
173
+ episode = e_no,
174
+ title = name,
175
+ url = self.fix_url(f"{self.main_url}/{slug}")
176
+ ))
169
177
 
170
178
  return SeriesInfo(
171
179
  url = url,
172
180
  poster = poster,
173
- title = title or "Bilinmiyor",
181
+ title = title,
174
182
  description = description,
175
183
  tags = tags,
176
- rating = str(rating) if rating else None,
177
- year = str(year) if year else None,
184
+ rating = rating,
185
+ year = year,
178
186
  episodes = episodes,
179
187
  actors = actors
180
188
  )
181
189
 
182
190
  async def load_links(self, url: str) -> list[ExtractResult]:
183
- istek = await self.httpx.get(url)
184
- secici = HTMLHelper(istek.text)
191
+ istek = await self.httpx.get(url)
192
+ secici = HTMLHelper(istek.text)
185
193
 
186
194
  next_data_text = secici.select_text("script#__NEXT_DATA__")
187
195
  if not next_data_text:
188
196
  return []
189
197
 
190
- next_data = loads(next_data_text)
198
+ next_data = loads(next_data_text)
191
199
  secure_data = next_data.get("props", {}).get("pageProps", {}).get("secureData", {})
192
200
  decrypted = await self.decrypt_response(secure_data)
193
201
  results = decrypted.get("RelatedResults", {}).get("getEpisodeSources", {}).get("result", [])
@@ -195,24 +203,21 @@ class Dizilla(PluginBase):
195
203
  if not results:
196
204
  return []
197
205
 
198
- # Get first source (matching Kotlin)
199
- first_result = results[0]
206
+ first_result = results[0]
200
207
  source_content = str(first_result.get("source_content", ""))
201
-
202
- # Clean the source_content string (matching Kotlin: .replace("\"", "").replace("\\", ""))
208
+
203
209
  cleaned_source = source_content.replace('"', '').replace('\\', '')
204
-
205
- # Parse cleaned HTML
210
+
206
211
  iframe_secici = HTMLHelper(cleaned_source)
207
- iframe_src = iframe_secici.select_attr("iframe", "src")
208
-
209
- # Referer check (matching Kotlin: loadExtractor(iframe, "${mainUrl}/", ...))
212
+ iframe_src = iframe_secici.select_attr("iframe", "src")
213
+
210
214
  iframe_url = self.fix_url(iframe_src) if iframe_src else None
211
-
215
+
212
216
  if not iframe_url:
213
217
  return []
214
218
 
215
219
  data = await self.extract(iframe_url, referer=f"{self.main_url}/", prefix=first_result.get('language_name', 'Unknown'))
216
220
  if not data:
217
221
  return []
222
+
218
223
  return data if isinstance(data, list) else [data]
@@ -1,6 +1,7 @@
1
1
  # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
2
 
3
- from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, ExtractResult, HTMLHelper
3
+ from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, ExtractResult, HTMLHelper
4
+ from contextlib import suppress
4
5
 
5
6
  class FilmBip(PluginBase):
6
7
  name = "FilmBip"
@@ -39,8 +40,8 @@ class FilmBip(PluginBase):
39
40
 
40
41
  results = []
41
42
  for veri in secici.select("div.poster-long"):
42
- title = secici.select_attr("a.block img.lazy", "alt", veri)
43
- href = secici.select_attr("a.block", "href", veri)
43
+ title = secici.select_attr("a.block img.lazy", "alt", veri)
44
+ href = secici.select_attr("a.block", "href", veri)
44
45
  poster = secici.select_poster("a.block img.lazy", veri)
45
46
 
46
47
  if title and href:
@@ -48,7 +49,7 @@ class FilmBip(PluginBase):
48
49
  category = category,
49
50
  title = title,
50
51
  url = self.fix_url(href),
51
- poster = self.fix_url(poster) if poster else None,
52
+ poster = self.fix_url(poster),
52
53
  ))
53
54
 
54
55
  return results
@@ -87,7 +88,7 @@ class FilmBip(PluginBase):
87
88
  results.append(SearchResult(
88
89
  title = title.strip(),
89
90
  url = self.fix_url(href),
90
- poster = self.fix_url(poster) if poster else None,
91
+ poster = self.fix_url(poster),
91
92
  ))
92
93
 
93
94
  return results
@@ -108,13 +109,13 @@ class FilmBip(PluginBase):
108
109
 
109
110
  return MovieInfo(
110
111
  url = url,
111
- poster = self.fix_url(poster) if poster else None,
112
- title = title or "",
112
+ poster = self.fix_url(poster),
113
+ title = title,
113
114
  description = description,
114
115
  tags = tags,
115
- year = str(year) if year else None,
116
+ year = year,
116
117
  rating = rating,
117
- duration = int(duration) if duration else None,
118
+ duration = duration,
118
119
  actors = actors,
119
120
  )
120
121
 
@@ -123,14 +124,78 @@ class FilmBip(PluginBase):
123
124
  secici = HTMLHelper(istek.text)
124
125
 
125
126
  results = []
126
-
127
- for player in secici.select("div#tv-spoox2"):
128
- iframe = secici.select_attr("iframe", "src", player)
129
-
130
- if iframe:
131
- iframe = self.fix_url(iframe)
132
- data = await self.extract(iframe)
133
- if data:
134
- results.append(data)
127
+ for tab in secici.select("ul.tab.alternative-group li[data-number]"):
128
+ tab_id = tab.attrs.get("data-number")
129
+ tab_name = secici.select_text(None, tab)
130
+ tab_hash = tab.attrs.get("data-group-hash")
131
+
132
+ if not tab_id:
133
+ continue
134
+
135
+ button_data = [] # (player_name, iframe_url)
136
+
137
+ # İlgili content divini bul
138
+ content_div = secici.select_first(f"div#{tab_id}")
139
+
140
+ # Eğer div var ve içi doluysa oradan al
141
+ if content_div and secici.select("ul li button", content_div):
142
+ buttons = secici.select("ul li button", content_div)
143
+ for btn in buttons:
144
+ button_data.append((btn.text(strip=True), btn.attrs.get("data-hhs")))
145
+
146
+ elif tab_hash:
147
+ # Div yok veya boş, AJAX ile çek
148
+ with suppress(Exception):
149
+ hash_resp = await self.httpx.post(
150
+ url = f"{self.main_url}/get/video/group",
151
+ headers = {
152
+ "X-Requested-With" : "XMLHttpRequest",
153
+ "Content-Type" : "application/x-www-form-urlencoded; charset=UTF-8",
154
+ "Referer" : url
155
+ },
156
+ data = {"hash": tab_hash}
157
+ )
158
+
159
+ if hash_resp.status_code == 200:
160
+ json_data = hash_resp.json()
161
+ if json_data.get("success"):
162
+ # 1. Videos listesi (API yanıtı)
163
+ if videos := json_data.get("videos"):
164
+ for vid in videos:
165
+ button_data.append((vid.get("name"), vid.get("link")))
166
+
167
+ # 2. HTML content (Fallback)
168
+ else:
169
+ html_content = json_data.get("content") or json_data.get("html") or json_data.get("theme")
170
+ if html_content:
171
+ sub_helper = HTMLHelper(html_content)
172
+ sub_btns = sub_helper.select("ul li button")
173
+ for btn in sub_btns:
174
+ button_data.append((btn.text(strip=True), btn.attrs.get("data-hhs")))
175
+
176
+ for player_name, iframe_url in button_data:
177
+ with suppress(Exception):
178
+ if iframe_url:
179
+ data = await self.extract(
180
+ url = self.fix_url(iframe_url),
181
+ name_override = f"{tab_name} | {player_name}"
182
+ )
183
+ if data:
184
+ if isinstance(data, list):
185
+ results.extend(data)
186
+ else:
187
+ results.append(data)
188
+
189
+ # Eğer hiç sonuç bulunamazsa fallback
190
+ if not results:
191
+ for player in secici.select("div#tv-spoox2"):
192
+ if iframe := secici.select_attr("iframe", "src", player):
193
+ iframe = self.fix_url(iframe)
194
+ data = await self.extract(iframe)
195
+ if data:
196
+ if isinstance(data, list):
197
+ results.extend(data)
198
+ else:
199
+ results.append(data)
135
200
 
136
201
  return results