KekikStream 1.4.4__py3-none-any.whl → 2.0.2__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 (81) hide show
  1. KekikStream/CLI/pypi_kontrol.py +6 -6
  2. KekikStream/Core/Extractor/ExtractorBase.py +13 -12
  3. KekikStream/Core/Extractor/ExtractorLoader.py +25 -17
  4. KekikStream/Core/Extractor/ExtractorManager.py +53 -9
  5. KekikStream/Core/Extractor/ExtractorModels.py +5 -7
  6. KekikStream/Core/Extractor/YTDLPCache.py +35 -0
  7. KekikStream/Core/Media/MediaHandler.py +52 -31
  8. KekikStream/Core/Media/MediaManager.py +0 -3
  9. KekikStream/Core/Plugin/PluginBase.py +47 -21
  10. KekikStream/Core/Plugin/PluginLoader.py +11 -7
  11. KekikStream/Core/Plugin/PluginModels.py +25 -25
  12. KekikStream/Core/__init__.py +1 -0
  13. KekikStream/Extractors/CloseLoad.py +6 -26
  14. KekikStream/Extractors/ContentX_.py +40 -0
  15. KekikStream/Extractors/DzenRu.py +38 -0
  16. KekikStream/Extractors/ExPlay.py +53 -0
  17. KekikStream/Extractors/FirePlayer.py +60 -0
  18. KekikStream/Extractors/HDPlayerSystem.py +41 -0
  19. KekikStream/Extractors/JetTv.py +45 -0
  20. KekikStream/Extractors/MailRu.py +2 -4
  21. KekikStream/Extractors/MixTiger.py +57 -0
  22. KekikStream/Extractors/MolyStream.py +25 -7
  23. KekikStream/Extractors/Odnoklassniki.py +16 -11
  24. KekikStream/Extractors/{OkRuHTTP.py → Odnoklassniki_.py} +5 -1
  25. KekikStream/Extractors/{HDStreamAble.py → PeaceMakerst_.py} +1 -1
  26. KekikStream/Extractors/PixelDrain.py +0 -1
  27. KekikStream/Extractors/PlayerFilmIzle.py +62 -0
  28. KekikStream/Extractors/RapidVid.py +30 -13
  29. KekikStream/Extractors/RapidVid_.py +7 -0
  30. KekikStream/Extractors/SetPlay.py +57 -0
  31. KekikStream/Extractors/SetPrime.py +45 -0
  32. KekikStream/Extractors/SibNet.py +0 -1
  33. KekikStream/Extractors/TurkeyPlayer.py +34 -0
  34. KekikStream/Extractors/VidHide.py +72 -0
  35. KekikStream/Extractors/VidMoly.py +20 -19
  36. KekikStream/Extractors/{VidMolyMe.py → VidMoly_.py} +1 -1
  37. KekikStream/Extractors/VidMoxy.py +0 -1
  38. KekikStream/Extractors/VidPapi.py +89 -0
  39. KekikStream/Extractors/YTDLP.py +177 -0
  40. KekikStream/Extractors/YildizKisaFilm.py +41 -0
  41. KekikStream/Plugins/DiziBox.py +28 -16
  42. KekikStream/Plugins/DiziPal.py +246 -0
  43. KekikStream/Plugins/DiziYou.py +58 -31
  44. KekikStream/Plugins/Dizilla.py +97 -68
  45. KekikStream/Plugins/FilmBip.py +145 -0
  46. KekikStream/Plugins/FilmMakinesi.py +61 -52
  47. KekikStream/Plugins/FilmModu.py +138 -0
  48. KekikStream/Plugins/FullHDFilm.py +164 -0
  49. KekikStream/Plugins/FullHDFilmizlesene.py +38 -37
  50. KekikStream/Plugins/HDFilmCehennemi.py +44 -54
  51. KekikStream/Plugins/JetFilmizle.py +68 -42
  52. KekikStream/Plugins/KultFilmler.py +219 -0
  53. KekikStream/Plugins/RecTV.py +41 -37
  54. KekikStream/Plugins/RoketDizi.py +232 -0
  55. KekikStream/Plugins/SelcukFlix.py +309 -0
  56. KekikStream/Plugins/SezonlukDizi.py +16 -14
  57. KekikStream/Plugins/SineWix.py +39 -30
  58. KekikStream/Plugins/Sinefy.py +238 -0
  59. KekikStream/Plugins/SinemaCX.py +157 -0
  60. KekikStream/Plugins/Sinezy.py +146 -0
  61. KekikStream/Plugins/SuperFilmGeldi.py +121 -0
  62. KekikStream/Plugins/UgurFilm.py +10 -10
  63. KekikStream/__init__.py +296 -319
  64. KekikStream/requirements.txt +3 -4
  65. kekikstream-2.0.2.dist-info/METADATA +309 -0
  66. kekikstream-2.0.2.dist-info/RECORD +82 -0
  67. {kekikstream-1.4.4.dist-info → kekikstream-2.0.2.dist-info}/WHEEL +1 -1
  68. KekikStream/Extractors/FourCX.py +0 -7
  69. KekikStream/Extractors/FourPichive.py +0 -7
  70. KekikStream/Extractors/FourPlayRu.py +0 -7
  71. KekikStream/Extractors/Hotlinger.py +0 -7
  72. KekikStream/Extractors/OkRuSSL.py +0 -7
  73. KekikStream/Extractors/Pichive.py +0 -7
  74. KekikStream/Extractors/PlayRu.py +0 -7
  75. KekikStream/Helpers/Unpack.py +0 -75
  76. KekikStream/Plugins/Shorten.py +0 -225
  77. kekikstream-1.4.4.dist-info/METADATA +0 -108
  78. kekikstream-1.4.4.dist-info/RECORD +0 -63
  79. {kekikstream-1.4.4.dist-info → kekikstream-2.0.2.dist-info}/entry_points.txt +0 -0
  80. {kekikstream-1.4.4.dist-info → kekikstream-2.0.2.dist-info/licenses}/LICENSE +0 -0
  81. {kekikstream-1.4.4.dist-info → kekikstream-2.0.2.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,238 @@
1
+ # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
+
3
+ from KekikStream.Core import PluginBase, MainPageResult, SearchResult, SeriesInfo, Episode, MovieInfo
4
+ from parsel import Selector
5
+ import re, json, urllib.parse
6
+
7
+ class Sinefy(PluginBase):
8
+ name = "Sinefy"
9
+ language = "tr"
10
+ main_url = "https://sinefy3.com"
11
+ favicon = f"https://www.google.com/s2/favicons?domain={main_url}&sz=64"
12
+ description = "Yabancı film izle olarak vizyondaki en yeni yabancı filmleri türkçe dublaj ve altyazılı olarak en hızlı şekilde full hd olarak sizlere sunuyoruz."
13
+
14
+ main_page = {
15
+ f"{main_url}/page/" : "Son Eklenenler",
16
+ f"{main_url}/en-yenifilmler" : "Yeni Filmler",
17
+ f"{main_url}/netflix-filmleri-izle" : "Netflix Filmleri",
18
+ f"{main_url}/dizi-izle/netflix" : "Netflix Dizileri",
19
+ f"{main_url}/gozat/filmler/animasyon" : "Animasyon",
20
+ f"{main_url}/gozat/filmler/komedi" : "Komedi",
21
+ f"{main_url}/gozat/filmler/suc" : "Suç",
22
+ f"{main_url}/gozat/filmler/aile" : "Aile",
23
+ f"{main_url}/gozat/filmler/aksiyon" : "Aksiyon",
24
+ f"{main_url}/gozat/filmler/macera" : "Macera",
25
+ f"{main_url}/gozat/filmler/fantastik" : "Fantastik",
26
+ f"{main_url}/gozat/filmler/korku" : "Korku",
27
+ f"{main_url}/gozat/filmler/romantik" : "Romantik",
28
+ f"{main_url}/gozat/filmler/savas" : "Savaş",
29
+ f"{main_url}/gozat/filmler/gerilim" : "Gerilim",
30
+ f"{main_url}/gozat/filmler/bilim-kurgu" : "Bilim Kurgu",
31
+ f"{main_url}/gozat/filmler/dram" : "Dram",
32
+ f"{main_url}/gozat/filmler/gizem" : "Gizem",
33
+ f"{main_url}/gozat/filmler/western" : "Western",
34
+ f"{main_url}/gozat/filmler/ulke/turkiye" : "Türk Filmleri",
35
+ f"{main_url}/gozat/filmler/ulke/kore" : "Kore Filmleri"
36
+ }
37
+
38
+ async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
39
+ if "page/" in url:
40
+ full_url = f"{url}{page}"
41
+ elif "en-yenifilmler" in url or "netflix" in url:
42
+ full_url = f"{url}/{page}"
43
+ else:
44
+ full_url = f"{url}&page={page}"
45
+
46
+ resp = await self.httpx.get(full_url)
47
+ sel = Selector(resp.text)
48
+
49
+ results = []
50
+ # Kotlin: div.poster-with-subject, div.dark-segment div.poster-md.poster
51
+ for item in sel.css("div.poster-with-subject, div.dark-segment div.poster-md.poster"):
52
+ title = item.css("h2::text").get()
53
+ href = item.css("a::attr(href)").get()
54
+ poster = item.css("img::attr(data-srcset)").get()
55
+ if poster:
56
+ poster = poster.split(",")[0].split(" ")[0]
57
+
58
+ if title and href:
59
+ results.append(MainPageResult(
60
+ category = category,
61
+ title = title,
62
+ url = self.fix_url(href),
63
+ poster = self.fix_url(poster)
64
+ ))
65
+
66
+ return results
67
+
68
+ async def search(self, query: str) -> list[SearchResult]:
69
+ # Try to get dynamic keys from main page first
70
+ c_key = "ca1d4a53d0f4761a949b85e51e18f096"
71
+ c_value = "MTc0NzI2OTAwMDU3ZTEwYmZjMDViNWFmOWIwZDViODg0MjU4MjA1ZmYxOThmZTYwMDdjMWQzMzliNzY5NzFlZmViMzRhMGVmNjgwODU3MGIyZA=="
72
+
73
+ try:
74
+ resp = await self.httpx.get(self.main_url)
75
+ sel = Selector(resp.text)
76
+ cke = sel.css("input[name='cKey']::attr(value)").get()
77
+ cval = sel.css("input[name='cValue']::attr(value)").get()
78
+ if cke and cval:
79
+ c_key = cke
80
+ c_value = cval
81
+
82
+ except Exception:
83
+ pass
84
+
85
+ post_url = f"{self.main_url}/bg/searchcontent"
86
+ data = {
87
+ "cKey" : c_key,
88
+ "cValue" : c_value,
89
+ "searchTerm" : query
90
+ }
91
+
92
+ headers = {
93
+ "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:134.0) Gecko/20100101 Firefox/134.0",
94
+ "Accept" : "application/json, text/javascript, */*; q=0.01",
95
+ "X-Requested-With" : "XMLHttpRequest",
96
+ "Content-Type" : "application/x-www-form-urlencoded; charset=UTF-8"
97
+ }
98
+
99
+ response = await self.httpx.post(post_url, data=data, headers=headers)
100
+
101
+ try:
102
+ # Extract JSON data from response (might contain garbage chars at start)
103
+ raw = response.text
104
+ json_start = raw.find('{')
105
+ if json_start != -1:
106
+ clean_json = raw[json_start:]
107
+ data = json.loads(clean_json)
108
+
109
+ results = []
110
+ # Result array is in data['data']['result']
111
+ res_array = data.get("data", {}).get("result", [])
112
+
113
+ if not res_array:
114
+ # Fallback manual parsing ?
115
+ pass
116
+
117
+ for item in res_array:
118
+ name = item.get("object_name")
119
+ slug = item.get("used_slug")
120
+ poster = item.get("object_poster_url")
121
+
122
+ if name and slug:
123
+ if "cdn.ampproject.org" in poster:
124
+ poster = "https://images.macellan.online/images/movie/poster/180/275/80/" + poster.split("/")[-1]
125
+
126
+ results.append(SearchResult(
127
+ title=name,
128
+ url=self.fix_url(slug),
129
+ poster=self.fix_url(poster)
130
+ ))
131
+ return results
132
+
133
+ except Exception:
134
+ pass
135
+ return []
136
+
137
+ async def load_item(self, url: str) -> SeriesInfo:
138
+ resp = await self.httpx.get(url)
139
+ sel = Selector(resp.text)
140
+
141
+ title = sel.css("h1::text").get()
142
+ poster_info = sel.css("div.ui.items img::attr(data-srcset)").get()
143
+ poster = None
144
+ if poster_info:
145
+ # take 1x
146
+ parts = str(poster_info).split(",")
147
+ for p in parts:
148
+ if "1x" in p:
149
+ poster = p.strip().split(" ")[0]
150
+ break
151
+
152
+ description = sel.css("p#tv-series-desc::text").get()
153
+ tags = sel.css("div.item.categories a::text").getall()
154
+ rating = sel.css("span.color-imdb::text").get()
155
+ actors = sel.css("div.content h5::text").getall()
156
+ year = sel.css("span.item.year::text").get() # Year bilgisi eklendi
157
+
158
+ episodes = []
159
+ season_elements = sel.css("section.episodes-box")
160
+
161
+ if season_elements:
162
+ # Get season links
163
+ season_links = []
164
+ menu = sel.css("div.ui.vertical.fluid.tabular.menu a")
165
+ for link in menu:
166
+ href = link.css("::attr(href)").get()
167
+ if href:
168
+ season_links.append(self.fix_url(href))
169
+
170
+ for s_url in season_links:
171
+ target_url = s_url if "/bolum-" in s_url else f"{s_url}/bolum-1"
172
+
173
+ try:
174
+ s_resp = await self.httpx.get(target_url)
175
+ s_sel = Selector(s_resp.text)
176
+ ep_links = s_sel.css("div.ui.list.celled a.item")
177
+
178
+ current_season_no = 1
179
+ match = re.search(r"sezon-(\d+)", target_url)
180
+ if match:
181
+ current_season_no = int(match.group(1))
182
+
183
+ for ep_link in ep_links:
184
+ href = ep_link.css("::attr(href)").get()
185
+ name = ep_link.css("div.content div.header::text").get()
186
+
187
+ if href:
188
+ ep_no = 0
189
+ match_ep = re.search(r"bolum-(\d+)", href)
190
+ if match_ep:
191
+ ep_no = int(match_ep.group(1))
192
+
193
+ episodes.append(Episode(
194
+ season = current_season_no,
195
+ episode = ep_no,
196
+ title = name.strip() if name else "",
197
+ url = self.fix_url(href)
198
+ ))
199
+ except Exception:
200
+ pass
201
+
202
+ if episodes:
203
+ return SeriesInfo(
204
+ title = title,
205
+ url = url,
206
+ poster = self.fix_url(poster),
207
+ description = description,
208
+ rating = rating,
209
+ tags = tags,
210
+ actors = actors,
211
+ year = year,
212
+ episodes = episodes
213
+ )
214
+ else:
215
+ return MovieInfo(
216
+ title = title,
217
+ url = url,
218
+ poster = self.fix_url(poster),
219
+ description = description,
220
+ rating = rating,
221
+ tags = tags,
222
+ actors = actors,
223
+ year = year
224
+ )
225
+
226
+ async def load_links(self, url: str) -> list[dict]:
227
+ resp = await self.httpx.get(url)
228
+ sel = Selector(resp.text)
229
+
230
+ iframe = sel.css("iframe::attr(src)").get()
231
+ if iframe:
232
+ iframe = self.fix_url(iframe)
233
+ extractor = self.ex_manager.find_extractor(iframe)
234
+ return [{
235
+ "url" : iframe,
236
+ "name" : extractor.name if extractor else "Iframe"
237
+ }]
238
+ return []
@@ -0,0 +1,157 @@
1
+ # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
+
3
+ from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, ExtractResult, Subtitle
4
+ from parsel import Selector
5
+ import re
6
+
7
+ class SinemaCX(PluginBase):
8
+ name = "SinemaCX"
9
+ language = "tr"
10
+ main_url = "https://www.sinema.fit"
11
+ favicon = f"https://www.google.com/s2/favicons?domain={main_url}&sz=64"
12
+ description = "HD Film izle, Türkçe Dublaj ve Altyazılı filmler."
13
+
14
+ main_page = {
15
+ f"{main_url}/page/SAYFA" : "Son Eklenen Filmler",
16
+ f"{main_url}/izle/aile-filmleri/page/SAYFA" : "Aile Filmleri",
17
+ f"{main_url}/izle/aksiyon-filmleri/page/SAYFA" : "Aksiyon Filmleri",
18
+ f"{main_url}/izle/animasyon-filmleri/page/SAYFA" : "Animasyon Filmleri",
19
+ f"{main_url}/izle/belgesel/page/SAYFA" : "Belgesel Filmleri",
20
+ f"{main_url}/izle/bilim-kurgu-filmleri/page/SAYFA" : "Bilim Kurgu Filmler",
21
+ f"{main_url}/izle/biyografi/page/SAYFA" : "Biyografi Filmleri",
22
+ f"{main_url}/izle/fantastik-filmler/page/SAYFA" : "Fantastik Filmler",
23
+ f"{main_url}/izle/gizem-filmleri/page/SAYFA" : "Gizem Filmleri",
24
+ f"{main_url}/izle/komedi-filmleri/page/SAYFA" : "Komedi Filmleri",
25
+ f"{main_url}/izle/korku-filmleri/page/SAYFA" : "Korku Filmleri",
26
+ f"{main_url}/izle/macera-filmleri/page/SAYFA" : "Macera Filmleri",
27
+ f"{main_url}/izle/romantik-filmler/page/SAYFA" : "Romantik Filmler",
28
+ f"{main_url}/izle/erotik-filmler/page/SAYFA" : "Erotik Film",
29
+ }
30
+
31
+ async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
32
+ istek = await self.httpx.get(url.replace("SAYFA", str(page)))
33
+ secici = Selector(istek.text)
34
+
35
+ return [
36
+ MainPageResult(
37
+ category = category,
38
+ title = veri.css("div.yanac span::text").get(),
39
+ url = self.fix_url(veri.css("div.yanac a::attr(href)").get()),
40
+ poster = self.fix_url(veri.css("a.resim img::attr(data-src)").get() or veri.css("a.resim img::attr(src)").get()),
41
+ )
42
+ for veri in secici.css("div.son div.frag-k, div.icerik div.frag-k")
43
+ if veri.css("div.yanac span::text").get()
44
+ ]
45
+
46
+ async def search(self, query: str) -> list[SearchResult]:
47
+ istek = await self.httpx.get(f"{self.main_url}/?s={query}")
48
+ secici = Selector(istek.text)
49
+
50
+ return [
51
+ SearchResult(
52
+ title = veri.css("div.yanac span::text").get(),
53
+ url = self.fix_url(veri.css("div.yanac a::attr(href)").get()),
54
+ poster = self.fix_url(veri.css("a.resim img::attr(data-src)").get() or veri.css("a.resim img::attr(src)").get()),
55
+ )
56
+ for veri in secici.css("div.icerik div.frag-k")
57
+ if veri.css("div.yanac span::text").get()
58
+ ]
59
+
60
+ async def load_item(self, url: str) -> MovieInfo:
61
+ istek = await self.httpx.get(url)
62
+ secici = Selector(istek.text)
63
+
64
+ duration_match = re.search(r"Süre:.*?(\d+)\s*Dakika", istek.text)
65
+ description = secici.css("div.ackl div.scroll-liste::text").get()
66
+
67
+ return MovieInfo(
68
+ url = url,
69
+ poster = self.fix_url(secici.css("link[rel='image_src']::attr(href)").get()),
70
+ title = secici.css("div.f-bilgi h1::text").get(),
71
+ description = description.strip() if description else None,
72
+ tags = [a.css("::text").get() for a in secici.css("div.f-bilgi div.tur a")],
73
+ year = secici.css("div.f-bilgi ul.detay a[href*='yapim']::text").get(),
74
+ actors = [li.css("span.isim::text").get() for li in secici.css("li.oync li.oyuncu-k")],
75
+ duration = int(duration_match[1]) if duration_match else None,
76
+ )
77
+
78
+ async def load_links(self, url: str) -> list[dict]:
79
+ istek = await self.httpx.get(url)
80
+ secici = Selector(istek.text)
81
+
82
+ iframe_list = [iframe.css("::attr(data-vsrc)").get() for iframe in secici.css("iframe")]
83
+ iframe_list = [i for i in iframe_list if i]
84
+
85
+ # Sadece fragman varsa /2/ sayfasından dene
86
+ has_only_trailer = all(
87
+ "youtube" in (i or "").lower() or "fragman" in (i or "").lower() or "trailer" in (i or "").lower()
88
+ for i in iframe_list
89
+ )
90
+
91
+ if has_only_trailer:
92
+ alt_url = url.rstrip("/") + "/2/"
93
+ alt_istek = await self.httpx.get(alt_url)
94
+ alt_sec = Selector(alt_istek.text)
95
+ iframe_list = [iframe.css("::attr(data-vsrc)").get() for iframe in alt_sec.css("iframe")]
96
+ iframe_list = [i for i in iframe_list if i]
97
+
98
+ if not iframe_list:
99
+ return []
100
+
101
+ iframe = self.fix_url(iframe_list[0].split("?img=")[0])
102
+ if not iframe:
103
+ return []
104
+
105
+ results = []
106
+
107
+ # Altyazı kontrolü
108
+ self.httpx.headers.update({"Referer": f"{self.main_url}/"})
109
+ iframe_istek = await self.httpx.get(iframe)
110
+ iframe_text = iframe_istek.text
111
+
112
+ subtitles = []
113
+ sub_match = re.search(r'playerjsSubtitle\s*=\s*"(.+?)"', iframe_text)
114
+ if sub_match:
115
+ sub_section = sub_match[1]
116
+ for sub in re.finditer(r'\[(.*?)](https?://[^\s",]+)', sub_section):
117
+ subtitles.append(Subtitle(name=sub[1], url=self.fix_url(sub[2])))
118
+
119
+ # player.filmizle.in kontrolü
120
+ if "player.filmizle.in" in iframe.lower():
121
+ base_match = re.search(r"https?://([^/]+)", iframe)
122
+ if base_match:
123
+ base_url = base_match[1]
124
+ vid_id = iframe.split("/")[-1]
125
+
126
+ self.httpx.headers.update({"X-Requested-With": "XMLHttpRequest"})
127
+ vid_istek = await self.httpx.post(
128
+ f"https://{base_url}/player/index.php?data={vid_id}&do=getVideo",
129
+ )
130
+ vid_data = vid_istek.json()
131
+
132
+ if vid_data.get("securedLink"):
133
+ results.append({
134
+ "name" : f"{self.name}",
135
+ "url" : vid_data["securedLink"],
136
+ "referer" : iframe,
137
+ "subtitles" : subtitles
138
+ })
139
+ else:
140
+ # Extractor'a yönlendir
141
+ extractor = self.ex_manager.find_extractor(iframe)
142
+ results.append({
143
+ "name" : f"{extractor.name if extractor else self.name}",
144
+ "url" : iframe,
145
+ "referer" : f"{self.main_url}/",
146
+ "subtitles" : subtitles
147
+ })
148
+
149
+ return results
150
+
151
+ async def play(self, **kwargs):
152
+ extract_result = ExtractResult(**kwargs)
153
+ self.media_handler.title = kwargs.get("name")
154
+ if self.name not in self.media_handler.title:
155
+ self.media_handler.title = f"{self.name} | {self.media_handler.title}"
156
+
157
+ self.media_handler.play_media(extract_result)
@@ -0,0 +1,146 @@
1
+ # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
+
3
+ from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo
4
+ from parsel import Selector
5
+ import re, base64
6
+
7
+ class Sinezy(PluginBase):
8
+ name = "Sinezy"
9
+ language = "tr"
10
+ main_url = "https://sinezy.fit"
11
+ favicon = f"https://www.google.com/s2/favicons?domain={main_url}&sz=64"
12
+ 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
+
14
+ main_page = {
15
+ f"{main_url}/izle/en-yeni-filmler/" : "Yeni Filmler",
16
+ f"{main_url}/izle/en-yi-filmler/" : "En İyi Filmler",
17
+ f"{main_url}/izle/aksiyon-filmleri/" : "Aksiyon ",
18
+ f"{main_url}/izle/animasyon-filmleri/" : "Animasyon",
19
+ f"{main_url}/izle/belgesel-izle/" : "Belgesel",
20
+ f"{main_url}/izle/bilim-kurgu-filmleri/" : "Bilim Kurgu ",
21
+ f"{main_url}/izle/biyografi-filmleri/" : "Biyografi ",
22
+ f"{main_url}/izle/dram-filmleri/" : "Dram",
23
+ f"{main_url}/izle/erotik-film-izle/" : "Erotik ",
24
+ f"{main_url}/izle/fantastik-filmler/" : "Fantastik",
25
+ f"{main_url}/izle/gelecek-filmler/" : "Yakında",
26
+ f"{main_url}/izle/gerilim-filmleri/" : "Gerilim ",
27
+ f"{main_url}/izle/gizem-filmleri/" : "Gizem ",
28
+ f"{main_url}/izle/komedi-filmleri/" : "Komedi ",
29
+ f"{main_url}/izle/korku-filmleri/" : "Korku ",
30
+ f"{main_url}/izle/macera-filmleri/" : "Macera ",
31
+ f"{main_url}/izle/muzikal-izle/" : "Müzikal",
32
+ f"{main_url}/izle/romantik-film/" : "Romantik ",
33
+ f"{main_url}/izle/savas-filmleri/" : "Savaş ",
34
+ f"{main_url}/izle/spor-filmleri/" : "Spor ",
35
+ f"{main_url}/izle/suc-filmleri/" : "Suç ",
36
+ f"{main_url}/izle/tarih-filmleri/" : "Tarih ",
37
+ f"{main_url}/izle/turkce-altyazili-promo/" : "Altyazılı Pro",
38
+ f"{main_url}/izle/yabanci-dizi/" : "Yabancı Dizi",
39
+ f"{main_url}/izle/en-iyi-filmler/" : "En İyi Filmler",
40
+ f"{main_url}/izle/en-yeni-filmler/" : "Yeni Filmler",
41
+ f"{main_url}/izle/yerli-filmler/" : "Yerli Filmler",
42
+ f"{main_url}/izle/yetiskin-film/" : "Yetişkin +18",
43
+ }
44
+
45
+ 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 = Selector(resp.text)
49
+
50
+ results = []
51
+ for item in sel.css("div.container div.content div.movie_box.move_k"):
52
+ title = item.css("a::attr(title)").get()
53
+ href = item.css("a::attr(href)").get()
54
+ poster = item.css("img::attr(data-src)").get()
55
+
56
+ if title and href:
57
+ results.append(MainPageResult(
58
+ category = category,
59
+ title = title,
60
+ url = self.fix_url(href),
61
+ poster = self.fix_url(poster)
62
+ ))
63
+
64
+ return results
65
+
66
+ async def search(self, query: str) -> list[SearchResult]:
67
+ url = f"{self.main_url}/arama/?s={query}"
68
+ resp = await self.httpx.get(url)
69
+ sel = Selector(resp.text)
70
+
71
+ results = []
72
+ for item in sel.css("div.movie_box.move_k"):
73
+ title = item.css("a::attr(title)").get()
74
+ href = item.css("a::attr(href)").get()
75
+ poster = item.css("img::attr(data-src)").get()
76
+
77
+ if title and href:
78
+ results.append(SearchResult(
79
+ title = title,
80
+ url = self.fix_url(href),
81
+ poster = self.fix_url(poster)
82
+ ))
83
+
84
+ return results
85
+
86
+ async def load_item(self, url: str) -> MovieInfo:
87
+ resp = await self.httpx.get(url)
88
+ sel = Selector(resp.text)
89
+
90
+ title = sel.css("div.detail::attr(title)").get()
91
+ poster = sel.css("div.move_k img::attr(data-src)").get()
92
+ description = sel.css("div.desc.yeniscroll p::text").get()
93
+ rating = sel.css("span.info span.imdb::text").get()
94
+
95
+ tags = sel.css("div.detail span a::text").getall()
96
+ actors = sel.css("span.oyn p::text").getall() # Might need splitting logic
97
+
98
+ year = None
99
+ info_text = sel.css("span.info::text").get()
100
+ if info_text:
101
+ year_match = re.search(r'\b(19\d{2}|20\d{2})\b', info_text)
102
+ if year_match:
103
+ year = year_match.group(1)
104
+
105
+ # Bulunamadıysa tüm sayfada ara
106
+ if not year:
107
+ all_text = " ".join(sel.css("::text").getall())
108
+ year_match = re.search(r'\b(19\d{2}|20\d{2})\b', all_text)
109
+ if year_match:
110
+ year = year_match.group(1)
111
+
112
+ return MovieInfo(
113
+ title = title,
114
+ url = url,
115
+ poster = self.fix_url(poster),
116
+ description = description,
117
+ tags = tags,
118
+ rating = rating,
119
+ actors = actors,
120
+ year = year
121
+ )
122
+
123
+ async def load_links(self, url: str) -> list[dict]:
124
+ resp = await self.httpx.get(url)
125
+
126
+ match = re.search(r"ilkpartkod\s*=\s*'([^']+)'", resp.text, re.IGNORECASE)
127
+ if match:
128
+ encoded = match.group(1)
129
+ try:
130
+ decoded = base64.b64decode(encoded).decode('utf-8')
131
+ iframe_match = re.search(r'src="([^"]*)"', decoded)
132
+
133
+ if iframe_match:
134
+ iframe = iframe_match.group(1)
135
+ iframe = self.fix_url(iframe)
136
+
137
+ extractor = self.ex_manager.find_extractor(iframe)
138
+
139
+ return [{
140
+ "url" : iframe,
141
+ "name" : extractor.name if extractor else "Iframe"
142
+ }]
143
+ except Exception:
144
+ pass
145
+
146
+ return []
@@ -0,0 +1,121 @@
1
+ # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
+
3
+ from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, ExtractResult, Subtitle
4
+ from parsel import Selector
5
+ import re
6
+
7
+ class SuperFilmGeldi(PluginBase):
8
+ name = "SuperFilmGeldi"
9
+ language = "tr"
10
+ main_url = "https://www.superfilmgeldi13.art"
11
+ favicon = f"https://www.google.com/s2/favicons?domain={main_url}&sz=64"
12
+ description = "Ücretsiz film izleme sitesi."
13
+
14
+ main_page = {
15
+ f"{main_url}/page/SAYFA" : "Son Eklenenler",
16
+ f"{main_url}/hdizle/category/aksiyon/page/SAYFA" : "Aksiyon",
17
+ f"{main_url}/hdizle/category/animasyon/page/SAYFA" : "Animasyon",
18
+ f"{main_url}/hdizle/category/belgesel/page/SAYFA" : "Belgesel",
19
+ f"{main_url}/hdizle/category/bilim-kurgu/page/SAYFA" : "Bilim Kurgu",
20
+ f"{main_url}/hdizle/category/fantastik/page/SAYFA" : "Fantastik",
21
+ f"{main_url}/hdizle/category/komedi-filmleri/page/SAYFA" : "Komedi Filmleri",
22
+ f"{main_url}/hdizle/category/macera/page/SAYFA" : "Macera",
23
+ f"{main_url}/hdizle/category/gerilim/page/SAYFA" : "Gerilim",
24
+ f"{main_url}/hdizle/category/suc/page/SAYFA" : "Suç",
25
+ f"{main_url}/hdizle/category/karete-filmleri/page/SAYFA" : "Karate Filmleri",
26
+ }
27
+
28
+ async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
29
+ istek = await self.httpx.get(url.replace("SAYFA", str(page)))
30
+ secici = Selector(istek.text)
31
+
32
+ return [
33
+ MainPageResult(
34
+ category = category,
35
+ title = self.clean_title(veri.css("span.movie-title a::text").get().split(" izle")[0]),
36
+ url = self.fix_url(veri.css("span.movie-title a::attr(href)").get()),
37
+ poster = self.fix_url(veri.css("img::attr(src)").get()),
38
+ )
39
+ for veri in secici.css("div.movie-preview-content")
40
+ if veri.css("span.movie-title a::text").get()
41
+ ]
42
+
43
+ async def search(self, query: str) -> list[SearchResult]:
44
+ istek = await self.httpx.get(f"{self.main_url}?s={query}")
45
+ secici = Selector(istek.text)
46
+
47
+ return [
48
+ SearchResult(
49
+ title = self.clean_title(veri.css("span.movie-title a::text").get().split(" izle")[0]),
50
+ url = self.fix_url(veri.css("span.movie-title a::attr(href)").get()),
51
+ poster = self.fix_url(veri.css("img::attr(src)").get()),
52
+ )
53
+ for veri in secici.css("div.movie-preview-content")
54
+ if veri.css("span.movie-title a::text").get()
55
+ ]
56
+
57
+ async def load_item(self, url: str) -> MovieInfo:
58
+ istek = await self.httpx.get(url)
59
+ secici = Selector(istek.text)
60
+
61
+ title = secici.css("div.title h1::text").get()
62
+ title = self.clean_title(title.split(" izle")[0]) if title else ""
63
+ poster = self.fix_url(secici.css("div.poster img::attr(src)").get())
64
+ year = secici.css("div.release a::text").re_first(r"(\d{4})")
65
+ description = secici.css("div.excerpt p::text").get()
66
+ tags = secici.css("div.categories a::text").getall()
67
+ actors = secici.css("div.actor a::text").getall()
68
+
69
+ return MovieInfo(
70
+ url = url,
71
+ poster = poster,
72
+ title = title,
73
+ description = description,
74
+ tags = tags,
75
+ year = year,
76
+ actors = actors,
77
+ )
78
+
79
+ async def load_links(self, url: str) -> list[dict]:
80
+ istek = await self.httpx.get(url)
81
+ secici = Selector(istek.text)
82
+
83
+ iframe = self.fix_url(secici.css("div#vast iframe::attr(src)").get())
84
+ if not iframe:
85
+ return []
86
+
87
+ results = []
88
+
89
+ # Mix player özel işleme
90
+ if "mix" in iframe and "index.php?data=" in iframe:
91
+ iframe_istek = await self.httpx.get(iframe, headers={"Referer": f"{self.main_url}/"})
92
+ mix_point = re.search(r'videoUrl":"(.*)","videoServer', iframe_istek.text)
93
+
94
+ if mix_point:
95
+ mix_point = mix_point[1].replace("\\", "")
96
+
97
+ # Endpoint belirleme
98
+ if "mixlion" in iframe:
99
+ end_point = "?s=3&d="
100
+ elif "mixeagle" in iframe:
101
+ end_point = "?s=1&d="
102
+ else:
103
+ end_point = "?s=0&d="
104
+
105
+ m3u_link = iframe.split("/player")[0] + mix_point + end_point
106
+
107
+ results.append({
108
+ "name" : f"{self.name} | Mix Player",
109
+ "url" : m3u_link,
110
+ "referer" : iframe,
111
+ "subtitles" : []
112
+ })
113
+ else:
114
+ extractor = self.ex_manager.find_extractor(iframe)
115
+ results.append({
116
+ "name" : extractor.name if extractor else "Player",
117
+ "url" : iframe,
118
+ "referer" : f"{self.main_url}/"
119
+ })
120
+
121
+ return results