KekikStream 2.2.9__py3-none-any.whl → 2.5.3__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 (88) hide show
  1. KekikStream/Core/Extractor/ExtractorBase.py +3 -2
  2. KekikStream/Core/Extractor/ExtractorLoader.py +8 -14
  3. KekikStream/Core/HTMLHelper.py +205 -0
  4. KekikStream/Core/Plugin/PluginBase.py +48 -12
  5. KekikStream/Core/Plugin/PluginLoader.py +13 -14
  6. KekikStream/Core/Plugin/PluginManager.py +2 -2
  7. KekikStream/Core/Plugin/PluginModels.py +0 -3
  8. KekikStream/Core/__init__.py +2 -0
  9. KekikStream/Extractors/Abstream.py +27 -0
  10. KekikStream/Extractors/CloseLoad.py +31 -56
  11. KekikStream/Extractors/ContentX.py +28 -71
  12. KekikStream/Extractors/DonilasPlay.py +34 -78
  13. KekikStream/Extractors/DzenRu.py +11 -25
  14. KekikStream/Extractors/ExPlay.py +20 -38
  15. KekikStream/Extractors/Filemoon.py +23 -53
  16. KekikStream/Extractors/HDMomPlayer.py +30 -0
  17. KekikStream/Extractors/HDPlayerSystem.py +13 -31
  18. KekikStream/Extractors/HotStream.py +27 -0
  19. KekikStream/Extractors/JFVid.py +3 -24
  20. KekikStream/Extractors/JetTv.py +21 -34
  21. KekikStream/Extractors/JetV.py +55 -0
  22. KekikStream/Extractors/MailRu.py +11 -29
  23. KekikStream/Extractors/MixPlayHD.py +17 -31
  24. KekikStream/Extractors/MixTiger.py +17 -40
  25. KekikStream/Extractors/MolyStream.py +25 -22
  26. KekikStream/Extractors/Odnoklassniki.py +41 -105
  27. KekikStream/Extractors/PeaceMakerst.py +20 -47
  28. KekikStream/Extractors/PixelDrain.py +9 -16
  29. KekikStream/Extractors/PlayerFilmIzle.py +23 -46
  30. KekikStream/Extractors/RapidVid.py +23 -36
  31. KekikStream/Extractors/SetPlay.py +19 -44
  32. KekikStream/Extractors/SetPrime.py +3 -6
  33. KekikStream/Extractors/SibNet.py +8 -19
  34. KekikStream/Extractors/Sobreatsesuyp.py +25 -47
  35. KekikStream/Extractors/TRsTX.py +25 -55
  36. KekikStream/Extractors/TurboImgz.py +8 -16
  37. KekikStream/Extractors/TurkeyPlayer.py +5 -5
  38. KekikStream/Extractors/VCTPlay.py +10 -28
  39. KekikStream/Extractors/Veev.py +145 -0
  40. KekikStream/Extractors/VidBiz.py +62 -0
  41. KekikStream/Extractors/VidHide.py +59 -34
  42. KekikStream/Extractors/VidMoly.py +67 -89
  43. KekikStream/Extractors/VidMoxy.py +17 -29
  44. KekikStream/Extractors/VidPapi.py +26 -58
  45. KekikStream/Extractors/VideoSeyred.py +21 -42
  46. KekikStream/Extractors/Videostr.py +58 -0
  47. KekikStream/Extractors/Vidoza.py +18 -0
  48. KekikStream/Extractors/Vtbe.py +38 -0
  49. KekikStream/Extractors/YTDLP.py +2 -2
  50. KekikStream/Extractors/YildizKisaFilm.py +13 -31
  51. KekikStream/Extractors/Zeus.py +61 -0
  52. KekikStream/Plugins/BelgeselX.py +108 -99
  53. KekikStream/Plugins/DiziBox.py +61 -106
  54. KekikStream/Plugins/DiziMom.py +179 -0
  55. KekikStream/Plugins/DiziPal.py +104 -192
  56. KekikStream/Plugins/DiziYou.py +66 -149
  57. KekikStream/Plugins/Dizilla.py +93 -126
  58. KekikStream/Plugins/FilmBip.py +102 -72
  59. KekikStream/Plugins/FilmEkseni.py +199 -0
  60. KekikStream/Plugins/FilmMakinesi.py +101 -64
  61. KekikStream/Plugins/FilmModu.py +35 -59
  62. KekikStream/Plugins/Filmatek.py +184 -0
  63. KekikStream/Plugins/FilmciBaba.py +155 -0
  64. KekikStream/Plugins/FullHDFilmizlesene.py +32 -78
  65. KekikStream/Plugins/HDFilm.py +243 -0
  66. KekikStream/Plugins/HDFilmCehennemi.py +261 -222
  67. KekikStream/Plugins/JetFilmizle.py +117 -98
  68. KekikStream/Plugins/KultFilmler.py +153 -143
  69. KekikStream/Plugins/RecTV.py +53 -49
  70. KekikStream/Plugins/RoketDizi.py +92 -123
  71. KekikStream/Plugins/SelcukFlix.py +86 -95
  72. KekikStream/Plugins/SetFilmIzle.py +105 -143
  73. KekikStream/Plugins/SezonlukDizi.py +106 -128
  74. KekikStream/Plugins/Sinefy.py +194 -166
  75. KekikStream/Plugins/SinemaCX.py +159 -113
  76. KekikStream/Plugins/Sinezy.py +44 -73
  77. KekikStream/Plugins/SuperFilmGeldi.py +28 -52
  78. KekikStream/Plugins/UgurFilm.py +94 -72
  79. KekikStream/Plugins/Watch32.py +160 -0
  80. KekikStream/Plugins/YabanciDizi.py +250 -0
  81. {kekikstream-2.2.9.dist-info → kekikstream-2.5.3.dist-info}/METADATA +1 -1
  82. kekikstream-2.5.3.dist-info/RECORD +99 -0
  83. {kekikstream-2.2.9.dist-info → kekikstream-2.5.3.dist-info}/WHEEL +1 -1
  84. KekikStream/Plugins/FullHDFilm.py +0 -254
  85. kekikstream-2.2.9.dist-info/RECORD +0 -82
  86. {kekikstream-2.2.9.dist-info → kekikstream-2.5.3.dist-info}/entry_points.txt +0 -0
  87. {kekikstream-2.2.9.dist-info → kekikstream-2.5.3.dist-info}/licenses/LICENSE +0 -0
  88. {kekikstream-2.2.9.dist-info → kekikstream-2.5.3.dist-info}/top_level.txt +0 -0
@@ -1,8 +1,7 @@
1
1
  # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
2
 
3
- from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, Subtitle, ExtractResult
4
- from selectolax.parser import HTMLParser
5
- import re
3
+ from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, Subtitle, ExtractResult, HTMLHelper
4
+ import asyncio, contextlib
6
5
 
7
6
  class SinemaCX(PluginBase):
8
7
  name = "SinemaCX"
@@ -39,161 +38,208 @@ class SinemaCX(PluginBase):
39
38
 
40
39
  async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
41
40
  istek = await self.httpx.get(url.replace("SAYFA", str(page)))
42
- secici = HTMLParser(istek.text)
41
+ secici = HTMLHelper(istek.text)
43
42
 
44
43
  results = []
45
- for veri in secici.css("div.son div.frag-k, div.icerik div.frag-k"):
46
- span_el = veri.css_first("div.yanac span")
47
- if not span_el:
48
- continue
49
-
50
- title = span_el.text(strip=True)
44
+ for veri in secici.select("div.son div.frag-k, div.icerik div.frag-k"):
45
+ title = secici.select_text("div.yanac span", veri)
51
46
  if not title:
52
47
  continue
53
48
 
54
- link_el = veri.css_first("div.yanac a")
55
- img_el = veri.css_first("a.resim img")
56
-
57
- href = link_el.attrs.get("href") if link_el else None
58
- poster = (img_el.attrs.get("data-src") or img_el.attrs.get("src")) if img_el else None
49
+ href = secici.select_attr("div.yanac a", "href", veri)
50
+ poster = secici.select_attr("a.resim img", "data-src", veri) or secici.select_attr("a.resim img", "src", veri)
59
51
 
60
52
  results.append(MainPageResult(
61
53
  category = category,
62
54
  title = title,
63
- url = self.fix_url(href) if href else "",
64
- poster = self.fix_url(poster) if poster else None,
55
+ url = self.fix_url(href),
56
+ poster = self.fix_url(poster),
65
57
  ))
66
58
 
67
59
  return results
68
60
 
69
61
  async def search(self, query: str) -> list[SearchResult]:
70
62
  istek = await self.httpx.get(f"{self.main_url}/?s={query}")
71
- secici = HTMLParser(istek.text)
63
+ secici = HTMLHelper(istek.text)
72
64
 
73
65
  results = []
74
- for veri in secici.css("div.icerik div.frag-k"):
75
- span_el = veri.css_first("div.yanac span")
76
- if not span_el:
77
- continue
78
-
79
- title = span_el.text(strip=True)
66
+ for veri in secici.select("div.icerik div.frag-k"):
67
+ title = secici.select_text("div.yanac span", veri)
80
68
  if not title:
81
69
  continue
82
70
 
83
- link_el = veri.css_first("div.yanac a")
84
- img_el = veri.css_first("a.resim img")
85
-
86
- href = link_el.attrs.get("href") if link_el else None
87
- poster = (img_el.attrs.get("data-src") or img_el.attrs.get("src")) if img_el else None
71
+ href = secici.select_attr("div.yanac a", "href", veri)
72
+ poster = secici.select_attr("a.resim img", "data-src", veri) or secici.select_attr("a.resim img", "src", veri)
88
73
 
89
74
  results.append(SearchResult(
90
75
  title = title,
91
- url = self.fix_url(href) if href else "",
92
- poster = self.fix_url(poster) if poster else None,
76
+ url = self.fix_url(href),
77
+ poster = self.fix_url(poster),
93
78
  ))
94
79
 
95
80
  return results
96
81
 
97
82
  async def load_item(self, url: str) -> MovieInfo:
98
83
  istek = await self.httpx.get(url)
99
- secici = HTMLParser(istek.text)
100
-
101
- duration_match = re.search(r"Süre:.*?(\d+)\s*Dakika", istek.text)
102
-
103
- desc_el = secici.css_first("div.ackl div.scroll-liste")
104
- description = desc_el.text(strip=True) if desc_el else None
105
-
106
- link_el = secici.css_first("link[rel='image_src']")
107
- poster = link_el.attrs.get("href") if link_el else None
108
-
109
- title_el = secici.css_first("div.f-bilgi h1")
110
- title = title_el.text(strip=True) if title_el else None
111
-
112
- tags = [a.text(strip=True) for a in secici.css("div.f-bilgi div.tur a") if a.text(strip=True)]
113
-
114
- year_el = secici.css_first("div.f-bilgi ul.detay a[href*='yapim']")
115
- year = year_el.text(strip=True) if year_el else None
116
-
117
- actors = []
118
- for li in secici.css("li.oync li.oyuncu-k"):
119
- isim_el = li.css_first("span.isim")
120
- if isim_el and isim_el.text(strip=True):
121
- actors.append(isim_el.text(strip=True))
84
+ secici = HTMLHelper(istek.text)
85
+
86
+ title = secici.select_text("div.f-bilgi h1")
87
+ poster = secici.select_poster("div.resim img")
88
+ description = secici.select_text("div.ackl div.scroll-liste")
89
+ rating = secici.select_text("b.puandegistir")
90
+ tags = secici.select_texts("div.f-bilgi div.tur a")
91
+ year = secici.extract_year("ul.detay a[href*='yapim']")
92
+ actors = secici.select_texts("li.oync li.oyuncu-k span.isim")
93
+ _duration = secici.regex_first(r"<span>Süre:\s*</span>\s*(\d+)")
94
+ duration = int(_duration) if _duration else None
122
95
 
123
96
  return MovieInfo(
124
97
  url = url,
125
- poster = self.fix_url(poster) if poster else None,
98
+ poster = self.fix_url(poster),
126
99
  title = title,
127
100
  description = description,
101
+ rating = rating,
128
102
  tags = tags,
129
103
  year = year,
130
104
  actors = actors,
131
- duration = int(duration_match[1]) if duration_match else None,
105
+ duration = duration,
132
106
  )
133
107
 
134
- async def load_links(self, url: str) -> list[ExtractResult]:
135
- istek = await self.httpx.get(url)
136
- secici = HTMLParser(istek.text)
108
+ async def _get_iframe_from_source(self, text: str) -> str | None:
109
+ """Verilen sayfa kaynağındaki iframe'i (data-vsrc veya src) bulur."""
110
+ secici = HTMLHelper(text)
137
111
 
138
- iframe_list = [iframe.attrs.get("data-vsrc") for iframe in secici.css("iframe") if iframe.attrs.get("data-vsrc")]
112
+ # Öncelik data-vsrc
113
+ if src := secici.select_attr("iframe", "data-vsrc"):
114
+ return self.fix_url(src.split("?img=")[0])
139
115
 
140
- # Sadece fragman varsa /2/ sayfasından dene
141
- has_only_trailer = all(
142
- "youtube" in (i or "").lower() or "fragman" in (i or "").lower() or "trailer" in (i or "").lower()
143
- for i in iframe_list
144
- )
145
-
146
- if has_only_trailer:
147
- alt_url = url.rstrip("/") + "/2/"
148
- alt_istek = await self.httpx.get(alt_url)
149
- alt_sec = HTMLParser(alt_istek.text)
150
- iframe_list = [iframe.attrs.get("data-vsrc") for iframe in alt_sec.css("iframe") if iframe.attrs.get("data-vsrc")]
116
+ # Sonra src
117
+ if src := secici.select_attr("iframe", "src"):
118
+ return self.fix_url(src)
151
119
 
152
- if not iframe_list:
153
- return []
154
-
155
- iframe = self.fix_url(iframe_list[0].split("?img=")[0])
156
- if not iframe:
157
- return []
120
+ return None
158
121
 
122
+ async def _process_player(self, iframe_url: str, name: str) -> list[ExtractResult]:
123
+ """Iframe URL'ini işler ve sonuç döndürür."""
159
124
  results = []
160
125
 
161
- # Altyazı kontrolü
162
- self.httpx.headers.update({"Referer": f"{self.main_url}/"})
163
- iframe_istek = await self.httpx.get(iframe)
164
- iframe_text = iframe_istek.text
165
-
166
- subtitles = []
167
- sub_match = re.search(r'playerjsSubtitle\s*=\s*"(.+?)"', iframe_text)
168
- if sub_match:
169
- sub_section = sub_match[1]
170
- for sub in re.finditer(r'\[(.*?)](https?://[^\s",]+)', sub_section):
171
- subtitles.append(Subtitle(name=sub[1], url=self.fix_url(sub[2])))
172
-
173
- # player.filmizle.in kontrolü
174
- if "player.filmizle.in" in iframe.lower():
175
- base_match = re.search(r"https?://([^/]+)", iframe)
176
- if base_match:
177
- base_url = base_match[1]
178
- vid_id = iframe.split("/")[-1]
179
-
180
- self.httpx.headers.update({"X-Requested-With": "XMLHttpRequest"})
181
- vid_istek = await self.httpx.post(
182
- f"https://{base_url}/player/index.php?data={vid_id}&do=getVideo",
183
- )
184
- vid_data = vid_istek.json()
185
-
186
- if vid_data.get("securedLink"):
187
- results.append(ExtractResult(
188
- name = f"{self.name}",
189
- url = vid_data["securedLink"],
190
- referer = iframe,
191
- subtitles = subtitles
192
- ))
126
+ if "player.filmizle.in" in iframe_url.lower():
127
+ with contextlib.suppress(Exception):
128
+ # Referer önemli
129
+ self.httpx.headers.update({"Referer": f"{self.main_url}/"})
130
+
131
+ # Iframe içeriğini çek (Altyazı ve JS için)
132
+ iframe_resp = await self.httpx.get(iframe_url)
133
+ iframe_text = iframe_resp.text
134
+
135
+ subtitles = []
136
+ if sub_section := HTMLHelper(iframe_text).regex_first(r'playerjsSubtitle\s*=\s*"(.+?)"'):
137
+ for lang, link in HTMLHelper(sub_section).regex_all(r'\[(.*?)](https?://[^\s\",]+)'):
138
+ subtitles.append(Subtitle(name=lang, url=self.fix_url(link)))
139
+
140
+ base_url = HTMLHelper(iframe_url).regex_first(r"https?://([^/]+)")
141
+ if base_url:
142
+ vid_id = iframe_url.split("/")[-1]
143
+ self.httpx.headers.update({"X-Requested-With": "XMLHttpRequest"})
144
+
145
+ vid_istek = await self.httpx.post(f"https://{base_url}/player/index.php?data={vid_id}&do=getVideo")
146
+ vid_data = vid_istek.json()
147
+
148
+ if link := vid_data.get("securedLink"):
149
+ results.append(ExtractResult(
150
+ name = name,
151
+ url = link,
152
+ referer = iframe_url,
153
+ subtitles = subtitles
154
+ ))
193
155
  else:
194
- # Extractor'a yönlendir
195
- data = await self.extract(iframe)
196
- if data:
197
- results.append(data)
156
+ # Standart Extractor
157
+ with contextlib.suppress(Exception):
158
+ extracted = await self.extract(iframe_url)
159
+ if extracted:
160
+ items = extracted if isinstance(extracted, list) else [extracted]
161
+ for item in items:
162
+ item.name = name
163
+ results.append(item)
198
164
 
199
165
  return results
166
+
167
+ async def load_links(self, url: str) -> list[ExtractResult]:
168
+ istek = await self.httpx.get(url)
169
+ main_text = istek.text
170
+ secici = HTMLHelper(main_text)
171
+
172
+ sources = [] #List of tuple (url, name, needs_fetch)
173
+
174
+ if part_list := secici.select("ul#part li, ul#f_part li"):
175
+ for li in part_list:
176
+ # Aktif Tab (li.tab-aktif veya span.secili)
177
+ if "tab-aktif" in li.attrs.get("class", ""):
178
+ if a_tag := secici.select_first("a", li):
179
+ # Direkt text al (deep=False)
180
+ val = a_tag.text(strip=True, deep=False)
181
+ name = val if val else "SinemaCX"
182
+ sources.append((None, name, False))
183
+
184
+ elif span := secici.select_first("span.secili", li):
185
+ name = span.text(strip=True)
186
+ sources.append((None, name, False))
187
+
188
+ # Pasif Tab
189
+ elif a_tag := secici.select_first("a", li):
190
+ href = a_tag.attrs.get("href")
191
+ # title varsa title, yoksa text (deep=False ile almayı dene önce)
192
+ name = a_tag.attrs.get("title")
193
+ if not name:
194
+ name = a_tag.text(strip=True, deep=False)
195
+ if not name:
196
+ name = a_tag.text(strip=True) # Fallback
197
+
198
+ if href:
199
+ sources.append((self.fix_url(href), name, True))
200
+ else:
201
+ # Tab yoksa, tek parça filmdir.
202
+ sources.append((None, "SinemaCX", False))
203
+
204
+ # 2. Kaynakları İşle
205
+ extract_tasks = []
206
+
207
+ async def process_task(source):
208
+ src_url, src_name, needs_fetch = source
209
+
210
+ iframe_url = None
211
+ if not needs_fetch:
212
+ # Mevcut sayfa (main_text)
213
+ iframe_url = await self._get_iframe_from_source(main_text)
214
+ else:
215
+ # Yeni sayfa fetch et
216
+ with contextlib.suppress(Exception):
217
+ resp = await self.httpx.get(src_url)
218
+ iframe_url = await self._get_iframe_from_source(resp.text)
219
+
220
+ if iframe_url:
221
+ if "youtube.com" in iframe_url or "youtu.be" in iframe_url:
222
+ return []
223
+ return await self._process_player(iframe_url, src_name)
224
+ return []
225
+
226
+ for src in sources:
227
+ extract_tasks.append(process_task(src))
228
+
229
+ results_groups = await asyncio.gather(*extract_tasks)
230
+
231
+ final_results = []
232
+ for group in results_groups:
233
+ if group:
234
+ final_results.extend(group)
235
+
236
+ # Duplicate Eliminasyonu
237
+ unique_results = []
238
+ seen = set()
239
+ for res in final_results:
240
+ key = (res.url, res.name)
241
+ if res.url and key not in seen:
242
+ unique_results.append(res)
243
+ seen.add(key)
244
+
245
+ return unique_results
@@ -1,13 +1,12 @@
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
4
- from selectolax.parser import HTMLParser
5
- import re, base64
3
+ from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, ExtractResult, HTMLHelper
4
+ import base64
6
5
 
7
6
  class Sinezy(PluginBase):
8
7
  name = "Sinezy"
9
8
  language = "tr"
10
- main_url = "https://sinezy.fit"
9
+ main_url = "https://sinezy.ink"
11
10
  favicon = f"https://www.google.com/s2/favicons?domain={main_url}&sz=64"
12
11
  description = "Yerli ve yabancı film izle! Türkçe Dublaj ve Alt Yazılı Seçenekleriyle full hd film izlemek için En çok tercih edilen adres!"
13
12
 
@@ -43,112 +42,84 @@ class Sinezy(PluginBase):
43
42
  }
44
43
 
45
44
  async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
46
- full_url = f"{url}page/{page}/"
47
- resp = await self.httpx.get(full_url)
48
- sel = HTMLParser(resp.text)
49
-
45
+ istek = await self.httpx.get(f"{url}page/{page}/")
46
+ secici = HTMLHelper(istek.text)
47
+
50
48
  results = []
51
- for item in sel.css("div.container div.content div.movie_box.move_k"):
52
- link_el = item.css_first("a")
53
- img_el = item.css_first("img")
54
-
55
- title = link_el.attrs.get("title") if link_el else None
56
- href = link_el.attrs.get("href") if link_el else None
57
- poster = img_el.attrs.get("data-src") if img_el else None
58
-
49
+ for item in secici.select("div.container div.content div.movie_box.move_k"):
50
+ title = secici.select_attr("a", "title", item)
51
+ href = secici.select_attr("a", "href", item)
52
+ poster = secici.select_attr("img", "data-src", item)
53
+
59
54
  if title and href:
60
55
  results.append(MainPageResult(
61
56
  category = category,
62
57
  title = title,
63
58
  url = self.fix_url(href),
64
- poster = self.fix_url(poster) if poster else None
59
+ poster = self.fix_url(poster)
65
60
  ))
66
61
 
67
62
  return results
68
63
 
69
64
  async def search(self, query: str) -> list[SearchResult]:
70
- url = f"{self.main_url}/arama/?s={query}"
71
- resp = await self.httpx.get(url)
72
- sel = HTMLParser(resp.text)
65
+ istek = await self.httpx.get(f"{self.main_url}/arama/?s={query}")
66
+ secici = HTMLHelper(istek.text)
73
67
 
74
68
  results = []
75
- for item in sel.css("div.movie_box.move_k"):
76
- link_el = item.css_first("a")
77
- img_el = item.css_first("img")
78
-
79
- title = link_el.attrs.get("title") if link_el else None
80
- href = link_el.attrs.get("href") if link_el else None
81
- poster = img_el.attrs.get("data-src") if img_el else None
69
+ for item in secici.select("div.movie_box.move_k"):
70
+ title = secici.select_attr("a", "title", item)
71
+ href = secici.select_attr("a", "href", item)
72
+ poster = secici.select_attr("img", "data-src", item)
82
73
 
83
74
  if title and href:
84
75
  results.append(SearchResult(
85
76
  title = title,
86
77
  url = self.fix_url(href),
87
- poster = self.fix_url(poster) if poster else None
78
+ poster = self.fix_url(poster)
88
79
  ))
89
80
 
90
81
  return results
91
82
 
92
83
  async def load_item(self, url: str) -> MovieInfo:
93
- resp = await self.httpx.get(url)
94
- sel = HTMLParser(resp.text)
95
-
96
- detail_el = sel.css_first("div.detail")
97
- title = detail_el.attrs.get("title") if detail_el else None
98
-
99
- poster_el = sel.css_first("div.move_k img")
100
- poster = poster_el.attrs.get("data-src") if poster_el else None
101
-
102
- desc_el = sel.css_first("div.desc.yeniscroll p")
103
- description = desc_el.text(strip=True) if desc_el else None
104
-
105
- rating_el = sel.css_first("span.info span.imdb")
106
- rating = rating_el.text(strip=True) if rating_el else None
107
-
108
- tags = [a.text(strip=True) for a in sel.css("div.detail span a") if a.text(strip=True)]
109
- actors = [p.text(strip=True) for p in sel.css("span.oyn p") if p.text(strip=True)]
110
-
111
- year = None
112
- info_el = sel.css_first("span.info")
113
- info_text = info_el.text(strip=True) if info_el else ""
114
- if info_text:
115
- year_match = re.search(r'\b(19\d{2}|20\d{2})\b', info_text)
116
- if year_match:
117
- year = year_match.group(1)
118
-
119
- # Bulunamadıysa tüm sayfada ara
120
- if not year:
121
- all_text = sel.body.text() if sel.body else ""
122
- year_match = re.search(r'\b(19\d{2}|20\d{2})\b', all_text)
123
- if year_match:
124
- year = year_match.group(1)
84
+ istek = await self.httpx.get(url)
85
+ secici = HTMLHelper(istek.text)
86
+
87
+ title = secici.select_attr("div.detail", "title")
88
+ poster = secici.select_poster("div.move_k img")
89
+ description = secici.select_text("div.desc.yeniscroll p")
90
+ rating = secici.select_text("span.info span.imdb")
91
+ tags = secici.select_texts("div.detail span a")
92
+ actors = secici.select_texts("span.oyn p")
93
+ year = secici.extract_year()
94
+ duration = secici.regex_first(r"(\d+) Dakika", secici.select_text("div.detail p"))
125
95
 
126
96
  return MovieInfo(
127
- title = title,
128
97
  url = url,
129
- poster = self.fix_url(poster) if poster else None,
98
+ poster = self.fix_url(poster),
99
+ title = title,
130
100
  description = description,
131
101
  tags = tags,
132
102
  rating = rating,
103
+ year = year,
133
104
  actors = actors,
134
- year = year
105
+ duration = duration
135
106
  )
136
107
 
137
108
  async def load_links(self, url: str) -> list[ExtractResult]:
138
- resp = await self.httpx.get(url)
109
+ istek = await self.httpx.get(url)
110
+ secici = HTMLHelper(istek.text)
139
111
 
140
- match = re.search(r"ilkpartkod\s*=\s*'([^']+)'", resp.text, re.IGNORECASE)
141
- if match:
142
- encoded = match.group(1)
112
+ encoded = secici.regex_first(r"ilkpartkod\s*=\s*'([^']+)'", secici.html)
113
+ name = secici.select_direct_text("li.pgrup a")
114
+ if encoded:
143
115
  try:
144
- decoded = base64.b64decode(encoded).decode('utf-8')
145
- iframe_match = re.search(r'src="([^"]*)"', decoded)
116
+ decoded = base64.b64decode(encoded).decode('utf-8')
117
+ decoded_sec = HTMLHelper(decoded)
118
+ iframe = decoded_sec.select_attr('iframe', 'src')
146
119
 
147
- if iframe_match:
148
- iframe = iframe_match.group(1)
120
+ if iframe:
149
121
  iframe = self.fix_url(iframe)
150
-
151
- data = await self.extract(iframe)
122
+ data = await self.extract(iframe, name_override=name)
152
123
  if data:
153
124
  return [data]
154
125
  except Exception:
@@ -1,8 +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, MovieInfo, ExtractResult
4
- from selectolax.parser import HTMLParser
5
- import re
3
+ from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, ExtractResult, HTMLHelper
6
4
 
7
5
  class SuperFilmGeldi(PluginBase):
8
6
  name = "SuperFilmGeldi"
@@ -36,97 +34,74 @@ class SuperFilmGeldi(PluginBase):
36
34
 
37
35
  async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
38
36
  istek = await self.httpx.get(url.replace("SAYFA", str(page)))
39
- secici = HTMLParser(istek.text)
37
+ secici = HTMLHelper(istek.text)
40
38
 
41
39
  results = []
42
- for veri in secici.css("div.movie-preview-content"):
43
- link_el = veri.css_first("span.movie-title a")
44
- if not link_el:
45
- continue
46
-
47
- title_text = link_el.text(strip=True)
40
+ for veri in secici.select("div.movie-preview-content"):
41
+ title_text = secici.select_text("span.movie-title a", veri)
48
42
  if not title_text:
49
43
  continue
50
44
 
51
- img_el = veri.css_first("img")
52
- href = link_el.attrs.get("href")
53
- poster = img_el.attrs.get("src") if img_el else None
45
+ href = secici.select_attr("span.movie-title a", "href", veri)
46
+ poster = secici.select_attr("img", "src", veri)
54
47
 
55
48
  results.append(MainPageResult(
56
49
  category = category,
57
50
  title = self.clean_title(title_text.split(" izle")[0]),
58
51
  url = self.fix_url(href) if href else "",
59
- poster = self.fix_url(poster) if poster else None,
52
+ poster = self.fix_url(poster),
60
53
  ))
61
54
 
62
55
  return results
63
56
 
64
57
  async def search(self, query: str) -> list[SearchResult]:
65
58
  istek = await self.httpx.get(f"{self.main_url}?s={query}")
66
- secici = HTMLParser(istek.text)
59
+ secici = HTMLHelper(istek.text)
67
60
 
68
61
  results = []
69
- for veri in secici.css("div.movie-preview-content"):
70
- link_el = veri.css_first("span.movie-title a")
71
- if not link_el:
72
- continue
73
-
74
- title_text = link_el.text(strip=True)
62
+ for veri in secici.select("div.movie-preview-content"):
63
+ title_text = secici.select_text("span.movie-title a", veri)
75
64
  if not title_text:
76
65
  continue
77
66
 
78
- img_el = veri.css_first("img")
79
- href = link_el.attrs.get("href")
80
- poster = img_el.attrs.get("src") if img_el else None
67
+ href = secici.select_attr("span.movie-title a", "href", veri)
68
+ poster = secici.select_attr("img", "src", veri)
81
69
 
82
70
  results.append(SearchResult(
83
71
  title = self.clean_title(title_text.split(" izle")[0]),
84
72
  url = self.fix_url(href) if href else "",
85
- poster = self.fix_url(poster) if poster else None,
73
+ poster = self.fix_url(poster),
86
74
  ))
87
75
 
88
76
  return results
89
77
 
90
78
  async def load_item(self, url: str) -> MovieInfo:
91
79
  istek = await self.httpx.get(url)
92
- secici = HTMLParser(istek.text)
93
-
94
- title_el = secici.css_first("div.title h1")
95
- title = title_el.text(strip=True) if title_el else ""
96
- title = self.clean_title(title.split(" izle")[0]) if title else ""
97
-
98
- poster_el = secici.css_first("div.poster img")
99
- poster = poster_el.attrs.get("src") if poster_el else None
100
-
101
- # year: re_first kullanılamaz, re.search kullanıyoruz
102
- year_el = secici.css_first("div.release a")
103
- year_text = year_el.text(strip=True) if year_el else ""
104
- year_match = re.search(r"(\d{4})", year_text)
105
- year = year_match.group(1) if year_match else None
106
-
107
- desc_el = secici.css_first("div.excerpt p")
108
- description = desc_el.text(strip=True) if desc_el else None
80
+ secici = HTMLHelper(istek.text)
109
81
 
110
- tags = [a.text(strip=True) for a in secici.css("div.categories a") if a.text(strip=True)]
111
- actors = [a.text(strip=True) for a in secici.css("div.actor a") if a.text(strip=True)]
82
+ title = self.clean_title(secici.select_text("div.title h1").split(" izle")[0]) if secici.select_text("div.title h1") else ""
83
+ poster = secici.select_poster("div.poster img")
84
+ year = secici.extract_year("div.release a")
85
+ description = secici.select_text("div.excerpt p")
86
+ tags = secici.select_texts("div.categories a")
87
+ actors = secici.select_texts("div.actor a")
112
88
 
113
89
  return MovieInfo(
114
90
  url = url,
115
- poster = self.fix_url(poster) if poster else None,
91
+ poster = self.fix_url(poster),
116
92
  title = title,
117
93
  description = description,
118
94
  tags = tags,
119
95
  year = year,
120
- actors = actors,
96
+ actors = actors
121
97
  )
122
98
 
123
99
  async def load_links(self, url: str) -> list[ExtractResult]:
124
100
  istek = await self.httpx.get(url)
125
- secici = HTMLParser(istek.text)
101
+ secici = HTMLHelper(istek.text)
126
102
 
127
- iframe_el = secici.css_first("div#vast iframe")
128
- iframe = iframe_el.attrs.get("src") if iframe_el else None
129
- iframe = self.fix_url(iframe) if iframe else None
103
+ iframe = secici.select_attr("div#vast iframe", "src")
104
+ iframe = self.fix_url(iframe) if iframe else None
130
105
 
131
106
  if not iframe:
132
107
  return []
@@ -136,10 +111,11 @@ class SuperFilmGeldi(PluginBase):
136
111
  # Mix player özel işleme
137
112
  if "mix" in iframe and "index.php?data=" in iframe:
138
113
  iframe_istek = await self.httpx.get(iframe, headers={"Referer": f"{self.main_url}/"})
139
- mix_point = re.search(r'videoUrl"\s*:\s*"(.*?)"\s*,\s*"videoServer', iframe_istek.text)
114
+ iframe_sec = HTMLHelper(iframe_istek.text)
115
+ mix_point = iframe_sec.regex_first(r'videoUrl"\s*:\s*"(.*?)"\s*,\s*"videoServer')
140
116
 
141
117
  if mix_point:
142
- mix_point = mix_point[1].replace("\\", "")
118
+ mix_point = mix_point.replace("\\", "")
143
119
 
144
120
  # Endpoint belirleme
145
121
  if "mixlion" in iframe: