KekikStream 1.7.1__py3-none-any.whl → 2.2.0__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 (88) hide show
  1. KekikStream/Core/Extractor/ExtractorBase.py +20 -9
  2. KekikStream/Core/Extractor/ExtractorLoader.py +25 -17
  3. KekikStream/Core/Extractor/ExtractorManager.py +53 -9
  4. KekikStream/Core/Extractor/ExtractorModels.py +5 -7
  5. KekikStream/Core/Extractor/YTDLPCache.py +35 -0
  6. KekikStream/Core/Media/MediaHandler.py +44 -26
  7. KekikStream/Core/Media/MediaManager.py +0 -3
  8. KekikStream/Core/Plugin/PluginBase.py +82 -22
  9. KekikStream/Core/Plugin/PluginLoader.py +11 -7
  10. KekikStream/Core/Plugin/PluginModels.py +25 -26
  11. KekikStream/Core/__init__.py +1 -0
  12. KekikStream/Extractors/CloseLoad.py +21 -7
  13. KekikStream/Extractors/ContentX.py +21 -6
  14. KekikStream/Extractors/DonilasPlay.py +86 -0
  15. KekikStream/Extractors/DzenRu.py +38 -0
  16. KekikStream/Extractors/ExPlay.py +53 -0
  17. KekikStream/Extractors/Filemoon.py +78 -0
  18. KekikStream/Extractors/HDPlayerSystem.py +41 -0
  19. KekikStream/Extractors/JetTv.py +45 -0
  20. KekikStream/Extractors/MailRu.py +3 -4
  21. KekikStream/Extractors/MixPlayHD.py +2 -3
  22. KekikStream/Extractors/MixTiger.py +57 -0
  23. KekikStream/Extractors/MolyStream.py +5 -5
  24. KekikStream/Extractors/Odnoklassniki.py +13 -7
  25. KekikStream/Extractors/PeaceMakerst.py +10 -5
  26. KekikStream/Extractors/PixelDrain.py +1 -2
  27. KekikStream/Extractors/PlayerFilmIzle.py +65 -0
  28. KekikStream/Extractors/RapidVid.py +23 -8
  29. KekikStream/Extractors/SetPlay.py +66 -0
  30. KekikStream/Extractors/SetPrime.py +45 -0
  31. KekikStream/Extractors/SibNet.py +2 -3
  32. KekikStream/Extractors/Sobreatsesuyp.py +4 -5
  33. KekikStream/Extractors/TRsTX.py +4 -5
  34. KekikStream/Extractors/TauVideo.py +2 -3
  35. KekikStream/Extractors/TurboImgz.py +2 -3
  36. KekikStream/Extractors/TurkeyPlayer.py +34 -0
  37. KekikStream/Extractors/VCTPlay.py +41 -0
  38. KekikStream/Extractors/VidHide.py +81 -0
  39. KekikStream/Extractors/VidMoly.py +55 -34
  40. KekikStream/Extractors/VidMoxy.py +2 -3
  41. KekikStream/Extractors/VidPapi.py +89 -0
  42. KekikStream/Extractors/VideoSeyred.py +3 -4
  43. KekikStream/Extractors/YTDLP.py +211 -0
  44. KekikStream/Extractors/YildizKisaFilm.py +41 -0
  45. KekikStream/Plugins/BelgeselX.py +196 -0
  46. KekikStream/Plugins/DiziBox.py +25 -34
  47. KekikStream/Plugins/DiziPal.py +24 -35
  48. KekikStream/Plugins/DiziYou.py +54 -37
  49. KekikStream/Plugins/Dizilla.py +66 -46
  50. KekikStream/Plugins/FilmBip.py +142 -0
  51. KekikStream/Plugins/FilmMakinesi.py +36 -28
  52. KekikStream/Plugins/FilmModu.py +20 -24
  53. KekikStream/Plugins/FullHDFilm.py +220 -0
  54. KekikStream/Plugins/FullHDFilmizlesene.py +9 -15
  55. KekikStream/Plugins/HDFilmCehennemi.py +141 -69
  56. KekikStream/Plugins/JetFilmizle.py +85 -52
  57. KekikStream/Plugins/KultFilmler.py +217 -0
  58. KekikStream/Plugins/RecTV.py +22 -34
  59. KekikStream/Plugins/RoketDizi.py +222 -0
  60. KekikStream/Plugins/SelcukFlix.py +328 -0
  61. KekikStream/Plugins/SetFilmIzle.py +252 -0
  62. KekikStream/Plugins/SezonlukDizi.py +54 -21
  63. KekikStream/Plugins/SineWix.py +17 -29
  64. KekikStream/Plugins/Sinefy.py +241 -0
  65. KekikStream/Plugins/SinemaCX.py +154 -0
  66. KekikStream/Plugins/Sinezy.py +143 -0
  67. KekikStream/Plugins/SuperFilmGeldi.py +130 -0
  68. KekikStream/Plugins/UgurFilm.py +13 -19
  69. KekikStream/__init__.py +47 -56
  70. KekikStream/requirements.txt +3 -4
  71. kekikstream-2.2.0.dist-info/METADATA +312 -0
  72. kekikstream-2.2.0.dist-info/RECORD +81 -0
  73. KekikStream/Extractors/FourCX.py +0 -7
  74. KekikStream/Extractors/FourPichive.py +0 -7
  75. KekikStream/Extractors/FourPlayRu.py +0 -7
  76. KekikStream/Extractors/HDStreamAble.py +0 -7
  77. KekikStream/Extractors/Hotlinger.py +0 -7
  78. KekikStream/Extractors/OkRuHTTP.py +0 -7
  79. KekikStream/Extractors/OkRuSSL.py +0 -7
  80. KekikStream/Extractors/Pichive.py +0 -7
  81. KekikStream/Extractors/PlayRu.py +0 -7
  82. KekikStream/Extractors/VidMolyMe.py +0 -7
  83. kekikstream-1.7.1.dist-info/METADATA +0 -109
  84. kekikstream-1.7.1.dist-info/RECORD +0 -63
  85. {kekikstream-1.7.1.dist-info → kekikstream-2.2.0.dist-info}/WHEEL +0 -0
  86. {kekikstream-1.7.1.dist-info → kekikstream-2.2.0.dist-info}/entry_points.txt +0 -0
  87. {kekikstream-1.7.1.dist-info → kekikstream-2.2.0.dist-info}/licenses/LICENSE +0 -0
  88. {kekikstream-1.7.1.dist-info → kekikstream-2.2.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,252 @@
1
+ # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
+
3
+ from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, SeriesInfo, Episode, ExtractResult
4
+ from parsel import Selector
5
+ import re, json
6
+
7
+ class SetFilmIzle(PluginBase):
8
+ name = "SetFilmIzle"
9
+ language = "tr"
10
+ main_url = "https://www.setfilmizle.uk"
11
+ favicon = f"https://www.google.com/s2/favicons?domain={main_url}&sz=64"
12
+ description = "Setfilmizle sitemizde, donma yaşamadan Türkçe dublaj ve altyazılı filmleri ile dizileri muhteşem 1080p full HD kalitesinde izleyebilirsiniz."
13
+
14
+ main_page = {
15
+ f"{main_url}/tur/aile/" : "Aile",
16
+ f"{main_url}/tur/aksiyon/" : "Aksiyon",
17
+ f"{main_url}/tur/animasyon/" : "Animasyon",
18
+ f"{main_url}/tur/belgesel/" : "Belgesel",
19
+ f"{main_url}/tur/bilim-kurgu/" : "Bilim-Kurgu",
20
+ f"{main_url}/tur/biyografi/" : "Biyografi",
21
+ f"{main_url}/tur/dini/" : "Dini",
22
+ f"{main_url}/tur/dram/" : "Dram",
23
+ f"{main_url}/tur/fantastik/" : "Fantastik",
24
+ f"{main_url}/tur/genclik/" : "Gençlik",
25
+ f"{main_url}/tur/gerilim/" : "Gerilim",
26
+ f"{main_url}/tur/gizem/" : "Gizem",
27
+ f"{main_url}/tur/komedi/" : "Komedi",
28
+ f"{main_url}/tur/korku/" : "Korku",
29
+ f"{main_url}/tur/macera/" : "Macera",
30
+ f"{main_url}/tur/romantik/" : "Romantik",
31
+ f"{main_url}/tur/savas/" : "Savaş",
32
+ f"{main_url}/tur/suc/" : "Suç",
33
+ f"{main_url}/tur/tarih/" : "Tarih",
34
+ f"{main_url}/tur/western/" : "Western"
35
+ }
36
+
37
+ def _get_nonce(self, nonce_type: str = "video_nonce", referer: str = None) -> str:
38
+ """Site cache'lenmiş nonce'ları expire olabiliyor, fresh nonce al"""
39
+ try:
40
+ resp = self.cloudscraper.post(
41
+ f"{self.main_url}/wp-admin/admin-ajax.php",
42
+ headers = {
43
+ "Referer" : referer or self.main_url,
44
+ "Origin" : self.main_url,
45
+ "Content-Type" : "application/x-www-form-urlencoded",
46
+ },
47
+ data = "action=st_cache_refresh_nonces"
48
+ )
49
+ nonces = resp.json().get("data", {}).get("nonces", {})
50
+ return nonces.get(nonce_type, "")
51
+ except:
52
+ return ""
53
+
54
+ async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
55
+ istek = self.cloudscraper.get(url)
56
+ secici = Selector(istek.text)
57
+
58
+ results = []
59
+ for item in secici.css("div.items article"):
60
+ title = item.css("h2::text").get()
61
+ href = item.css("a::attr(href)").get()
62
+ poster = item.css("img::attr(data-src)").get()
63
+
64
+ if title and href:
65
+ results.append(MainPageResult(
66
+ category = category,
67
+ title = title.strip(),
68
+ url = self.fix_url(href),
69
+ poster = self.fix_url(poster) if poster else None
70
+ ))
71
+
72
+ return results
73
+
74
+ async def search(self, query: str) -> list[SearchResult]:
75
+ nonce = self._get_nonce("search")
76
+
77
+ search_resp = self.cloudscraper.post(
78
+ f"{self.main_url}/wp-admin/admin-ajax.php",
79
+ headers = {
80
+ "X-Requested-With" : "XMLHttpRequest",
81
+ "Content-Type" : "application/x-www-form-urlencoded",
82
+ "Referer" : f"{self.main_url}/"
83
+ },
84
+ data = {
85
+ "action" : "ajax_search",
86
+ "search" : query,
87
+ "original_search" : query,
88
+ "nonce" : nonce
89
+ }
90
+ )
91
+
92
+ try:
93
+ data = search_resp.json()
94
+ html = data.get("html", "")
95
+ except:
96
+ return []
97
+
98
+ secici = Selector(text=html)
99
+ results = []
100
+
101
+ for item in secici.css("div.items article"):
102
+ title = item.css("h2::text").get()
103
+ href = item.css("a::attr(href)").get()
104
+ poster = item.css("img::attr(data-src)").get()
105
+
106
+ if title and href:
107
+ results.append(SearchResult(
108
+ title = title.strip(),
109
+ url = self.fix_url(href),
110
+ poster = self.fix_url(poster) if poster else None
111
+ ))
112
+
113
+ return results
114
+
115
+ async def load_item(self, url: str) -> MovieInfo | SeriesInfo:
116
+ istek = await self.httpx.get(url)
117
+ secici = Selector(istek.text)
118
+
119
+ raw_title = secici.css("h1::text").get() or ""
120
+ title = re.sub(r"\s*izle.*$", "", raw_title, flags=re.IGNORECASE).strip()
121
+ poster = secici.css("div.poster img::attr(src)").get()
122
+ description = secici.css("div.wp-content p::text").get()
123
+ year = secici.css("div.extra span.C a::text").get()
124
+ if year:
125
+ year_match = re.search(r"\d{4}", year)
126
+ year = year_match.group() if year_match else None
127
+ tags = [a.css("::text").get().strip() for a in secici.css("div.sgeneros a") if a.css("::text").get()]
128
+ duration = secici.css("span.runtime::text").get()
129
+ if duration:
130
+ dur_match = re.search(r"\d+", duration)
131
+ duration = int(dur_match.group()) if dur_match else None
132
+
133
+ actors = [span.css("::text").get().strip() for span in secici.css("span.valor a > span") if span.css("::text").get()]
134
+
135
+ trailer_match = re.search(r'embed/([^?]*)\?rel', istek.text)
136
+ trailer = f"https://www.youtube.com/embed/{trailer_match.group(1)}" if trailer_match else None
137
+
138
+ # Dizi mi film mi kontrol et
139
+ is_series = "/dizi/" in url
140
+
141
+ if is_series:
142
+ year_elem = secici.css("a[href*='/yil/']::text").get()
143
+ if year_elem:
144
+ year_match = re.search(r"\d{4}", year_elem)
145
+ year = year_match.group() if year_match else year
146
+
147
+ dur_elem = secici.css("div#info span:contains('Dakika')::text").get()
148
+ if dur_elem:
149
+ dur_match = re.search(r"\d+", dur_elem)
150
+ duration = int(dur_match.group()) if dur_match else duration
151
+
152
+ episodes = []
153
+ for ep_item in secici.css("div#episodes ul.episodios li"):
154
+ ep_href = ep_item.css("h4.episodiotitle a::attr(href)").get()
155
+ ep_name = ep_item.css("h4.episodiotitle a::text").get()
156
+
157
+ if not ep_href or not ep_name:
158
+ continue
159
+
160
+ ep_detail = ep_name.strip()
161
+ season_match = re.search(r"(\d+)\.\s*Sezon", ep_detail)
162
+ episode_match = re.search(r"Sezon\s+(\d+)\.\s*Bölüm", ep_detail)
163
+
164
+ ep_season = int(season_match.group(1)) if season_match else 1
165
+ ep_episode = int(episode_match.group(1)) if episode_match else None
166
+
167
+ episodes.append(Episode(
168
+ season = ep_season,
169
+ episode = ep_episode,
170
+ title = ep_name.strip(),
171
+ url = self.fix_url(ep_href)
172
+ ))
173
+
174
+ return SeriesInfo(
175
+ url = url,
176
+ poster = self.fix_url(poster) if poster else None,
177
+ title = title,
178
+ description = description.strip() if description else None,
179
+ tags = tags,
180
+ year = year,
181
+ duration = duration,
182
+ actors = actors,
183
+ episodes = episodes
184
+ )
185
+
186
+ return MovieInfo(
187
+ url = url,
188
+ poster = self.fix_url(poster) if poster else None,
189
+ title = title,
190
+ description = description.strip() if description else None,
191
+ tags = tags,
192
+ year = year,
193
+ duration = duration,
194
+ actors = actors
195
+ )
196
+
197
+ async def load_links(self, url: str) -> list[ExtractResult]:
198
+ istek = await self.httpx.get(url)
199
+ secici = Selector(istek.text)
200
+
201
+ nonce = self._get_nonce("video_nonce", referer=url)
202
+
203
+ # partKey to dil label mapping
204
+ part_key_labels = {
205
+ "turkcedublaj" : "Türkçe Dublaj",
206
+ "turkcealtyazi" : "Türkçe Altyazı",
207
+ "orijinal" : "Orijinal"
208
+ }
209
+
210
+ links = []
211
+ for player in secici.css("nav.player a"):
212
+ source_id = player.css("::attr(data-post-id)").get()
213
+ player_name = player.css("::attr(data-player-name)").get()
214
+ part_key = player.css("::attr(data-part-key)").get()
215
+
216
+ if not source_id or "event" in source_id or source_id == "":
217
+ continue
218
+
219
+ try:
220
+ resp = self.cloudscraper.post(
221
+ f"{self.main_url}/wp-admin/admin-ajax.php",
222
+ headers = {"Referer": url},
223
+ data = {
224
+ "action" : "get_video_url",
225
+ "nonce" : nonce,
226
+ "post_id" : source_id,
227
+ "player_name" : player_name or "",
228
+ "part_key" : part_key or ""
229
+ }
230
+ )
231
+ data = resp.json()
232
+ except:
233
+ continue
234
+
235
+ iframe_url = data.get("data", {}).get("url")
236
+ if not iframe_url:
237
+ continue
238
+
239
+ # SetPlay URL'si için part_key ekleme
240
+ if "setplay" not in iframe_url and part_key:
241
+ iframe_url = f"{iframe_url}?partKey={part_key}"
242
+
243
+ # Dil etiketi oluştur
244
+ label = part_key_labels.get(part_key, "")
245
+ if not label and part_key:
246
+ label = part_key.replace("_", " ").title()
247
+
248
+ data = await self.extract(iframe_url, prefix=label if label else None)
249
+ if data:
250
+ links.append(data)
251
+
252
+ return links
@@ -1,7 +1,8 @@
1
1
  # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
2
 
3
- from KekikStream.Core import kekik_cache, PluginBase, MainPageResult, SearchResult, SeriesInfo, Episode
3
+ from KekikStream.Core import PluginBase, MainPageResult, SearchResult, SeriesInfo, Episode, ExtractResult
4
4
  from parsel import Selector
5
+ import re
5
6
 
6
7
  class SezonlukDizi(PluginBase):
7
8
  name = "SezonlukDizi"
@@ -19,11 +20,27 @@ class SezonlukDizi(PluginBase):
19
20
  f"{main_url}/diziler.asp?siralama_tipi=id&kat=4&s=" : "Animasyonlar",
20
21
  f"{main_url}/diziler.asp?siralama_tipi=id&kat=5&s=" : "Animeler",
21
22
  f"{main_url}/diziler.asp?siralama_tipi=id&kat=6&s=" : "Belgeseller",
23
+ f"{main_url}/diziler.asp?siralama_tipi=id&tur=aile&s=" : "Aile",
24
+ f"{main_url}/diziler.asp?siralama_tipi=id&tur=aksiyon&s=" : "Aksiyon",
25
+ f"{main_url}/diziler.asp?siralama_tipi=id&tur=bilimkurgu&s=" : "Bilim Kurgu",
26
+ f"{main_url}/diziler.asp?siralama_tipi=id&tur=biyografik&s=" : "Biyografi",
27
+ f"{main_url}/diziler.asp?siralama_tipi=id&tur=dram&s=" : "Dram",
28
+ f"{main_url}/diziler.asp?siralama_tipi=id&tur=fantastik&s=" : "Fantastik",
29
+ f"{main_url}/diziler.asp?siralama_tipi=id&tur=gerilim&s=" : "Gerilim",
30
+ f"{main_url}/diziler.asp?siralama_tipi=id&tur=gizem&s=" : "Gizem",
31
+ f"{main_url}/diziler.asp?siralama_tipi=id&tur=korku&s=" : "Korku",
32
+ f"{main_url}/diziler.asp?siralama_tipi=id&tur=komedi&s=" : "Komedi",
33
+ f"{main_url}/diziler.asp?siralama_tipi=id&tur=macera&s=" : "Macera",
34
+ f"{main_url}/diziler.asp?siralama_tipi=id&tur=muzikal&s=" : "Müzikal",
35
+ f"{main_url}/diziler.asp?siralama_tipi=id&tur=suc&s=" : "Suç",
36
+ f"{main_url}/diziler.asp?siralama_tipi=id&tur=romantik&s=" : "Romantik",
37
+ f"{main_url}/diziler.asp?siralama_tipi=id&tur=savas&s=" : "Savaş",
38
+ f"{main_url}/diziler.asp?siralama_tipi=id&tur=tarihi&s=" : "Tarihi",
39
+ f"{main_url}/diziler.asp?siralama_tipi=id&tur=western&s=" : "Western"
22
40
  }
23
41
 
24
- #@kekik_cache(ttl=60*60)
25
42
  async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
26
- istek = await self.cffi.get(f"{url}{page}")
43
+ istek = await self.httpx.get(f"{url}{page}")
27
44
  secici = Selector(istek.text)
28
45
 
29
46
  return [
@@ -36,9 +53,8 @@ class SezonlukDizi(PluginBase):
36
53
  for veri in secici.css("div.afis a") if veri.css("div.description::text").get()
37
54
  ]
38
55
 
39
- #@kekik_cache(ttl=60*60)
40
56
  async def search(self, query: str) -> list[SearchResult]:
41
- istek = await self.cffi.get(f"{self.main_url}/diziler.asp?adi={query}")
57
+ istek = await self.httpx.get(f"{self.main_url}/diziler.asp?adi={query}")
42
58
  secici = Selector(istek.text)
43
59
 
44
60
  return [
@@ -50,9 +66,8 @@ class SezonlukDizi(PluginBase):
50
66
  for afis in secici.css("div.afis a.column")
51
67
  ]
52
68
 
53
- #@kekik_cache(ttl=60*60)
54
69
  async def load_item(self, url: str) -> SeriesInfo:
55
- istek = await self.cffi.get(url)
70
+ istek = await self.httpx.get(url)
56
71
  secici = Selector(istek.text)
57
72
 
58
73
  title = secici.css("div.header::text").get().strip()
@@ -63,14 +78,14 @@ class SezonlukDizi(PluginBase):
63
78
  rating = secici.css("div.dizipuani a div::text").re_first(r"[\d.,]+")
64
79
  actors = []
65
80
 
66
- actors_istek = await self.cffi.get(f"{self.main_url}/oyuncular/{url.split('/')[-1]}")
81
+ actors_istek = await self.httpx.get(f"{self.main_url}/oyuncular/{url.split('/')[-1]}")
67
82
  actors_secici = Selector(actors_istek.text)
68
83
  actors = [
69
84
  actor.css("div.header::text").get().strip()
70
85
  for actor in actors_secici.css("div.doubling div.ui")
71
86
  ]
72
87
 
73
- episodes_istek = await self.cffi.get(f"{self.main_url}/bolumler/{url.split('/')[-1]}")
88
+ episodes_istek = await self.httpx.get(f"{self.main_url}/bolumler/{url.split('/')[-1]}")
74
89
  episodes_secici = Selector(episodes_istek.text)
75
90
  episodes = []
76
91
 
@@ -102,19 +117,35 @@ class SezonlukDizi(PluginBase):
102
117
  actors = actors
103
118
  )
104
119
 
105
- #@kekik_cache(ttl=15*60)
106
- async def load_links(self, url: str) -> list[dict]:
107
- istek = await self.cffi.get(url)
120
+ async def get_asp_data(self) -> tuple[str, str]:
121
+ """Fetch dynamic ASP version numbers from site.min.js"""
122
+ try:
123
+ js_content = await self.httpx.get(f"{self.main_url}/js/site.min.js")
124
+ alternatif_match = re.search(r'dataAlternatif(.*?)\.asp', js_content.text)
125
+ embed_match = re.search(r'dataEmbed(.*?)\.asp', js_content.text)
126
+
127
+ alternatif_ver = alternatif_match.group(1) if alternatif_match else "22"
128
+ embed_ver = embed_match.group(1) if embed_match else "22"
129
+
130
+ return (alternatif_ver, embed_ver)
131
+ except Exception:
132
+ return ("22", "22") # Fallback to default versions
133
+
134
+ async def load_links(self, url: str) -> list[ExtractResult]:
135
+ istek = await self.httpx.get(url)
108
136
  secici = Selector(istek.text)
109
137
 
110
138
  bid = secici.css("div#dilsec::attr(data-id)").get()
111
139
  if not bid:
112
140
  return []
113
141
 
142
+ # Get dynamic ASP versions
143
+ alternatif_ver, embed_ver = await self.get_asp_data()
144
+
114
145
  results = []
115
146
  for dil, label in [("1", "Altyazı"), ("0", "Dublaj")]:
116
- dil_istek = await self.cffi.post(
117
- url = f"{self.main_url}/ajax/dataAlternatif22.asp",
147
+ dil_istek = await self.httpx.post(
148
+ url = f"{self.main_url}/ajax/dataAlternatif{alternatif_ver}.asp",
118
149
  headers = {"X-Requested-With": "XMLHttpRequest"},
119
150
  data = {"bid": bid, "dil": dil},
120
151
  )
@@ -126,18 +157,20 @@ class SezonlukDizi(PluginBase):
126
157
 
127
158
  if dil_json.get("status") == "success":
128
159
  for idx, veri in enumerate(dil_json.get("data", [])):
129
- veri_response = await self.cffi.post(
130
- url = f"{self.main_url}/ajax/dataEmbed22.asp",
160
+ veri_response = await self.httpx.post(
161
+ url = f"{self.main_url}/ajax/dataEmbed{embed_ver}.asp",
131
162
  headers = {"X-Requested-With": "XMLHttpRequest"},
132
163
  data = {"id": veri.get("id")},
133
164
  )
134
165
  secici = Selector(veri_response.text)
135
166
 
136
167
  if iframe := secici.css("iframe::attr(src)").get():
137
- extractor = self.ex_manager.find_extractor(self.fix_url(iframe))
138
- results.append({
139
- "url" : self.fix_url(iframe),
140
- "name" : f"{extractor.name if extractor else f'{label} - Player {idx + 1}'}"
141
- })
168
+ if "link.asp" in iframe:
169
+ continue
170
+
171
+ iframe_url = self.fix_url(iframe)
172
+ data = await self.extract(iframe_url, prefix=label)
173
+ if data:
174
+ results.append(data)
142
175
 
143
176
  return results
@@ -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 kekik_cache, PluginBase, MainPageResult, SearchResult, MovieInfo, Episode, SeriesInfo, ExtractResult, Subtitle
3
+ from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, Episode, SeriesInfo, ExtractResult
4
4
  import json
5
5
 
6
6
  class SineWix(PluginBase):
@@ -35,9 +35,8 @@ class SineWix(PluginBase):
35
35
  f"{main_url}/sinewix/movies/36" : "Tarih",
36
36
  }
37
37
 
38
- #@kekik_cache(ttl=60*60)
39
38
  async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
40
- istek = await self.cffi.get(f"{url}/{page}")
39
+ istek = await self.httpx.get(f"{url}/{page}")
41
40
  veriler = istek.json()
42
41
 
43
42
  return [
@@ -50,9 +49,8 @@ class SineWix(PluginBase):
50
49
  for veri in veriler.get("data")
51
50
  ]
52
51
 
53
- #@kekik_cache(ttl=60*60)
54
52
  async def search(self, query: str) -> list[SearchResult]:
55
- istek = await self.cffi.get(f"{self.main_url}/sinewix/search/{query}")
53
+ istek = await self.httpx.get(f"{self.main_url}/sinewix/search/{query}")
56
54
 
57
55
  return [
58
56
  SearchResult(
@@ -63,12 +61,11 @@ class SineWix(PluginBase):
63
61
  for veri in istek.json().get("search")
64
62
  ]
65
63
 
66
- #@kekik_cache(ttl=60*60)
67
64
  async def load_item(self, url: str) -> MovieInfo | SeriesInfo:
68
65
  item_type = url.split("?type=")[-1].split("&id=")[0]
69
66
  item_id = url.split("&id=")[-1]
70
67
 
71
- istek = await self.cffi.get(f"{self.main_url}/sinewix/{item_type}/{item_id}")
68
+ istek = await self.httpx.get(f"{self.main_url}/sinewix/{item_type}/{item_id}")
72
69
  veri = istek.json()
73
70
 
74
71
  match item_type:
@@ -126,24 +123,23 @@ class SineWix(PluginBase):
126
123
  episodes = episodes,
127
124
  )
128
125
 
129
- #@kekik_cache(ttl=15*60)
130
- async def load_links(self, url: str) -> list[dict]:
126
+ async def load_links(self, url: str) -> list[ExtractResult]:
131
127
  try:
132
128
  veri = json.loads(url)
133
129
  if veri.get("is_episode"):
134
- return [{
135
- "url" : veri.get("url"),
136
- "name" : veri.get("title"),
137
- "referer" : self.main_url
138
- }]
130
+ return [ExtractResult(
131
+ url = veri.get("url"),
132
+ name = veri.get("title"),
133
+ referer = self.main_url
134
+ )]
139
135
  except Exception:
140
136
  pass
141
137
 
142
138
  # Eğer JSON değilse ve direkt URL ise (eski yapı veya harici link)
143
139
  if not url.startswith(self.main_url) and not url.startswith("{"):
144
- return [{"url": url, "name": "Video"}]
140
+ return [ExtractResult(url=url, name="Video")]
145
141
 
146
- istek = await self.cffi.get(url)
142
+ istek = await self.httpx.get(url)
147
143
  veri = istek.json()
148
144
 
149
145
  org_title = veri.get("title")
@@ -153,18 +149,10 @@ class SineWix(PluginBase):
153
149
  results = []
154
150
  for video in veri.get("videos"):
155
151
  video_link = video.get("link").split("_blank\">")[-1]
156
- results.append({
157
- "url" : video_link,
158
- "name" : f"{self.name}",
159
- "referer" : self.main_url
160
- })
152
+ results.append(ExtractResult(
153
+ url = video_link,
154
+ name = f"{self.name}",
155
+ referer = self.main_url
156
+ ))
161
157
 
162
158
  return results
163
-
164
- async def play(self, name: str, url: str, referer: str, subtitles: list[Subtitle]):
165
- extract_result = ExtractResult(name=name, url=url, referer=referer, subtitles=subtitles)
166
- self.media_handler.title = name
167
- if self.name not in self.media_handler.title:
168
- self.media_handler.title = f"{self.name} | {self.media_handler.title}"
169
-
170
- self.media_handler.play_media(extract_result)