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.
- KekikStream/Core/Extractor/ExtractorBase.py +20 -9
- KekikStream/Core/Extractor/ExtractorLoader.py +25 -17
- KekikStream/Core/Extractor/ExtractorManager.py +53 -9
- KekikStream/Core/Extractor/ExtractorModels.py +5 -7
- KekikStream/Core/Extractor/YTDLPCache.py +35 -0
- KekikStream/Core/Media/MediaHandler.py +44 -26
- KekikStream/Core/Media/MediaManager.py +0 -3
- KekikStream/Core/Plugin/PluginBase.py +82 -22
- KekikStream/Core/Plugin/PluginLoader.py +11 -7
- KekikStream/Core/Plugin/PluginModels.py +25 -26
- KekikStream/Core/__init__.py +1 -0
- KekikStream/Extractors/CloseLoad.py +21 -7
- KekikStream/Extractors/ContentX.py +21 -6
- KekikStream/Extractors/DonilasPlay.py +86 -0
- KekikStream/Extractors/DzenRu.py +38 -0
- KekikStream/Extractors/ExPlay.py +53 -0
- KekikStream/Extractors/Filemoon.py +78 -0
- KekikStream/Extractors/HDPlayerSystem.py +41 -0
- KekikStream/Extractors/JetTv.py +45 -0
- KekikStream/Extractors/MailRu.py +3 -4
- KekikStream/Extractors/MixPlayHD.py +2 -3
- KekikStream/Extractors/MixTiger.py +57 -0
- KekikStream/Extractors/MolyStream.py +5 -5
- KekikStream/Extractors/Odnoklassniki.py +13 -7
- KekikStream/Extractors/PeaceMakerst.py +10 -5
- KekikStream/Extractors/PixelDrain.py +1 -2
- KekikStream/Extractors/PlayerFilmIzle.py +65 -0
- KekikStream/Extractors/RapidVid.py +23 -8
- KekikStream/Extractors/SetPlay.py +66 -0
- KekikStream/Extractors/SetPrime.py +45 -0
- KekikStream/Extractors/SibNet.py +2 -3
- KekikStream/Extractors/Sobreatsesuyp.py +4 -5
- KekikStream/Extractors/TRsTX.py +4 -5
- KekikStream/Extractors/TauVideo.py +2 -3
- KekikStream/Extractors/TurboImgz.py +2 -3
- KekikStream/Extractors/TurkeyPlayer.py +34 -0
- KekikStream/Extractors/VCTPlay.py +41 -0
- KekikStream/Extractors/VidHide.py +81 -0
- KekikStream/Extractors/VidMoly.py +55 -34
- KekikStream/Extractors/VidMoxy.py +2 -3
- KekikStream/Extractors/VidPapi.py +89 -0
- KekikStream/Extractors/VideoSeyred.py +3 -4
- KekikStream/Extractors/YTDLP.py +211 -0
- KekikStream/Extractors/YildizKisaFilm.py +41 -0
- KekikStream/Plugins/BelgeselX.py +196 -0
- KekikStream/Plugins/DiziBox.py +25 -34
- KekikStream/Plugins/DiziPal.py +24 -35
- KekikStream/Plugins/DiziYou.py +54 -37
- KekikStream/Plugins/Dizilla.py +66 -46
- KekikStream/Plugins/FilmBip.py +142 -0
- KekikStream/Plugins/FilmMakinesi.py +36 -28
- KekikStream/Plugins/FilmModu.py +20 -24
- KekikStream/Plugins/FullHDFilm.py +220 -0
- KekikStream/Plugins/FullHDFilmizlesene.py +9 -15
- KekikStream/Plugins/HDFilmCehennemi.py +141 -69
- KekikStream/Plugins/JetFilmizle.py +85 -52
- KekikStream/Plugins/KultFilmler.py +217 -0
- KekikStream/Plugins/RecTV.py +22 -34
- KekikStream/Plugins/RoketDizi.py +222 -0
- KekikStream/Plugins/SelcukFlix.py +328 -0
- KekikStream/Plugins/SetFilmIzle.py +252 -0
- KekikStream/Plugins/SezonlukDizi.py +54 -21
- KekikStream/Plugins/SineWix.py +17 -29
- KekikStream/Plugins/Sinefy.py +241 -0
- KekikStream/Plugins/SinemaCX.py +154 -0
- KekikStream/Plugins/Sinezy.py +143 -0
- KekikStream/Plugins/SuperFilmGeldi.py +130 -0
- KekikStream/Plugins/UgurFilm.py +13 -19
- KekikStream/__init__.py +47 -56
- KekikStream/requirements.txt +3 -4
- kekikstream-2.2.0.dist-info/METADATA +312 -0
- kekikstream-2.2.0.dist-info/RECORD +81 -0
- KekikStream/Extractors/FourCX.py +0 -7
- KekikStream/Extractors/FourPichive.py +0 -7
- KekikStream/Extractors/FourPlayRu.py +0 -7
- KekikStream/Extractors/HDStreamAble.py +0 -7
- KekikStream/Extractors/Hotlinger.py +0 -7
- KekikStream/Extractors/OkRuHTTP.py +0 -7
- KekikStream/Extractors/OkRuSSL.py +0 -7
- KekikStream/Extractors/Pichive.py +0 -7
- KekikStream/Extractors/PlayRu.py +0 -7
- KekikStream/Extractors/VidMolyMe.py +0 -7
- kekikstream-1.7.1.dist-info/METADATA +0 -109
- kekikstream-1.7.1.dist-info/RECORD +0 -63
- {kekikstream-1.7.1.dist-info → kekikstream-2.2.0.dist-info}/WHEEL +0 -0
- {kekikstream-1.7.1.dist-info → kekikstream-2.2.0.dist-info}/entry_points.txt +0 -0
- {kekikstream-1.7.1.dist-info → kekikstream-2.2.0.dist-info}/licenses/LICENSE +0 -0
- {kekikstream-1.7.1.dist-info → kekikstream-2.2.0.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,241 @@
|
|
|
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, ExtractResult
|
|
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[ExtractResult]:
|
|
227
|
+
resp = await self.httpx.get(url)
|
|
228
|
+
sel = Selector(resp.text)
|
|
229
|
+
|
|
230
|
+
iframe = sel.css("iframe::attr(src)").get()
|
|
231
|
+
if not iframe:
|
|
232
|
+
return []
|
|
233
|
+
|
|
234
|
+
iframe_url = self.fix_url(iframe)
|
|
235
|
+
|
|
236
|
+
# Always return iframe (matching Kotlin - no extractor check)
|
|
237
|
+
# loadExtractor in Kotlin handles extraction internally
|
|
238
|
+
return [ExtractResult(
|
|
239
|
+
url = iframe_url,
|
|
240
|
+
name = "Sinefy Player"
|
|
241
|
+
)]
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
|
+
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, Subtitle, ExtractResult
|
|
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 = "Türkiye'nin en iyi film platformu Sinema.cc! 2026'nın en yeni ve popüler yabancı yapımları, Türkçe dublaj ve altyazılı HD kalitede, reklamsız ve ücretsiz olarak seni bekliyor. Şimdi izle!"
|
|
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/dram-filmleri/page/SAYFA" : "Dram Filmleri",
|
|
23
|
+
f"{main_url}/izle/erotik-filmler/page/SAYFA" : "Erotik Film",
|
|
24
|
+
f"{main_url}/izle/fantastik-filmler/page/SAYFA" : "Fantastik Filmler",
|
|
25
|
+
f"{main_url}/izle/gerilim-filmleri/page/SAYFA" : "Gerilim Filmleri",
|
|
26
|
+
f"{main_url}/izle/gizem-filmleri/page/SAYFA" : "Gizem Filmleri",
|
|
27
|
+
f"{main_url}/izle/komedi-filmleri/page/SAYFA" : "Komedi Filmleri",
|
|
28
|
+
f"{main_url}/izle/korku-filmleri/page/SAYFA" : "Korku Filmleri",
|
|
29
|
+
f"{main_url}/izle/macera-filmleri/page/SAYFA" : "Macera Filmleri",
|
|
30
|
+
f"{main_url}/izle/muzikal-filmler/page/SAYFA" : "Müzikal Filmler",
|
|
31
|
+
f"{main_url}/izle/romantik-filmler/page/SAYFA" : "Romantik Filmler",
|
|
32
|
+
f"{main_url}/izle/savas-filmleri/page/SAYFA" : "Savaş Filmleri",
|
|
33
|
+
f"{main_url}/izle/seri-filmler/page/SAYFA" : "Seri Filmler",
|
|
34
|
+
f"{main_url}/izle/spor-filmleri/page/SAYFA" : "Spor Filmleri",
|
|
35
|
+
f"{main_url}/izle/suc-filmleri/page/SAYFA" : "Suç Filmleri",
|
|
36
|
+
f"{main_url}/izle/tarihi-filmler/page/SAYFA" : "Tarih Filmler",
|
|
37
|
+
f"{main_url}/izle/western-filmleri/page/SAYFA" : "Western Filmler",
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
41
|
+
istek = await self.httpx.get(url.replace("SAYFA", str(page)))
|
|
42
|
+
secici = Selector(istek.text)
|
|
43
|
+
|
|
44
|
+
return [
|
|
45
|
+
MainPageResult(
|
|
46
|
+
category = category,
|
|
47
|
+
title = veri.css("div.yanac span::text").get(),
|
|
48
|
+
url = self.fix_url(veri.css("div.yanac a::attr(href)").get()),
|
|
49
|
+
poster = self.fix_url(veri.css("a.resim img::attr(data-src)").get() or veri.css("a.resim img::attr(src)").get()),
|
|
50
|
+
)
|
|
51
|
+
for veri in secici.css("div.son div.frag-k, div.icerik div.frag-k")
|
|
52
|
+
if veri.css("div.yanac span::text").get()
|
|
53
|
+
]
|
|
54
|
+
|
|
55
|
+
async def search(self, query: str) -> list[SearchResult]:
|
|
56
|
+
istek = await self.httpx.get(f"{self.main_url}/?s={query}")
|
|
57
|
+
secici = Selector(istek.text)
|
|
58
|
+
|
|
59
|
+
return [
|
|
60
|
+
SearchResult(
|
|
61
|
+
title = veri.css("div.yanac span::text").get(),
|
|
62
|
+
url = self.fix_url(veri.css("div.yanac a::attr(href)").get()),
|
|
63
|
+
poster = self.fix_url(veri.css("a.resim img::attr(data-src)").get() or veri.css("a.resim img::attr(src)").get()),
|
|
64
|
+
)
|
|
65
|
+
for veri in secici.css("div.icerik div.frag-k")
|
|
66
|
+
if veri.css("div.yanac span::text").get()
|
|
67
|
+
]
|
|
68
|
+
|
|
69
|
+
async def load_item(self, url: str) -> MovieInfo:
|
|
70
|
+
istek = await self.httpx.get(url)
|
|
71
|
+
secici = Selector(istek.text)
|
|
72
|
+
|
|
73
|
+
duration_match = re.search(r"Süre:.*?(\d+)\s*Dakika", istek.text)
|
|
74
|
+
description = secici.css("div.ackl div.scroll-liste::text").get()
|
|
75
|
+
|
|
76
|
+
return MovieInfo(
|
|
77
|
+
url = url,
|
|
78
|
+
poster = self.fix_url(secici.css("link[rel='image_src']::attr(href)").get()),
|
|
79
|
+
title = secici.css("div.f-bilgi h1::text").get(),
|
|
80
|
+
description = description.strip() if description else None,
|
|
81
|
+
tags = [a.css("::text").get() for a in secici.css("div.f-bilgi div.tur a")],
|
|
82
|
+
year = secici.css("div.f-bilgi ul.detay a[href*='yapim']::text").get(),
|
|
83
|
+
actors = [li.css("span.isim::text").get() for li in secici.css("li.oync li.oyuncu-k")],
|
|
84
|
+
duration = int(duration_match[1]) if duration_match else None,
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
async def load_links(self, url: str) -> list[ExtractResult]:
|
|
88
|
+
istek = await self.httpx.get(url)
|
|
89
|
+
secici = Selector(istek.text)
|
|
90
|
+
|
|
91
|
+
iframe_list = [iframe.css("::attr(data-vsrc)").get() for iframe in secici.css("iframe")]
|
|
92
|
+
iframe_list = [i for i in iframe_list if i]
|
|
93
|
+
|
|
94
|
+
# Sadece fragman varsa /2/ sayfasından dene
|
|
95
|
+
has_only_trailer = all(
|
|
96
|
+
"youtube" in (i or "").lower() or "fragman" in (i or "").lower() or "trailer" in (i or "").lower()
|
|
97
|
+
for i in iframe_list
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
if has_only_trailer:
|
|
101
|
+
alt_url = url.rstrip("/") + "/2/"
|
|
102
|
+
alt_istek = await self.httpx.get(alt_url)
|
|
103
|
+
alt_sec = Selector(alt_istek.text)
|
|
104
|
+
iframe_list = [iframe.css("::attr(data-vsrc)").get() for iframe in alt_sec.css("iframe")]
|
|
105
|
+
iframe_list = [i for i in iframe_list if i]
|
|
106
|
+
|
|
107
|
+
if not iframe_list:
|
|
108
|
+
return []
|
|
109
|
+
|
|
110
|
+
iframe = self.fix_url(iframe_list[0].split("?img=")[0])
|
|
111
|
+
if not iframe:
|
|
112
|
+
return []
|
|
113
|
+
|
|
114
|
+
results = []
|
|
115
|
+
|
|
116
|
+
# Altyazı kontrolü
|
|
117
|
+
self.httpx.headers.update({"Referer": f"{self.main_url}/"})
|
|
118
|
+
iframe_istek = await self.httpx.get(iframe)
|
|
119
|
+
iframe_text = iframe_istek.text
|
|
120
|
+
|
|
121
|
+
subtitles = []
|
|
122
|
+
sub_match = re.search(r'playerjsSubtitle\s*=\s*"(.+?)"', iframe_text)
|
|
123
|
+
if sub_match:
|
|
124
|
+
sub_section = sub_match[1]
|
|
125
|
+
for sub in re.finditer(r'\[(.*?)](https?://[^\s",]+)', sub_section):
|
|
126
|
+
subtitles.append(Subtitle(name=sub[1], url=self.fix_url(sub[2])))
|
|
127
|
+
|
|
128
|
+
# player.filmizle.in kontrolü
|
|
129
|
+
if "player.filmizle.in" in iframe.lower():
|
|
130
|
+
base_match = re.search(r"https?://([^/]+)", iframe)
|
|
131
|
+
if base_match:
|
|
132
|
+
base_url = base_match[1]
|
|
133
|
+
vid_id = iframe.split("/")[-1]
|
|
134
|
+
|
|
135
|
+
self.httpx.headers.update({"X-Requested-With": "XMLHttpRequest"})
|
|
136
|
+
vid_istek = await self.httpx.post(
|
|
137
|
+
f"https://{base_url}/player/index.php?data={vid_id}&do=getVideo",
|
|
138
|
+
)
|
|
139
|
+
vid_data = vid_istek.json()
|
|
140
|
+
|
|
141
|
+
if vid_data.get("securedLink"):
|
|
142
|
+
results.append(ExtractResult(
|
|
143
|
+
name = f"{self.name}",
|
|
144
|
+
url = vid_data["securedLink"],
|
|
145
|
+
referer = iframe,
|
|
146
|
+
subtitles = subtitles
|
|
147
|
+
))
|
|
148
|
+
else:
|
|
149
|
+
# Extractor'a yönlendir
|
|
150
|
+
data = await self.extract(iframe)
|
|
151
|
+
if data:
|
|
152
|
+
results.append(data)
|
|
153
|
+
|
|
154
|
+
return results
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
|
+
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, ExtractResult
|
|
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[ExtractResult]:
|
|
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
|
+
data = await self.extract(iframe)
|
|
138
|
+
if data:
|
|
139
|
+
return [data]
|
|
140
|
+
except Exception:
|
|
141
|
+
pass
|
|
142
|
+
|
|
143
|
+
return []
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
|
+
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, ExtractResult
|
|
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 = "Hd film izliyerek arkadaşlarınızla ve sevdiklerinizle iyi bir vakit geçirmek istiyorsanız açın bir film eğlenmeye bakın. Bilim kurgu filmleri, aşk drama vahşet aşk romantik sıradışı korku filmlerini izle."
|
|
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/biyografi/page/SAYFA" : "Biyografi",
|
|
20
|
+
f"{main_url}/hdizle/category/bilim-kurgu/page/SAYFA" : "Bilim Kurgu",
|
|
21
|
+
f"{main_url}/hdizle/category/fantastik/page/SAYFA" : "Fantastik",
|
|
22
|
+
f"{main_url}/hdizle/category/dram/page/SAYFA" : "Dram",
|
|
23
|
+
f"{main_url}/hdizle/category/gerilim/page/SAYFA" : "Gerilim",
|
|
24
|
+
f"{main_url}/hdizle/category/gizem/page/SAYFA" : "Gizem",
|
|
25
|
+
f"{main_url}/hdizle/category/komedi-filmleri/page/SAYFA" : "Komedi Filmleri",
|
|
26
|
+
f"{main_url}/hdizle/category/karete-filmleri/page/SAYFA" : "Karate Filmleri",
|
|
27
|
+
f"{main_url}/hdizle/category/korku/page/SAYFA" : "Korku",
|
|
28
|
+
f"{main_url}/hdizle/category/muzik/page/SAYFA" : "Müzik",
|
|
29
|
+
f"{main_url}/hdizle/category/macera/page/SAYFA" : "Macera",
|
|
30
|
+
f"{main_url}/hdizle/category/romantik/page/SAYFA" : "Romantik",
|
|
31
|
+
f"{main_url}/hdizle/category/spor/page/SAYFA" : "Spor",
|
|
32
|
+
f"{main_url}/hdizle/category/savas/page/SAYFA" : "Savaş",
|
|
33
|
+
f"{main_url}/hdizle/category/suc/page/SAYFA" : "Suç",
|
|
34
|
+
f"{main_url}/hdizle/category/western/page/SAYFA" : "Western",
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
38
|
+
istek = await self.httpx.get(url.replace("SAYFA", str(page)))
|
|
39
|
+
secici = Selector(istek.text)
|
|
40
|
+
|
|
41
|
+
return [
|
|
42
|
+
MainPageResult(
|
|
43
|
+
category = category,
|
|
44
|
+
title = self.clean_title(veri.css("span.movie-title a::text").get().split(" izle")[0]),
|
|
45
|
+
url = self.fix_url(veri.css("span.movie-title a::attr(href)").get()),
|
|
46
|
+
poster = self.fix_url(veri.css("img::attr(src)").get()),
|
|
47
|
+
)
|
|
48
|
+
for veri in secici.css("div.movie-preview-content")
|
|
49
|
+
if veri.css("span.movie-title a::text").get()
|
|
50
|
+
]
|
|
51
|
+
|
|
52
|
+
async def search(self, query: str) -> list[SearchResult]:
|
|
53
|
+
istek = await self.httpx.get(f"{self.main_url}?s={query}")
|
|
54
|
+
secici = Selector(istek.text)
|
|
55
|
+
|
|
56
|
+
return [
|
|
57
|
+
SearchResult(
|
|
58
|
+
title = self.clean_title(veri.css("span.movie-title a::text").get().split(" izle")[0]),
|
|
59
|
+
url = self.fix_url(veri.css("span.movie-title a::attr(href)").get()),
|
|
60
|
+
poster = self.fix_url(veri.css("img::attr(src)").get()),
|
|
61
|
+
)
|
|
62
|
+
for veri in secici.css("div.movie-preview-content")
|
|
63
|
+
if veri.css("span.movie-title a::text").get()
|
|
64
|
+
]
|
|
65
|
+
|
|
66
|
+
async def load_item(self, url: str) -> MovieInfo:
|
|
67
|
+
istek = await self.httpx.get(url)
|
|
68
|
+
secici = Selector(istek.text)
|
|
69
|
+
|
|
70
|
+
title = secici.css("div.title h1::text").get()
|
|
71
|
+
title = self.clean_title(title.split(" izle")[0]) if title else ""
|
|
72
|
+
poster = self.fix_url(secici.css("div.poster img::attr(src)").get())
|
|
73
|
+
year = secici.css("div.release a::text").re_first(r"(\d{4})")
|
|
74
|
+
description = secici.css("div.excerpt p::text").get()
|
|
75
|
+
tags = secici.css("div.categories a::text").getall()
|
|
76
|
+
actors = secici.css("div.actor a::text").getall()
|
|
77
|
+
|
|
78
|
+
return MovieInfo(
|
|
79
|
+
url = url,
|
|
80
|
+
poster = poster,
|
|
81
|
+
title = title,
|
|
82
|
+
description = description,
|
|
83
|
+
tags = tags,
|
|
84
|
+
year = year,
|
|
85
|
+
actors = actors,
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
async def load_links(self, url: str) -> list[ExtractResult]:
|
|
89
|
+
from KekikStream.Core import ExtractResult
|
|
90
|
+
|
|
91
|
+
istek = await self.httpx.get(url)
|
|
92
|
+
secici = Selector(istek.text)
|
|
93
|
+
|
|
94
|
+
iframe = self.fix_url(secici.css("div#vast iframe::attr(src)").get())
|
|
95
|
+
if not iframe:
|
|
96
|
+
return []
|
|
97
|
+
|
|
98
|
+
results = []
|
|
99
|
+
|
|
100
|
+
# Mix player özel işleme
|
|
101
|
+
if "mix" in iframe and "index.php?data=" in iframe:
|
|
102
|
+
iframe_istek = await self.httpx.get(iframe, headers={"Referer": f"{self.main_url}/"})
|
|
103
|
+
mix_point = re.search(r'videoUrl"\s*:\s*"(.*?)"\s*,\s*"videoServer', iframe_istek.text)
|
|
104
|
+
|
|
105
|
+
if mix_point:
|
|
106
|
+
mix_point = mix_point[1].replace("\\", "")
|
|
107
|
+
|
|
108
|
+
# Endpoint belirleme
|
|
109
|
+
if "mixlion" in iframe:
|
|
110
|
+
end_point = "?s=3&d="
|
|
111
|
+
elif "mixeagle" in iframe:
|
|
112
|
+
end_point = "?s=1&d="
|
|
113
|
+
else:
|
|
114
|
+
end_point = "?s=0&d="
|
|
115
|
+
|
|
116
|
+
m3u_link = iframe.split("/player")[0] + mix_point + end_point
|
|
117
|
+
|
|
118
|
+
results.append(ExtractResult(
|
|
119
|
+
name = f"{self.name} | Mix Player",
|
|
120
|
+
url = m3u_link,
|
|
121
|
+
referer = iframe,
|
|
122
|
+
subtitles = []
|
|
123
|
+
))
|
|
124
|
+
else:
|
|
125
|
+
# Extractor'a yönlendir
|
|
126
|
+
data = await self.extract(iframe)
|
|
127
|
+
if data:
|
|
128
|
+
results.append(data)
|
|
129
|
+
|
|
130
|
+
return results
|