KekikStream 2.3.6__py3-none-any.whl → 2.3.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.
@@ -84,89 +84,87 @@ class RoketDizi(PluginBase):
84
84
  except Exception:
85
85
  return []
86
86
 
87
- async def load_item(self, url: str) -> SeriesInfo:
88
- # Note: Handling both Movie and Series logic in one, returning SeriesInfo generally or MovieInfo
87
+ async def load_item(self, url: str) -> MovieInfo | SeriesInfo:
89
88
  resp = await self.httpx.get(url)
90
89
  sel = HTMLHelper(resp.text)
91
- html_text = resp.text
92
-
93
- title = sel.select_text("h1.text-white")
94
-
95
- poster = sel.select_attr("div.w-full.page-top img", "src")
96
-
97
- description = sel.select_text("div.mt-2.text-sm")
98
-
99
- # Tags - genre bilgileri (Detaylar bölümünde)
100
- tags = []
101
- genre_text = sel.select_text("h3.text-white.opacity-90")
102
- if genre_text:
103
- tags = [t.strip() for t in genre_text.split(",")]
104
-
105
- # Rating
106
- rating = sel.select_text("span.text-white.text-sm.font-bold")
107
-
108
- # Year ve Actors - Detaylar (Details) bölümünden
109
- year = None
110
- actors = []
90
+
91
+ next_data_text = sel.select_text("script#__NEXT_DATA__")
92
+ if not next_data_text:
93
+ return SeriesInfo(url=url, title=sel.select_text("h1") or "Bilinmeyen")
111
94
 
112
- # Detaylar bölümündeki tüm flex-col div'leri al
113
- detail_items = sel.select("div.flex.flex-col")
114
- for item in detail_items:
115
- label = sel.select_text("span.text-base", item)
116
- value = sel.select_text("span.text-sm.opacity-90", item)
95
+ try:
96
+ next_data = json.loads(next_data_text)
97
+ secure_data_raw = next_data["props"]["pageProps"]["secureData"]
98
+ secure_data = json.loads(base64.b64decode(secure_data_raw).decode('utf-8'))
117
99
 
118
- label = label if label else None
119
- value = value if value else None
100
+ content_item = secure_data.get("contentItem", {})
101
+ content = secure_data.get("content", {}).get("result", {})
120
102
 
121
- if label and value:
122
- # Yayın tarihi (yıl)
123
- if label == "Yayın tarihi":
124
- # "16 Ekim 2018" formatından yılı çıkar
125
- year = HTMLHelper(value).regex_first(r'\d{4}')
126
- # Yaratıcılar veya Oyuncular
127
- elif label in ["Yaratıcılar", "Oyuncular"]:
128
- if value:
129
- actors.append(value)
130
-
131
- # Check urls for episodes
132
- all_urls = HTMLHelper(html_text).regex_all(r'"url":"([^"]*)"')
133
- is_series = any("bolum-" in u for u in all_urls)
134
-
135
- episodes = []
136
- if is_series:
137
- # Dict kullanarak duplicate'leri önle ama sıralı tut
138
- episodes_dict = {}
139
- for u in all_urls:
140
- if "bolum" in u and u not in episodes_dict:
141
- season = HTMLHelper(u).regex_first(r'/sezon-(\d+)')
142
- ep_num = HTMLHelper(u).regex_first(r'/bolum-(\d+)')
143
-
144
- season = int(season) if season else 1
145
- episode_num = int(ep_num) if ep_num else 1
146
-
147
- # Key olarak (season, episode) tuple kullan
148
- key = (season, episode_num)
149
- episodes_dict[key] = Episode(
150
- season = season,
151
- episode = episode_num,
152
- title = f"{season}. Sezon {episode_num}. Bölüm",
153
- url = self.fix_url(u)
154
- )
155
-
156
- # Sıralı liste oluştur
157
- episodes = [episodes_dict[key] for key in sorted(episodes_dict.keys())]
158
-
159
- return SeriesInfo(
160
- title = title,
161
- url = url,
162
- poster = self.fix_url(poster) if poster else None,
163
- description = description,
164
- tags = tags,
165
- rating = rating,
166
- actors = actors,
167
- episodes = episodes,
168
- year = year
169
- )
103
+ title = content_item.get("original_title") or content_item.get("culture_title")
104
+ poster = content_item.get("poster_url") or content_item.get("face_url")
105
+ description = content_item.get("description")
106
+ rating = str(content_item.get("imdb_point") or "")
107
+ year = str(content_item.get("release_year") or "")
108
+ tags = content_item.get("categories", "").split(",")
109
+
110
+ # Actors extraction from getSerieCastsById or getMovieCastsById
111
+ actors = []
112
+ casts_data = content.get("getSerieCastsById") or content.get("getMovieCastsById")
113
+ if casts_data and casts_data.get("result"):
114
+ actors = [cast.get("name") for cast in casts_data["result"] if cast.get("name")]
115
+
116
+ # Episodes extraction
117
+ episodes = []
118
+ if "Series" in str(content.get("FindedType")):
119
+ # Check for episodes in SecureData -> RelatedResults -> getEpisodeSources (this might be for the current episode)
120
+ # Usually full episode list isn't in secureData, but we can get it from HTML or another API
121
+ # However, many times Next.js pages have them in props
122
+ # Let's fallback to the previous regex method for episodes if not in JSON
123
+ all_urls = HTMLHelper(resp.text).regex_all(r'"url":"([^"]*)"')
124
+ episodes_dict = {}
125
+ for u in all_urls:
126
+ if "bolum" in u and u not in episodes_dict:
127
+ s_match = HTMLHelper(u).regex_first(r'/sezon-(\d+)')
128
+ e_match = HTMLHelper(u).regex_first(r'/bolum-(\d+)')
129
+ s_val = int(s_match) if s_match else 1
130
+ e_val = int(e_match) if e_match else 1
131
+ episodes_dict[(s_val, e_val)] = Episode(
132
+ season = s_val,
133
+ episode = e_val,
134
+ title = f"{s_val}. Sezon {e_val}. Bölüm",
135
+ url = self.fix_url(u)
136
+ )
137
+ episodes = [episodes_dict[key] for key in sorted(episodes_dict.keys())]
138
+
139
+ return SeriesInfo(
140
+ url = url,
141
+ poster = self.fix_url(poster) if poster else None,
142
+ title = self.clean_title(title),
143
+ description = description,
144
+ tags = tags,
145
+ rating = rating,
146
+ year = year,
147
+ actors = actors,
148
+ episodes = episodes
149
+ )
150
+ else:
151
+ return MovieInfo(
152
+ url = url,
153
+ poster = self.fix_url(poster) if poster else None,
154
+ title = self.clean_title(title),
155
+ description = description,
156
+ tags = tags,
157
+ rating = rating,
158
+ year = year,
159
+ actors = actors
160
+ )
161
+
162
+ except Exception:
163
+ # Fallback to simple extraction if JSON parsing fails
164
+ return SeriesInfo(
165
+ url = url,
166
+ title = self.clean_title(sel.select_text("h1")) or "Bilinmeyen"
167
+ )
170
168
 
171
169
  async def load_links(self, url: str) -> list[ExtractResult]:
172
170
  resp = await self.httpx.get(url)
@@ -184,76 +184,99 @@ class SelcukFlix(PluginBase):
184
184
  async def load_item(self, url: str) -> MovieInfo | SeriesInfo:
185
185
  resp = await self.httpx.get(url)
186
186
  sel = HTMLHelper(resp.text)
187
+
188
+ next_data_text = sel.select_text("script#__NEXT_DATA__")
189
+ if not next_data_text:
190
+ return SeriesInfo(url=url, title=sel.select_text("h1") or "Bilinmeyen")
187
191
 
188
- next_data = sel.select_text("script#__NEXT_DATA__")
189
- if not next_data:
190
- return None
191
-
192
- data = json.loads(next_data)
193
- secure_data = data["props"]["pageProps"]["secureData"]
194
- raw_data = base64.b64decode(secure_data.replace('"', ''))
195
192
  try:
196
- decoded_str = raw_data.decode('utf-8')
197
- except UnicodeDecodeError:
198
- decoded_str = raw_data.decode('iso-8859-1')
199
-
200
- content_details = json.loads(decoded_str)
201
- item = content_details.get("contentItem", {})
202
-
203
- title = item.get("original_title") or item.get("originalTitle") or ""
204
- poster = self.clean_image_url(item.get("poster_url") or item.get("posterUrl"))
205
- description = item.get("description") or item.get("used_description")
206
- rating = str(item.get("imdb_point") or item.get("imdbPoint", ""))
207
- year = item.get("release_year") or item.get("releaseYear")
208
- duration = item.get("total_minutes") or item.get("totalMinutes")
209
-
210
- series_data = content_details.get("relatedData", {}).get("seriesData")
211
- if not series_data and "RelatedResults" in content_details:
212
- series_data = content_details["RelatedResults"].get("getSerieSeasonAndEpisodes", {}).get("result")
213
- if series_data and isinstance(series_data, list):
214
- pass
215
-
216
- # Dizi mi film mi kontrol et (Kotlin referansı)
217
- if series_data:
218
- episodes = []
219
- seasons_list = []
220
- if isinstance(series_data, dict):
221
- seasons_list = series_data.get("seasons", [])
222
- elif isinstance(series_data, list):
223
- seasons_list = series_data
224
-
225
- for season in seasons_list:
226
- if not isinstance(season, dict): continue
227
- s_no = season.get("season_no") or season.get("seasonNo")
228
- ep_list = season.get("episodes", [])
229
- for ep in ep_list:
230
- episodes.append(Episode(
231
- season = s_no,
232
- episode = ep.get("episode_no") or ep.get("episodeNo"),
233
- title = ep.get("ep_text") or ep.get("epText"),
234
- url = self.fix_url(ep.get("used_slug") or ep.get("usedSlug"))
235
- ))
193
+ next_data = json.loads(next_data_text)
194
+ secure_data_raw = next_data["props"]["pageProps"].get("secureData")
195
+ if not secure_data_raw:
196
+ return SeriesInfo(url=url, title=sel.select_text("h1") or "Bilinmeyen")
236
197
 
237
- return SeriesInfo(
238
- title = title,
239
- url = url,
240
- poster = poster,
241
- description = description,
242
- rating = rating,
243
- year = year,
244
- episodes = episodes
245
- )
246
- else:
247
- # Film ise MovieInfo döndür
248
- return MovieInfo(
249
- title = title,
250
- url = url,
251
- poster = poster,
252
- description = description,
253
- rating = rating,
254
- year = year,
255
- duration = duration
256
- )
198
+ # Clean possible quotes from string before decoding
199
+ if isinstance(secure_data_raw, str):
200
+ secure_data_raw = secure_data_raw.strip('"')
201
+
202
+ decoded_str = base64.b64decode(secure_data_raw).decode('utf-8')
203
+ content_details = json.loads(decoded_str)
204
+
205
+ # Sometimes content_details might be a string (double encoded)
206
+ if isinstance(content_details, str):
207
+ content_details = json.loads(content_details)
208
+
209
+ print(f"DEBUG: type(content_details)={type(content_details)}")
210
+ item = content_details.get("contentItem", {})
211
+ print(f"DEBUG: type(item)={type(item)}")
212
+ related_results = content_details.get("RelatedResults", {})
213
+
214
+ title = item.get("original_title") or item.get("culture_title") or item.get("originalTitle") or ""
215
+ poster = self.clean_image_url(item.get("poster_url") or item.get("posterUrl") or item.get("face_url"))
216
+ description = item.get("description") or item.get("used_description")
217
+ rating = str(item.get("imdb_point") or item.get("imdbPoint") or "")
218
+ year = str(item.get("release_year") or item.get("releaseYear") or "")
219
+ duration = item.get("total_minutes") or item.get("totalMinutes")
220
+
221
+ tags = []
222
+ tags_raw = item.get("category_names") or item.get("categoryNames") or item.get("categories")
223
+ if isinstance(tags_raw, str):
224
+ tags = [t.strip() for t in tags_raw.split(",")]
225
+ elif isinstance(tags_raw, list):
226
+ tags = [c.get("title") if isinstance(c, dict) else str(c) for c in tags_raw]
227
+
228
+ actors = []
229
+ actors_raw = item.get("actor_names") or item.get("actorNames")
230
+ if isinstance(actors_raw, str):
231
+ actors = [a.strip() for a in actors_raw.split(",")]
232
+
233
+ # Casts from RelatedResults
234
+ casts_data = related_results.get("getSerieCastsById") or related_results.get("getMovieCastsById")
235
+ if casts_data and isinstance(casts_data, dict) and casts_data.get("result"):
236
+ actors = [cast.get("name") for cast in casts_data["result"] if cast.get("name")]
237
+
238
+ series_data = related_results.get("getSerieSeasonAndEpisodes")
239
+ if series_data and isinstance(series_data, dict) and series_data.get("result"):
240
+ episodes = []
241
+ for season in series_data["result"]:
242
+ s_no = season.get("season_no") or season.get("seasonNo") or 1
243
+ for ep in season.get("episodes", []):
244
+ ep_slug = ep.get("used_slug") or ep.get("usedSlug")
245
+ if ep_slug:
246
+ episodes.append(Episode(
247
+ season = s_no,
248
+ episode = ep.get("episode_no") or ep.get("episodeNo") or 1,
249
+ title = ep.get("ep_text") or ep.get("epText") or "",
250
+ url = self.fix_url(ep_slug)
251
+ ))
252
+
253
+ return SeriesInfo(
254
+ url = url,
255
+ poster = poster,
256
+ title = self.clean_title(title),
257
+ description = description,
258
+ tags = tags,
259
+ rating = rating,
260
+ year = year,
261
+ actors = actors,
262
+ duration = duration,
263
+ episodes = episodes
264
+ )
265
+ else:
266
+ return MovieInfo(
267
+ url = url,
268
+ poster = poster,
269
+ title = self.clean_title(title),
270
+ description = description,
271
+ tags = tags,
272
+ rating = rating,
273
+ year = year,
274
+ actors = actors,
275
+ duration = duration
276
+ )
277
+
278
+ except Exception:
279
+ return SeriesInfo(url=url, title=self.clean_title(sel.select_text("h1")) or "Bilinmeyen")
257
280
 
258
281
  async def load_links(self, url: str) -> list[ExtractResult]:
259
282
  resp = await self.httpx.get(url)
@@ -33,8 +33,8 @@ class SetFilmIzle(PluginBase):
33
33
  f"{main_url}/tur/western/" : "Western"
34
34
  }
35
35
 
36
- def _get_nonce(self, nonce_type: str = "video_nonce", referer: str = None) -> str:
37
- """Site cache'lenmiş nonce'ları expire olabiliyor, fresh nonce al"""
36
+ def _get_nonce(self, nonce_type: str = "video", referer: str = None) -> str:
37
+ """Site cache'lenmiş nonce'ları expire olabiliyor, fresh nonce al veya sayfadan çek"""
38
38
  try:
39
39
  resp = self.cloudscraper.post(
40
40
  f"{self.main_url}/wp-admin/admin-ajax.php",
@@ -45,8 +45,19 @@ class SetFilmIzle(PluginBase):
45
45
  },
46
46
  data = "action=st_cache_refresh_nonces"
47
47
  )
48
- nonces = resp.json().get("data", {}).get("nonces", {})
49
- return nonces.get(nonce_type, "")
48
+ data = resp.json()
49
+ if data and data.get("success"):
50
+ nonces = data.get("data", {}).get("nonces", {})
51
+ return nonces.get(nonce_type if nonce_type != "search" else "dt_ajax_search", "")
52
+ except:
53
+ pass
54
+
55
+ # AJAX başarısızsa sayfadan çekmeyi dene
56
+ try:
57
+ main_resp = self.cloudscraper.get(referer or self.main_url)
58
+ # STMOVIE_AJAX = { ... nonces: { search: "...", ... } }
59
+ nonce = HTMLHelper(main_resp.text).regex_first(rf'"{nonce_type}":\s*"([^"]+)"')
60
+ return nonce or ""
50
61
  except:
51
62
  return ""
52
63
 
@@ -112,7 +123,7 @@ class SetFilmIzle(PluginBase):
112
123
  return results
113
124
 
114
125
  async def load_item(self, url: str) -> MovieInfo | SeriesInfo:
115
- istek = await self.httpx.get(url)
126
+ istek = self.cloudscraper.get(url)
116
127
  secici = HTMLHelper(istek.text)
117
128
  html_text = istek.text
118
129
 
@@ -123,15 +134,21 @@ class SetFilmIzle(PluginBase):
123
134
 
124
135
  description = secici.select_text("div.wp-content p")
125
136
 
126
- year_text = secici.select_text("div.extra span.C a")
127
- year = secici.regex_first(r"\d{4}", year_text) if year_text else None
137
+ rating = secici.select_text("b#repimdb strong") or secici.regex_first(r'repimdb"><strong>\s*([^<]+)</strong>', html_text)
138
+
139
+ # Yıl için info bölümünden veya regex ile yakala
140
+ year = secici.regex_first(r'(\d{4})', secici.select_text("div.extra span.valor") or secici.select_text("span.valor") or "")
141
+ if not year:
142
+ year = secici.regex_first(r'<span>(\d{4})</span>', html_text) or secici.regex_first(r'(\d{4})', html_text)
128
143
 
129
144
  tags = [a.text(strip=True) for a in secici.select("div.sgeneros a") if a.text(strip=True)]
130
145
 
131
146
  duration_text = secici.select_text("span.runtime")
132
147
  duration = int(secici.regex_first(r"\d+", duration_text)) if duration_text and secici.regex_first(r"\d+", duration_text) else None
133
148
 
134
- actors = [span.text(strip=True) for span in secici.select("span.valor a > span") if span.text(strip=True)]
149
+ actors = [a.text(strip=True) for a in secici.select("span.valor a") if "/oyuncu/" in (a.attrs.get("href") or "")]
150
+ if not actors:
151
+ actors = secici.regex_all(r'href="[^"]*/oyuncu/[^"]*">([^<]+)</a>')
135
152
 
136
153
  trailer = None
137
154
  if trailer_id := secici.regex_first(r'embed/([^?]*)\?rel', html_text):
@@ -179,6 +196,7 @@ class SetFilmIzle(PluginBase):
179
196
  title = title,
180
197
  description = description,
181
198
  tags = tags,
199
+ rating = rating,
182
200
  year = year,
183
201
  duration = duration,
184
202
  actors = actors,
@@ -191,6 +209,7 @@ class SetFilmIzle(PluginBase):
191
209
  title = title,
192
210
  description = description,
193
211
  tags = tags,
212
+ rating = rating,
194
213
  year = year,
195
214
  duration = duration,
196
215
  actors = actors
@@ -90,14 +90,17 @@ class YabanciDizi(PluginBase):
90
90
  poster = sel.select_attr("meta[property='og:image']", "content")
91
91
  description = sel.select_text("p#tv-series-desc")
92
92
 
93
- year = sel.select_text("td div.truncate")
94
- if year:
95
- year = year.strip()
93
+ # Try to extract year from table first
94
+ year_cell = sel.select_text("td div.truncate")
95
+ year = None
96
+ if year_cell:
97
+ year_match = sel.regex_first(r"(\d{4})", year_cell)
98
+ if year_match:
99
+ year = year_match
96
100
 
97
101
  tags = []
98
102
  rating = None
99
103
  duration = None
100
- year = None
101
104
  actors = []
102
105
  for item in sel.select("div.item"):
103
106
  text = item.text(strip=True)
@@ -174,13 +177,14 @@ class YabanciDizi(PluginBase):
174
177
  )
175
178
 
176
179
  async def load_links(self, url: str) -> list[ExtractResult]:
177
- resp = await self.httpx.get(url, headers={"Referer": f"{self.main_url}/"})
180
+ # Use cloudscraper to bypass Cloudflare
181
+ resp = self.cloudscraper.get(url, headers={"Referer": f"{self.main_url}/"})
178
182
  sel = HTMLHelper(resp.text)
179
183
 
180
184
  results = []
181
185
 
182
- # Method 1: alternatives-for-this
183
- for alt in sel.select("div.alternatives-for-this div.item:not(.active)"):
186
+ # Method 1: alternatives-for-this (include active too)
187
+ for alt in sel.select("div.alternatives-for-this div.item"):
184
188
  data_hash = alt.attrs.get("data-hash")
185
189
  data_link = alt.attrs.get("data-link")
186
190
  q_type = alt.attrs.get("data-querytype")
@@ -188,7 +192,7 @@ class YabanciDizi(PluginBase):
188
192
  if not data_hash or not data_link: continue
189
193
 
190
194
  try:
191
- post_resp = await self.httpx.post(
195
+ post_resp = self.cloudscraper.post(
192
196
  f"{self.main_url}/ajax/service",
193
197
  data = {
194
198
  "link" : data_link,
@@ -219,7 +223,7 @@ class YabanciDizi(PluginBase):
219
223
  data_eid = id_el.attrs.get("data-eid")
220
224
 
221
225
  try:
222
- post_resp = await self.httpx.post(
226
+ post_resp = self.cloudscraper.post(
223
227
  f"{self.main_url}/ajax/service",
224
228
  data = {
225
229
  "e_id" : data_eid,
@@ -244,9 +248,10 @@ class YabanciDizi(PluginBase):
244
248
 
245
249
  return results
246
250
 
247
- async def _fetch_and_extract(self, iframe_url, prefix=""):
251
+ def _fetch_and_extract_sync(self, iframe_url, prefix=""):
252
+ """Synchronous helper for _fetch_and_extract using cloudscraper."""
248
253
  # Initial fetch
249
- resp = await self.httpx.get(
254
+ resp = self.cloudscraper.get(
250
255
  iframe_url,
251
256
  headers = {"Referer": f"{self.main_url}/"},
252
257
  cookies = {"udys": "1760709729873", "level": "1"}
@@ -254,11 +259,12 @@ class YabanciDizi(PluginBase):
254
259
 
255
260
  # Handle "Lütfen bekleyiniz" check from Kotlin
256
261
  if "Lütfen bekleyiniz" in resp.text:
257
- await asyncio.sleep(1)
258
- timestamp = int(time.time())
262
+ import time as time_module
263
+ time_module.sleep(1)
264
+ timestamp = int(time_module.time())
259
265
  # Retry with t=timestamp as in Kotlin
260
266
  sep = "&" if "?" in iframe_url else "?"
261
- resp = await self.httpx.get(
267
+ resp = self.cloudscraper.get(
262
268
  f"{iframe_url}{sep}t={timestamp}",
263
269
  headers = {"Referer": f"{self.main_url}/"},
264
270
  cookies = resp.cookies # Use cookies from first response
@@ -267,6 +273,11 @@ class YabanciDizi(PluginBase):
267
273
  sel = HTMLHelper(resp.text)
268
274
  final_iframe = sel.select_attr("iframe", "src")
269
275
 
276
+ return final_iframe
277
+
278
+ async def _fetch_and_extract(self, iframe_url, prefix=""):
279
+ final_iframe = self._fetch_and_extract_sync(iframe_url, prefix)
280
+
270
281
  if final_iframe:
271
282
  final_url = self.fix_url(final_iframe)
272
283
  return await self.extract(final_url, referer=f"{self.main_url}/", prefix=prefix)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: KekikStream
3
- Version: 2.3.6
3
+ Version: 2.3.8
4
4
  Summary: terminal üzerinden medya içeriği aramanızı ve VLC/MPV gibi popüler medya oynatıcılar aracılığıyla doğrudan izlemenizi sağlayan modüler ve genişletilebilir bir bıdı bıdı
5
5
  Home-page: https://github.com/keyiflerolsun/KekikStream
6
6
  Author: keyiflerolsun
@@ -12,7 +12,7 @@ KekikStream/Core/Extractor/ExtractorModels.py,sha256=Qj_gbIeGRewaZXNfYkTi4FFRRq6
12
12
  KekikStream/Core/Extractor/YTDLPCache.py,sha256=sRg5kwFxkRXA_8iRwsV29E51g9qQJvg8dWUnzfr7EwA,984
13
13
  KekikStream/Core/Media/MediaHandler.py,sha256=MEn3spPAThVloN3WcoCwWhpoyMA7tAZvcwYjmjJsX3U,7678
14
14
  KekikStream/Core/Media/MediaManager.py,sha256=AaUq2D7JSJIphjoAj2fjLOJjswm7Qf5hjYCbBdrbnDU,438
15
- KekikStream/Core/Plugin/PluginBase.py,sha256=4y8ZyUhqvwn07GrARjAGEjIW4AoCkAzHkyZSkd_4USc,6439
15
+ KekikStream/Core/Plugin/PluginBase.py,sha256=DMuYf6fRZeRJWYh3UdGcV1FpmDjUnjO1pgIBMRqHjiY,6638
16
16
  KekikStream/Core/Plugin/PluginLoader.py,sha256=6LE5id0571bB-gJZxaLfd973XcG6oaGeMhLVcYYY7kw,3768
17
17
  KekikStream/Core/Plugin/PluginManager.py,sha256=6a0Q2mHtzIpx1ttdSTsVHg2HfLJIO0r_iHjK3Kui1Rw,939
18
18
  KekikStream/Core/Plugin/PluginModels.py,sha256=Yvx-6Fkn8QCIcuqAkFbCP5EJcq3XBkK_P8S0tRNhS6E,2476
@@ -29,7 +29,7 @@ KekikStream/Extractors/JetTv.py,sha256=2X1vYDQ0hxBTcpnE_XTcbw9tMS1aXFURcobnPdN8Z
29
29
  KekikStream/Extractors/MailRu.py,sha256=xQVCWwYqNoG5T43VAW1_m0v4e80FbO-1pNPKkwhTccU,1218
30
30
  KekikStream/Extractors/MixPlayHD.py,sha256=u5fUePHfjOI3n7KlNsWhXIv7HA_NMj5bPw1ug-eiXLU,1557
31
31
  KekikStream/Extractors/MixTiger.py,sha256=4VbOYgE4s5H-BGVvJI0AI57M-WBWqnek_LGfCFHAucw,2116
32
- KekikStream/Extractors/MolyStream.py,sha256=SGKr4HdfxDmRk6nPgQUjSbdqFCKWzl7xWxRJtjjFMng,1420
32
+ KekikStream/Extractors/MolyStream.py,sha256=sEyJE8L_49GOVOhkA_FvZjwXhzLhyue0gw3gQT-dW8A,3125
33
33
  KekikStream/Extractors/Odnoklassniki.py,sha256=hajKPhWKiIuu_i441TXrWVORpLo2CdTcoJiyU3WQAuI,4038
34
34
  KekikStream/Extractors/PeaceMakerst.py,sha256=BJ5Cv5X2GEaMTwn_XFpAVVmts1h5xGno3l5rL7Ugob4,2335
35
35
  KekikStream/Extractors/PixelDrain.py,sha256=xPud8W_hqLUXJSU5O-MiCOblcmzrlDJpnEtuxr4ZdI4,1011
@@ -45,30 +45,30 @@ KekikStream/Extractors/TurboImgz.py,sha256=zLGMUwoThZ_LoW0bThyV8TSCcIYHsUme1RTqq
45
45
  KekikStream/Extractors/TurkeyPlayer.py,sha256=zdX0IOO3M-kgAYWex2WwJJu9aGf8WhOY-ZIrRmZRiC0,1246
46
46
  KekikStream/Extractors/VCTPlay.py,sha256=1BCl2_vVIrwvG56LCzl2KE5g2CUaMAhzImOZMdZpZCQ,1377
47
47
  KekikStream/Extractors/VidHide.py,sha256=38ly2Gi44rxIyjeM-6H_HjmwXbKEpSqK4ba16ToQUYs,2707
48
- KekikStream/Extractors/VidMoly.py,sha256=XYgqlyCUdDNN7Naxa_rjX0WoB5zt17Dda_TdNEDpKOE,4974
48
+ KekikStream/Extractors/VidMoly.py,sha256=4k5z68MrUASUuDMEWZ_Ynvp1Z7njjRcXPBZAnpbtGB4,5500
49
49
  KekikStream/Extractors/VidMoxy.py,sha256=dM7yBfrXSESvYyqc2uP_gLSgV61gpIAY940NAQ58Mts,1843
50
50
  KekikStream/Extractors/VidPapi.py,sha256=9y8TN-o4C3JvRyr2V8Ox908tFE1I2BItQLHZlqs8AuI,3175
51
51
  KekikStream/Extractors/VideoSeyred.py,sha256=KJxbJkuupmn4wWBj_ejnoDvmjUXwEXkzStYha3EsSpA,1995
52
52
  KekikStream/Extractors/YTDLP.py,sha256=Hy8loCSFSquu2zaL3INord-Jm6T8CM6K2-VcDA2K79g,7390
53
53
  KekikStream/Extractors/YildizKisaFilm.py,sha256=R_JlrOVeMiDlXYcuTdItnKvidyx8_u3B14fSrxew2aE,1316
54
54
  KekikStream/Plugins/BelgeselX.py,sha256=smoLjEJTdptjb7h4m6LhG7ZUmJQtIhYyi0CUFBsk970,8696
55
- KekikStream/Plugins/DiziBox.py,sha256=KZGWhs6p2-hUTsd-fjz2fsmGEkanL4At2PI8qHAoDm4,10541
56
- KekikStream/Plugins/DiziPal.py,sha256=CTCGlknBUQIzubhvjexQoqiT3sHni34lpxiTLTemCGo,10299
57
- KekikStream/Plugins/DiziWatch.py,sha256=Y5-tBK316WdJhc-OZsYiwjSdfjcdz-A78o_bDP4qu08,8847
58
- KekikStream/Plugins/DiziYou.py,sha256=ZV80_XHv1nN0wRGgJEtnoJcgFX7S_iVSKFGiFlAqcGQ,11277
59
- KekikStream/Plugins/Dizilla.py,sha256=apDLGe3Fd-13nNyhcV_TFQxqX4bOZZZxEEGLonKQzS4,13803
60
- KekikStream/Plugins/FilmBip.py,sha256=pzvleSRZCDHh2tx8Q0JwTFiH9TexNCRnFpr3MCiMb0E,6087
61
- KekikStream/Plugins/FilmMakinesi.py,sha256=WaCQD7tsZdPbeU35SEnBVRZt2SzUiAQOBRBZR6drvQ4,7797
55
+ KekikStream/Plugins/DiziBox.py,sha256=CKfbMAtyE6J7QgD19iryzhD5VJlc0Tz2s4nSYW7XSrg,11354
56
+ KekikStream/Plugins/DiziPal.py,sha256=tHUqAN8UvvzBAkJaGS4hFvdLo-eRO4EdQ_C9HYkj_0U,10576
57
+ KekikStream/Plugins/DiziWatch.py,sha256=NK9xccX4-HwWq67FFVfqDDzKwCDc_HvDJDW2QIvqjig,8900
58
+ KekikStream/Plugins/DiziYou.py,sha256=4KOvxHg-84mUHuHWsXoYlIG2SX4DCV2dm6GblHQ5wGo,11162
59
+ KekikStream/Plugins/Dizilla.py,sha256=PLN0pOkWB4IaGC7Toe-8f5rksmaNm_WfdSFMTAtt--0,13624
60
+ KekikStream/Plugins/FilmBip.py,sha256=40eSECwMHSKTWoUmF90UXxTJkbx6f71J_98Ht4Hnoj8,6352
61
+ KekikStream/Plugins/FilmMakinesi.py,sha256=0bVN28aCEfrxrvXrGyL6XtgipzUKUD9vN2QkHie2gY0,7859
62
62
  KekikStream/Plugins/FilmModu.py,sha256=ou1BrFNR4RQaJdxVqPB5FI8vnQ0UmD-siVdwLnpp7x0,7147
63
63
  KekikStream/Plugins/FullHDFilm.py,sha256=08NF5qEydmxT0rGYDWpTOSIYSad8Uv1H1V8yCKG_568,10525
64
- KekikStream/Plugins/FullHDFilmizlesene.py,sha256=QD1mQwwPFkNoWgBdLaSPFq22S1N1RSKspyyTqz-1Wjk,7145
64
+ KekikStream/Plugins/FullHDFilmizlesene.py,sha256=OpdndVQ7LjZ-sJdILGEqhYX-0D18yRqTS7Kpu-HrXmY,6870
65
65
  KekikStream/Plugins/HDFilmCehennemi.py,sha256=jntMKgE81k_jl3pFzJI3akqvi3g8U961dVx7bj5Pf2w,13140
66
- KekikStream/Plugins/JetFilmizle.py,sha256=I76CCdH8AJAfjPr5jejtndidcGTBMrVfTFNjnZwp9yo,7801
67
- KekikStream/Plugins/KultFilmler.py,sha256=e5kXjGJYiI15PQhSADIGznqX7MlA0lK5HYnfFwx_cpM,9383
68
- KekikStream/Plugins/RecTV.py,sha256=E5ZyWU_lqibwcRm9amb_fqdXpc8qdMkekbHVxY3UmuU,7268
69
- KekikStream/Plugins/RoketDizi.py,sha256=92c3_UFIhM1SkB0Ybnp53A06VtGw2GmXtr-xmiKeJi0,8444
70
- KekikStream/Plugins/SelcukFlix.py,sha256=iHLO52_726gzmKAsqgW5ki2_V16fdGAZVjvaqqnQozY,13601
71
- KekikStream/Plugins/SetFilmIzle.py,sha256=pM4DgR2La9jUacQPRr4dilbfnljcC9l_o1OUipJh3Eg,10418
66
+ KekikStream/Plugins/JetFilmizle.py,sha256=9sH9Z3y4SP8vta9v-gJOQOxFWAQnbZomFea1_G5EbmM,8100
67
+ KekikStream/Plugins/KultFilmler.py,sha256=rvIkd2OXRxuAXHMjiHCRmKrS5m09gy2JoMBgJh7ZIOk,9478
68
+ KekikStream/Plugins/RecTV.py,sha256=p-RELvvD1-gyUgitwosYryH9gRWQTjmn1O9tw-0YInk,8295
69
+ KekikStream/Plugins/RoketDizi.py,sha256=KiX7Xf5IyPPJ-CVcJLM9qc0M6Fi2dhg7zU3EgWkICXA,9318
70
+ KekikStream/Plugins/SelcukFlix.py,sha256=nJ7I5e5vBkn9AbLC_2bSu9bSSgMQeDhCQZBZovK00bc,15299
71
+ KekikStream/Plugins/SetFilmIzle.py,sha256=Z8A_Ivbe65i13RocGZXwmpwrVxNOwdj7Gh3CS2-Fslg,11437
72
72
  KekikStream/Plugins/SezonlukDizi.py,sha256=h8mIglL2ORUklnAvEwH_5z6tT3WYxiNnbkeIvxtGUTE,9751
73
73
  KekikStream/Plugins/SineWix.py,sha256=z0r90lggAugEWE1g9vg8gZsInBObUZPnVFQwq7GYmJs,7052
74
74
  KekikStream/Plugins/Sinefy.py,sha256=ShX13Q-_5KFBobxZufI5V_4zwWvEWfNYuP-g5CkBuww,11099
@@ -76,10 +76,10 @@ KekikStream/Plugins/SinemaCX.py,sha256=11kzAZWgjkitIonDHHiFHMgnViBj-GjyvTXg7k28M
76
76
  KekikStream/Plugins/Sinezy.py,sha256=fUj-3WaJMEsKZRnDpHFPxl5Eq2RPLroY80DcftLqvjM,5743
77
77
  KekikStream/Plugins/SuperFilmGeldi.py,sha256=StW0ue4qDj8p7CiWy19Lfr2aWtfYvslPExZJuR-3xiY,6348
78
78
  KekikStream/Plugins/UgurFilm.py,sha256=H6AA2iTaM0fn6uN8_Dfvr-OqUtM9gDdkg0BKIcZEj7U,4930
79
- KekikStream/Plugins/YabanciDizi.py,sha256=r3jusGf1Ufr0O1O04qQLxcxk3raCI3EFs4Z2Jwva2-s,11444
80
- kekikstream-2.3.6.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
81
- kekikstream-2.3.6.dist-info/METADATA,sha256=X9pxvMO-FVM4PLZ1IyEKnRZCl4dmBYU0SZvQENp19z0,10761
82
- kekikstream-2.3.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
83
- kekikstream-2.3.6.dist-info/entry_points.txt,sha256=dFwdiTx8djyehI0Gsz-rZwjAfZzUzoBSrmzRu9ubjJc,50
84
- kekikstream-2.3.6.dist-info/top_level.txt,sha256=DNmGJDXl27Drdfobrak8KYLmocW_uznVYFJOzcjUgmY,12
85
- kekikstream-2.3.6.dist-info/RECORD,,
79
+ KekikStream/Plugins/YabanciDizi.py,sha256=QXzifSl2JMcVOwkwn2vafYIw1jqB5vBTrf-usvsyMBc,11947
80
+ kekikstream-2.3.8.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
81
+ kekikstream-2.3.8.dist-info/METADATA,sha256=9xG4vCFR9UYkg6ZuhfdW9WEIMlLDVVYZoRp5mJqdqSs,10761
82
+ kekikstream-2.3.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
83
+ kekikstream-2.3.8.dist-info/entry_points.txt,sha256=dFwdiTx8djyehI0Gsz-rZwjAfZzUzoBSrmzRu9ubjJc,50
84
+ kekikstream-2.3.8.dist-info/top_level.txt,sha256=DNmGJDXl27Drdfobrak8KYLmocW_uznVYFJOzcjUgmY,12
85
+ kekikstream-2.3.8.dist-info/RECORD,,