KekikStream 2.4.2__py3-none-any.whl → 2.4.4__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 +3 -2
- KekikStream/Core/HTMLHelper.py +134 -40
- KekikStream/Core/Plugin/PluginBase.py +3 -2
- KekikStream/Extractors/CloseLoad.py +30 -54
- KekikStream/Extractors/ContentX.py +27 -72
- KekikStream/Extractors/DonilasPlay.py +33 -77
- KekikStream/Extractors/DzenRu.py +10 -24
- KekikStream/Extractors/ExPlay.py +20 -38
- KekikStream/Extractors/Filemoon.py +19 -45
- KekikStream/Extractors/HDMomPlayer.py +24 -56
- KekikStream/Extractors/HDPlayerSystem.py +13 -31
- KekikStream/Extractors/HotStream.py +14 -32
- KekikStream/Extractors/JFVid.py +3 -24
- KekikStream/Extractors/JetTv.py +21 -34
- KekikStream/Extractors/MailRu.py +11 -29
- KekikStream/Extractors/MixPlayHD.py +15 -28
- KekikStream/Extractors/MixTiger.py +17 -40
- KekikStream/Extractors/MolyStream.py +17 -21
- KekikStream/Extractors/Odnoklassniki.py +28 -104
- KekikStream/Extractors/PeaceMakerst.py +18 -45
- KekikStream/Extractors/PixelDrain.py +8 -16
- KekikStream/Extractors/PlayerFilmIzle.py +22 -41
- KekikStream/Extractors/RapidVid.py +21 -35
- KekikStream/Extractors/SetPlay.py +18 -43
- KekikStream/Extractors/SibNet.py +7 -17
- KekikStream/Extractors/Sobreatsesuyp.py +23 -45
- KekikStream/Extractors/TRsTX.py +23 -53
- KekikStream/Extractors/TurboImgz.py +7 -14
- KekikStream/Extractors/VCTPlay.py +10 -28
- KekikStream/Extractors/VidHide.py +10 -31
- KekikStream/Extractors/VidMoly.py +65 -99
- KekikStream/Extractors/VidMoxy.py +16 -27
- KekikStream/Extractors/VidPapi.py +24 -54
- KekikStream/Extractors/VideoSeyred.py +19 -40
- KekikStream/Extractors/Videostr.py +42 -99
- KekikStream/Extractors/Vidoza.py +8 -15
- KekikStream/Extractors/YildizKisaFilm.py +13 -31
- KekikStream/Plugins/BelgeselX.py +63 -69
- KekikStream/Plugins/DiziBox.py +16 -36
- KekikStream/Plugins/DiziMom.py +37 -129
- KekikStream/Plugins/DiziPal.py +71 -164
- KekikStream/Plugins/DiziYou.py +44 -152
- KekikStream/Plugins/Dizilla.py +18 -44
- KekikStream/Plugins/FilmBip.py +10 -24
- KekikStream/Plugins/FilmEkseni.py +12 -32
- KekikStream/Plugins/FilmMakinesi.py +24 -77
- KekikStream/Plugins/FilmModu.py +11 -18
- KekikStream/Plugins/Filmatek.py +13 -39
- KekikStream/Plugins/Full4kizle.py +33 -133
- KekikStream/Plugins/FullHDFilm.py +23 -93
- KekikStream/Plugins/FullHDFilmizlesene.py +10 -29
- KekikStream/Plugins/HDFilmCehennemi.py +27 -66
- KekikStream/Plugins/JetFilmizle.py +19 -20
- KekikStream/Plugins/KultFilmler.py +16 -50
- KekikStream/Plugins/RecTV.py +47 -85
- KekikStream/Plugins/SelcukFlix.py +29 -47
- KekikStream/Plugins/SetFilmIzle.py +28 -84
- KekikStream/Plugins/SezonlukDizi.py +27 -59
- KekikStream/Plugins/Sinefy.py +37 -100
- KekikStream/Plugins/SinemaCX.py +12 -18
- KekikStream/Plugins/Sinezy.py +11 -12
- KekikStream/Plugins/SuperFilmGeldi.py +8 -13
- KekikStream/Plugins/UgurFilm.py +14 -14
- KekikStream/Plugins/Watch32.py +42 -74
- KekikStream/Plugins/YabanciDizi.py +33 -87
- {kekikstream-2.4.2.dist-info → kekikstream-2.4.4.dist-info}/METADATA +1 -1
- kekikstream-2.4.4.dist-info/RECORD +93 -0
- kekikstream-2.4.2.dist-info/RECORD +0 -93
- {kekikstream-2.4.2.dist-info → kekikstream-2.4.4.dist-info}/WHEEL +0 -0
- {kekikstream-2.4.2.dist-info → kekikstream-2.4.4.dist-info}/entry_points.txt +0 -0
- {kekikstream-2.4.2.dist-info → kekikstream-2.4.4.dist-info}/licenses/LICENSE +0 -0
- {kekikstream-2.4.2.dist-info → kekikstream-2.4.4.dist-info}/top_level.txt +0 -0
|
@@ -98,151 +98,51 @@ class Full4kizle(PluginBase):
|
|
|
98
98
|
async def load_item(self, url: str) -> MovieInfo | SeriesInfo:
|
|
99
99
|
istek = await self.httpx.get(url)
|
|
100
100
|
helper = HTMLHelper(istek.text)
|
|
101
|
-
|
|
102
|
-
title_raw = helper.select_text("h1") or "Bilinmiyor"
|
|
103
|
-
title = re.sub(r"(?i)izle", "", title_raw).strip()
|
|
104
|
-
|
|
105
|
-
poster_el = helper.select_first(".poster img")
|
|
106
|
-
poster = self.fix_url(poster_el.attrs.get("src")) if poster_el else None
|
|
107
|
-
|
|
108
|
-
description = helper.select_text(".excerpt p")
|
|
109
|
-
|
|
110
|
-
# Robust metadata extraction using Regex
|
|
111
|
-
|
|
112
|
-
# Initialize year first
|
|
113
|
-
year = None
|
|
114
|
-
|
|
115
|
-
# Try .release first (legacy) or directly regex
|
|
116
|
-
rel_text = helper.select_text(".release")
|
|
117
|
-
if rel_text:
|
|
118
|
-
m_y = re.search(r"(\d{4})", rel_text)
|
|
119
|
-
if m_y: year = m_y.group(1)
|
|
120
|
-
|
|
121
|
-
# Year fallbacks
|
|
122
|
-
if not year:
|
|
123
|
-
# Try finding year in text like "Yapım: 2024" or just isolated year in release date
|
|
124
|
-
m_year = helper.regex_first(r"Yapım:\s*(\d{4})") or helper.regex_first(r"Yıl:\s*(\d{4})")
|
|
125
|
-
if m_year:
|
|
126
|
-
year = m_year
|
|
127
|
-
|
|
128
|
-
# Rating
|
|
129
|
-
rating_text = helper.select_text(".imdb-rating")
|
|
130
|
-
if rating_text:
|
|
131
|
-
rating = rating_text.replace("IMDB Puanı", "").strip()
|
|
132
|
-
else:
|
|
133
|
-
rating = helper.regex_first(r"IMDB\s*:\s*([\d\.]+)")
|
|
134
|
-
|
|
135
|
-
# Duration
|
|
136
|
-
duration = None
|
|
137
|
-
duration_val = helper.regex_first(r"Süre:\s*(\d+)")
|
|
138
|
-
if duration_val:
|
|
139
|
-
duration = int(duration_val)
|
|
140
101
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
# Fallback: Try .cast-list selector
|
|
151
|
-
if not actors_list:
|
|
152
|
-
actor_els = helper.select(".cast-list .actor-name, .cast-list a")
|
|
153
|
-
if actor_els:
|
|
154
|
-
actors_list = [el.text(strip=True) for el in actor_els if el.text(strip=True)]
|
|
155
|
-
|
|
156
|
-
if actors_list:
|
|
157
|
-
actors = ", ".join(actors_list)
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
# Tags (Genres) - Extract from genre links
|
|
161
|
-
tags = None
|
|
162
|
-
tags_list = []
|
|
163
|
-
|
|
164
|
-
# Site uses: <a href=".../tur/...">Genre Name</a> or <a href=".../Kategori/tur/...">
|
|
165
|
-
tag_els = helper.select("a[href*='/tur/'], a[href*='/Kategori/tur/']")
|
|
166
|
-
if tag_els:
|
|
167
|
-
tags_list = [el.text(strip=True) for el in tag_els if el.text(strip=True)]
|
|
168
|
-
|
|
169
|
-
# Fallback: Try .genres selector
|
|
170
|
-
if not tags_list:
|
|
171
|
-
tag_els = helper.select(".genres a, .genre a")
|
|
172
|
-
if tag_els:
|
|
173
|
-
tags_list = [el.text(strip=True) for el in tag_els if el.text(strip=True)]
|
|
174
|
-
|
|
175
|
-
# Remove duplicates while preserving order
|
|
176
|
-
if tags_list:
|
|
177
|
-
seen = set()
|
|
178
|
-
unique_tags = []
|
|
179
|
-
for tag in tags_list:
|
|
180
|
-
if tag not in seen:
|
|
181
|
-
seen.add(tag)
|
|
182
|
-
unique_tags.append(tag)
|
|
183
|
-
tags = unique_tags if unique_tags else None
|
|
102
|
+
title = self.clean_title(helper.select_text("h1"))
|
|
103
|
+
poster = helper.select_poster(".poster img")
|
|
104
|
+
description = helper.select_text(".excerpt p")
|
|
105
|
+
year = helper.extract_year(".release", ".movie-info")
|
|
106
|
+
rating = helper.regex_first(r"([\d\.]+)", helper.select_text(".imdb-rating"))
|
|
107
|
+
duration = int(helper.regex_first(r"(\d+)", helper.select_text(".movie-info")) or 0)
|
|
108
|
+
tags = helper.select_texts("a[href*='/tur/'], a[href*='/Kategori/tur/']")
|
|
109
|
+
actors = helper.select_texts("a[href*='/oyuncular/']") or helper.select_texts(".cast-list .actor-name, .cast-list a")
|
|
184
110
|
|
|
185
|
-
|
|
186
|
-
# Check for Episodes to decide if Series or Movie
|
|
111
|
+
# Bölüm linklerini kontrol et
|
|
187
112
|
ep_elements = helper.select(".parts-middle a, .parts-middle .part.active")
|
|
188
|
-
|
|
113
|
+
|
|
189
114
|
if not ep_elements:
|
|
190
|
-
# Movie
|
|
191
115
|
return MovieInfo(
|
|
192
116
|
url = url,
|
|
193
|
-
title = title,
|
|
117
|
+
title = title or "Bilinmiyor",
|
|
194
118
|
description = description,
|
|
195
|
-
poster = poster,
|
|
196
|
-
year = year,
|
|
119
|
+
poster = self.fix_url(poster) if poster else None,
|
|
120
|
+
year = str(year) if year else None,
|
|
197
121
|
rating = rating,
|
|
198
122
|
duration = duration,
|
|
199
123
|
tags = tags,
|
|
200
124
|
actors = actors
|
|
201
125
|
)
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
if s_match:
|
|
223
|
-
season = int(s_match.group(1))
|
|
224
|
-
if e_match:
|
|
225
|
-
episode = int(e_match.group(1))
|
|
226
|
-
|
|
227
|
-
episodes.append(Episode(
|
|
228
|
-
season = season,
|
|
229
|
-
episode = episode,
|
|
230
|
-
title = ep_name,
|
|
231
|
-
url = ep_href
|
|
232
|
-
))
|
|
233
|
-
|
|
234
|
-
return SeriesInfo(
|
|
235
|
-
url = url,
|
|
236
|
-
title = title,
|
|
237
|
-
description = description,
|
|
238
|
-
poster = poster,
|
|
239
|
-
year = year,
|
|
240
|
-
rating = rating,
|
|
241
|
-
duration = duration,
|
|
242
|
-
tags = tags,
|
|
243
|
-
actors = actors,
|
|
244
|
-
episodes = episodes
|
|
245
|
-
)
|
|
126
|
+
|
|
127
|
+
episodes = []
|
|
128
|
+
for i, el in enumerate(ep_elements):
|
|
129
|
+
name = helper.select_text(".part-name", el) or f"Bölüm {i+1}"
|
|
130
|
+
href = el.attrs.get("href") or url
|
|
131
|
+
s, e = helper.extract_season_episode(name)
|
|
132
|
+
episodes.append(Episode(season=s or 1, episode=e or (i + 1), title=name, url=self.fix_url(href)))
|
|
133
|
+
|
|
134
|
+
return SeriesInfo(
|
|
135
|
+
url = url,
|
|
136
|
+
title = title or "Bilinmiyor",
|
|
137
|
+
description = description,
|
|
138
|
+
poster = self.fix_url(poster) if poster else None,
|
|
139
|
+
year = str(year) if year else None,
|
|
140
|
+
rating = rating,
|
|
141
|
+
duration = duration,
|
|
142
|
+
tags = tags,
|
|
143
|
+
actors = actors,
|
|
144
|
+
episodes = episodes
|
|
145
|
+
)
|
|
246
146
|
|
|
247
147
|
async def load_links(self, url: str) -> list[ExtractResult]:
|
|
248
148
|
istek = await self.httpx.get(url)
|
|
@@ -87,108 +87,38 @@ class FullHDFilm(PluginBase):
|
|
|
87
87
|
async def load_item(self, url: str) -> MovieInfo | SeriesInfo:
|
|
88
88
|
istek = await self.httpx.get(url)
|
|
89
89
|
secici = HTMLHelper(istek.text)
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
actors
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
actors_text = actors_text.replace("Oyuncular:", "").strip()
|
|
101
|
-
actors = [a.strip() for a in actors_text.split(",")]
|
|
102
|
-
|
|
103
|
-
# Year: önce div.yayin-tarihi.info dene
|
|
104
|
-
year = secici.extract_year("div.yayin-tarihi.info")
|
|
105
|
-
|
|
106
|
-
# Fallback: h1'in parent'ından (2019) formatında ara
|
|
107
|
-
if not year:
|
|
108
|
-
# Parent'ın tüm text içeriğinden yıl çıkar
|
|
109
|
-
title_text = secici.select_text("h1")
|
|
110
|
-
if title_text:
|
|
111
|
-
# h1 parent'ındaki (2019) gibi text'i bul
|
|
112
|
-
year = secici.regex_first(r"\((\d{4})\)")
|
|
113
|
-
|
|
114
|
-
tags = secici.select_all_text("div.tur.info a")
|
|
115
|
-
|
|
116
|
-
# Rating: regex
|
|
117
|
-
rating_text = secici.select_text("div.imdb") or ""
|
|
118
|
-
rating = HTMLHelper(rating_text).regex_first(r"IMDb\s*([\d\.]+)")
|
|
119
|
-
|
|
120
|
-
# Description: önce div.film dene, yoksa og:description meta tag'ını kullan
|
|
121
|
-
description = secici.select_text("div.film")
|
|
122
|
-
|
|
123
|
-
# Fallback: og:description meta tag'ı
|
|
124
|
-
if not description:
|
|
125
|
-
og_desc = secici.select_attr("meta[property='og:description']", "content")
|
|
126
|
-
if og_desc:
|
|
127
|
-
description = og_desc
|
|
128
|
-
|
|
129
|
-
# Kotlin referansı: URL'de -dizi kontrolü veya tags içinde "dizi" kontrolü
|
|
90
|
+
|
|
91
|
+
title = self.clean_title(secici.select_text("h1"))
|
|
92
|
+
poster = secici.select_poster("div.poster img")
|
|
93
|
+
description = secici.select_text("div.film") or secici.select_attr("meta[property='og:description']", "content")
|
|
94
|
+
year = secici.extract_year("div.yayin-tarihi.info") or secici.regex_first(r"\((\d{4})\)")
|
|
95
|
+
tags = secici.select_texts("div.tur.info a")
|
|
96
|
+
rating = secici.regex_first(r"IMDb\s*([\d\.]+)", secici.select_text("div.imdb"))
|
|
97
|
+
actors = secici.select_direct_text("div.oyuncular")
|
|
98
|
+
|
|
99
|
+
# Kotlin referansı: URL'de -dizi veya tags içinde dizi kontrolü
|
|
130
100
|
is_series = "-dizi" in url.lower() or any("dizi" in tag.lower() for tag in tags)
|
|
131
101
|
|
|
132
102
|
if is_series:
|
|
133
103
|
episodes = []
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
for idx, el in enumerate(part_elements):
|
|
140
|
-
part_id = el.attrs.get("id")
|
|
141
|
-
part_name = secici.select_text("a", el)
|
|
142
|
-
|
|
143
|
-
if not part_name:
|
|
144
|
-
continue
|
|
145
|
-
|
|
146
|
-
# Fragman'ları atla
|
|
147
|
-
if "fragman" in part_name.lower() or (part_id and "fragman" in part_id.lower()):
|
|
148
|
-
continue
|
|
104
|
+
for idx, el in enumerate(secici.select("li.psec")):
|
|
105
|
+
part_id = el.attrs.get("id")
|
|
106
|
+
part_name = secici.select_text("a", el) or ""
|
|
107
|
+
if not part_name or "fragman" in part_name.lower(): continue
|
|
149
108
|
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
ep_val = HTMLHelper(part_name).regex_first(r'^(\d+)\.')
|
|
153
|
-
|
|
154
|
-
sz_num = int(sz_val) if sz_val and sz_val.isdigit() else 1
|
|
155
|
-
ep_num = int(ep_val) if ep_val and ep_val.isdigit() else idx + 1
|
|
156
|
-
|
|
157
|
-
# pdata'dan video URL'si çık (varsa)
|
|
158
|
-
video_url = url # Varsayılan olarak ana URL kullan
|
|
159
|
-
if idx < len(pdata_matches):
|
|
160
|
-
video_url = pdata_matches[idx][1] if pdata_matches[idx][1] else url
|
|
161
|
-
|
|
162
|
-
episodes.append(Episode(
|
|
163
|
-
season = sz_num,
|
|
164
|
-
episode = ep_num,
|
|
165
|
-
title = f"{sz_num}. Sezon {ep_num}. Bölüm",
|
|
166
|
-
url = url # Bölüm URL'leri load_links'te işlenecek
|
|
167
|
-
))
|
|
109
|
+
s, e = secici.extract_season_episode(f"{part_id} {part_name}")
|
|
110
|
+
episodes.append(Episode(season=s or 1, episode=e or (idx+1), title=f"{s or 1}. Sezon {e or idx+1}. Bölüm", url=url))
|
|
168
111
|
|
|
169
112
|
return SeriesInfo(
|
|
170
|
-
url
|
|
171
|
-
|
|
172
|
-
title = self.clean_title(title) if title else "",
|
|
173
|
-
description = description,
|
|
174
|
-
tags = tags,
|
|
175
|
-
year = year,
|
|
176
|
-
actors = actors,
|
|
177
|
-
rating = rating,
|
|
178
|
-
episodes = episodes
|
|
179
|
-
)
|
|
180
|
-
else:
|
|
181
|
-
return MovieInfo(
|
|
182
|
-
url = url,
|
|
183
|
-
poster = poster,
|
|
184
|
-
title = self.clean_title(title) if title else "",
|
|
185
|
-
description = description,
|
|
186
|
-
tags = tags,
|
|
187
|
-
year = year,
|
|
188
|
-
actors = actors,
|
|
189
|
-
rating = rating,
|
|
113
|
+
url=url, poster=self.fix_url(poster) if poster else None, title=title or "", description=description,
|
|
114
|
+
tags=tags, year=str(year) if year else None, actors=actors, rating=rating, episodes=episodes
|
|
190
115
|
)
|
|
191
116
|
|
|
117
|
+
return MovieInfo(
|
|
118
|
+
url=url, poster=self.fix_url(poster) if poster else None, title=title or "", description=description,
|
|
119
|
+
tags=tags, year=str(year) if year else None, actors=actors, rating=rating
|
|
120
|
+
)
|
|
121
|
+
|
|
192
122
|
def _get_iframe(self, source_code: str) -> str:
|
|
193
123
|
"""Base64 kodlu iframe'i çözümle"""
|
|
194
124
|
script_val = HTMLHelper(source_code).regex_first(r'<script[^>]*>(PCEtLWJhc2xpazp[^<]*)</script>')
|
|
@@ -81,43 +81,24 @@ class FullHDFilmizlesene(PluginBase):
|
|
|
81
81
|
async def load_item(self, url: str) -> MovieInfo:
|
|
82
82
|
istek = await self.httpx.get(url)
|
|
83
83
|
secici = HTMLHelper(istek.text)
|
|
84
|
-
html_text = istek.text
|
|
85
|
-
|
|
86
|
-
# Title: normalize-space yerine doğrudan class ile
|
|
87
|
-
title = secici.select_text("div.izle-titles") or ""
|
|
88
|
-
|
|
89
|
-
poster = secici.select_attr("div img[data-src]", "data-src") or ""
|
|
90
|
-
poster = poster.strip()
|
|
91
|
-
|
|
92
|
-
description = secici.select_text("div.ozet-ic p") or ""
|
|
93
|
-
|
|
94
|
-
tags = secici.select_all_text("a[rel='category tag']")
|
|
95
|
-
|
|
96
|
-
# Rating: regex ile sayısal değeri yakala
|
|
97
|
-
rating_text = secici.select_text("div.puanx-puan") or ""
|
|
98
|
-
rating = secici.regex_first(r"(\d+\.\d+|\d+)", rating_text)
|
|
99
|
-
|
|
100
|
-
# Year: ilk yıl formatında değer
|
|
101
|
-
year_text = secici.select_text("div.dd a.category") or ""
|
|
102
|
-
year = secici.regex_first(r"(\d{4})", year_text)
|
|
103
|
-
|
|
104
|
-
# Actors: nth-child yerine tüm li'leri alıp 2. index
|
|
105
|
-
lis = secici.select("div.film-info ul li")
|
|
106
|
-
actors = []
|
|
107
|
-
if len(lis) >= 2:
|
|
108
|
-
actors = secici.select_all_text("a > span", lis[1])
|
|
109
84
|
|
|
110
|
-
|
|
111
|
-
|
|
85
|
+
title = self.clean_title(secici.select_text("div.izle-titles"))
|
|
86
|
+
poster = secici.select_poster("div img[data-src]")
|
|
87
|
+
description = secici.select_text("div.ozet-ic p")
|
|
88
|
+
tags = secici.select_texts("a[rel='category tag']")
|
|
89
|
+
rating = secici.regex_first(r"(\d+\.\d+|\d+)", secici.select_text("div.puanx-puan"))
|
|
90
|
+
year = secici.extract_year("div.dd a.category")
|
|
91
|
+
actors = secici.select_texts("a > span", secici.select_first("div.film-info ul li:nth-child(2)"))
|
|
92
|
+
duration = int(secici.regex_first(r"(\d+)", secici.select_text("div.film-info ul li:nth-child(4)")) or 0)
|
|
112
93
|
|
|
113
94
|
return MovieInfo(
|
|
114
95
|
url = url,
|
|
115
96
|
poster = self.fix_url(poster) if poster else None,
|
|
116
|
-
title = title,
|
|
97
|
+
title = title or "Bilinmiyor",
|
|
117
98
|
description = description,
|
|
118
99
|
tags = tags,
|
|
119
100
|
rating = rating,
|
|
120
|
-
year = year,
|
|
101
|
+
year = str(year) if year else None,
|
|
121
102
|
actors = actors,
|
|
122
103
|
duration = duration
|
|
123
104
|
)
|
|
@@ -78,77 +78,38 @@ class HDFilmCehennemi(PluginBase):
|
|
|
78
78
|
istek = await self.httpx.get(url, headers = {"Referer": f"{self.main_url}/"})
|
|
79
79
|
secici = HTMLHelper(istek.text)
|
|
80
80
|
|
|
81
|
-
title
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
duration_str = secici.select_text("div.post-info-duration") or "0"
|
|
97
|
-
duration_str = duration_str.replace("dakika", "").strip()
|
|
98
|
-
|
|
99
|
-
try:
|
|
100
|
-
duration_val = HTMLHelper(duration_str).regex_first(r'\d+')
|
|
101
|
-
duration_minutes = int(duration_val) if duration_val else 0
|
|
102
|
-
except Exception:
|
|
103
|
-
duration_minutes = 0
|
|
104
|
-
|
|
105
|
-
# Dizi mi film mi kontrol et (Kotlin referansı: div.seasons kontrolü)
|
|
106
|
-
is_series = len(secici.select("div.seasons")) > 0
|
|
107
|
-
|
|
108
|
-
if is_series:
|
|
81
|
+
title = self.clean_title(secici.select_text("h1.section-title"))
|
|
82
|
+
poster = secici.select_poster("aside.post-info-poster img.lazyload")
|
|
83
|
+
description = secici.select_text("article.post-info-content > p")
|
|
84
|
+
tags = secici.select_texts("div.post-info-genres a")
|
|
85
|
+
rating = secici.select_text("div.post-info-imdb-rating span")
|
|
86
|
+
rating = rating.split("(")[0] if rating else None
|
|
87
|
+
year = secici.select_text("div.post-info-year-country a")
|
|
88
|
+
actors = secici.select_texts("div.post-info-cast a > strong")
|
|
89
|
+
duration = int(secici.regex_first(r"(\d+)", secici.select_text("div.post-info-duration")) or 0)
|
|
90
|
+
|
|
91
|
+
# Dizi mi film mi kontrol et
|
|
92
|
+
ep_links = secici.select("div.seasons-tab-content a")
|
|
93
|
+
|
|
94
|
+
if ep_links:
|
|
109
95
|
episodes = []
|
|
110
|
-
for ep in
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
ep_val = HTMLHelper(ep_name).regex_first(r'(\d+)\.\s*Bölüm')
|
|
117
|
-
sz_val = HTMLHelper(ep_name).regex_first(r'(\d+)\.\s*Sezon')
|
|
118
|
-
ep_num = int(ep_val) if ep_val and ep_val.isdigit() else 1
|
|
119
|
-
sz_num = int(sz_val) if sz_val and sz_val.isdigit() else 1
|
|
120
|
-
|
|
121
|
-
episodes.append(Episode(
|
|
122
|
-
season = sz_num,
|
|
123
|
-
episode = ep_num,
|
|
124
|
-
title = ep_name,
|
|
125
|
-
url = self.fix_url(ep_href)
|
|
126
|
-
))
|
|
96
|
+
for ep in ep_links:
|
|
97
|
+
name = secici.select_text("h4", ep)
|
|
98
|
+
href = ep.attrs.get("href")
|
|
99
|
+
if name and href:
|
|
100
|
+
s, e = secici.extract_season_episode(name)
|
|
101
|
+
episodes.append(Episode(season=s or 1, episode=e or 1, title=name, url=self.fix_url(href)))
|
|
127
102
|
|
|
128
103
|
return SeriesInfo(
|
|
129
|
-
url
|
|
130
|
-
|
|
131
|
-
title = self.clean_title(title),
|
|
132
|
-
description = description,
|
|
133
|
-
tags = tags,
|
|
134
|
-
rating = rating,
|
|
135
|
-
year = year,
|
|
136
|
-
actors = actors,
|
|
137
|
-
episodes = episodes
|
|
138
|
-
)
|
|
139
|
-
else:
|
|
140
|
-
return MovieInfo(
|
|
141
|
-
url = url,
|
|
142
|
-
poster = self.fix_url(poster) if poster else None,
|
|
143
|
-
title = self.clean_title(title),
|
|
144
|
-
description = description,
|
|
145
|
-
tags = tags,
|
|
146
|
-
rating = rating,
|
|
147
|
-
year = year,
|
|
148
|
-
actors = actors,
|
|
149
|
-
duration = duration_minutes
|
|
104
|
+
url=url, poster=self.fix_url(poster) if poster else None, title=title or "Bilinmiyor",
|
|
105
|
+
description=description, tags=tags, rating=rating, year=year, actors=actors, episodes=episodes
|
|
150
106
|
)
|
|
151
107
|
|
|
108
|
+
return MovieInfo(
|
|
109
|
+
url=url, poster=self.fix_url(poster) if poster else None, title=title or "Bilinmiyor",
|
|
110
|
+
description=description, tags=tags, rating=rating, year=year, actors=actors, duration=duration
|
|
111
|
+
)
|
|
112
|
+
|
|
152
113
|
def generate_random_cookie(self):
|
|
153
114
|
return "".join(random.choices(string.ascii_letters + string.digits, k=16))
|
|
154
115
|
|
|
@@ -99,35 +99,34 @@ class JetFilmizle(PluginBase):
|
|
|
99
99
|
istek = await self.httpx.get(url)
|
|
100
100
|
secici = HTMLHelper(istek.text)
|
|
101
101
|
|
|
102
|
-
title
|
|
103
|
-
|
|
104
|
-
poster = secici.select_poster("section.movie-exp img")
|
|
105
|
-
poster = poster.strip() if poster else None
|
|
106
|
-
|
|
102
|
+
title = self.clean_title(secici.select_text("div.movie-exp-title"))
|
|
103
|
+
poster = secici.select_poster("section.movie-exp img")
|
|
107
104
|
description = secici.select_text("section.movie-exp p.aciklama")
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
if
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
105
|
+
tags = secici.select_texts("section.movie-exp div.catss a")
|
|
106
|
+
rating = secici.select_text("section.movie-exp div.imdb_puan span")
|
|
107
|
+
year = secici.meta_value("Yayın Yılı")
|
|
108
|
+
actors = secici.select_texts("div[itemprop='actor'] a span") or [img.attrs.get("alt") for img in secici.select("div.oyuncular div.oyuncu img") if img.attrs.get("alt")]
|
|
109
|
+
duration = secici.meta_value("Süre")
|
|
110
|
+
duration = duration.split() if duration else None
|
|
111
|
+
|
|
112
|
+
total_minutes = 0
|
|
113
|
+
if duration:
|
|
114
|
+
for i, p in enumerate(duration):
|
|
115
|
+
if p == "saat":
|
|
116
|
+
total_minutes += int(duration[i-1]) * 60
|
|
117
|
+
elif p == "dakika":
|
|
118
|
+
total_minutes += int(duration[i-1])
|
|
120
119
|
|
|
121
120
|
return MovieInfo(
|
|
122
121
|
url = url,
|
|
123
122
|
poster = self.fix_url(poster) if poster else None,
|
|
124
|
-
title = title,
|
|
123
|
+
title = title or "Bilinmiyor",
|
|
125
124
|
description = description,
|
|
126
125
|
tags = tags,
|
|
127
126
|
rating = rating,
|
|
128
|
-
year = year,
|
|
127
|
+
year = str(year) if year else None,
|
|
129
128
|
actors = actors,
|
|
130
|
-
duration = int(
|
|
129
|
+
duration = int(total_minutes) if duration else None
|
|
131
130
|
)
|
|
132
131
|
|
|
133
132
|
async def load_links(self, url: str) -> list[ExtractResult]:
|
|
@@ -78,68 +78,34 @@ class KultFilmler(PluginBase):
|
|
|
78
78
|
istek = await self.httpx.get(url)
|
|
79
79
|
secici = HTMLHelper(istek.text)
|
|
80
80
|
|
|
81
|
-
title = secici.select_attr("div.film-bilgileri img", "alt") or secici.select_attr("[property='og:title']", "content")
|
|
82
|
-
poster = self.fix_url(secici.select_attr("[property='og:image']", "content"))
|
|
83
|
-
|
|
81
|
+
title = self.clean_title(secici.select_attr("div.film-bilgileri img", "alt") or secici.select_attr("[property='og:title']", "content"))
|
|
82
|
+
poster = self.fix_url(secici.select_attr("[property='og:image']", "content"))
|
|
84
83
|
description = secici.select_text("div.description")
|
|
84
|
+
tags = secici.select_texts("ul.post-categories a")
|
|
85
|
+
year = secici.extract_year("li.release span a")
|
|
86
|
+
duration = int(secici.regex_first(r"(\d+)", secici.select_text("li.time span")) or 0)
|
|
87
|
+
rating = secici.regex_first(r"(\d+\.\d+|\d+)", secici.select_text("div.imdb-count"))
|
|
88
|
+
actors = secici.select_texts("div.actors a")
|
|
85
89
|
|
|
86
|
-
tags = [a.text(strip=True) for a in secici.select("ul.post-categories a") if a.text(strip=True)]
|
|
87
|
-
|
|
88
|
-
# HTML analizine göre güncellenen alanlar
|
|
89
|
-
year = secici.select_text("li.release span a")
|
|
90
|
-
|
|
91
|
-
time_text = secici.select_text("li.time span")
|
|
92
|
-
duration = secici.regex_first(r"(\d+)", time_text) if time_text else None
|
|
93
|
-
|
|
94
|
-
rating_text = secici.select_text("div.imdb-count")
|
|
95
|
-
rating = secici.regex_first(r"(\d+\.\d+|\d+)", rating_text) if rating_text else None
|
|
96
|
-
|
|
97
|
-
actors = [a.text(strip=True) for a in secici.select("div.actors a") if a.text(strip=True)]
|
|
98
|
-
|
|
99
|
-
# Dizi mi kontrol et
|
|
100
90
|
if "/dizi/" in url:
|
|
101
91
|
episodes = []
|
|
102
92
|
for bolum in secici.select("div.episode-box"):
|
|
103
|
-
|
|
104
|
-
|
|
93
|
+
href = secici.select_attr("div.name a", "href", bolum)
|
|
105
94
|
ssn_detail = secici.select_text("span.episodetitle", bolum) or ""
|
|
106
95
|
ep_detail = secici.select_text("span.episodetitle b", bolum) or ""
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
ep_season = secici.regex_first(r"(\d+)\.", ssn_detail)
|
|
112
|
-
ep_episode = secici.regex_first(r"(\d+)\.", ep_detail)
|
|
113
|
-
|
|
114
|
-
episodes.append(Episode(
|
|
115
|
-
season = int(ep_season) if ep_season else 1,
|
|
116
|
-
episode = int(ep_episode) if ep_episode else 1,
|
|
117
|
-
title = ep_name.strip(" -"),
|
|
118
|
-
url = self.fix_url(ep_href),
|
|
119
|
-
))
|
|
96
|
+
if href:
|
|
97
|
+
s, e = secici.extract_season_episode(f"{ssn_detail} {ep_detail}")
|
|
98
|
+
name = f"{ssn_detail} - {ep_detail}".strip(" -")
|
|
99
|
+
episodes.append(Episode(season=s or 1, episode=e or 1, title=name, url=self.fix_url(href)))
|
|
120
100
|
|
|
121
101
|
return SeriesInfo(
|
|
122
|
-
url
|
|
123
|
-
|
|
124
|
-
title = self.clean_title(title) if title else "",
|
|
125
|
-
description = description,
|
|
126
|
-
tags = tags,
|
|
127
|
-
year = year,
|
|
128
|
-
actors = actors,
|
|
129
|
-
rating = rating,
|
|
130
|
-
episodes = episodes,
|
|
102
|
+
url=url, poster=poster, title=title or "Bilinmiyor", description=description,
|
|
103
|
+
tags=tags, year=str(year) if year else None, actors=actors, rating=rating, episodes=episodes
|
|
131
104
|
)
|
|
132
105
|
|
|
133
106
|
return MovieInfo(
|
|
134
|
-
url
|
|
135
|
-
|
|
136
|
-
title = self.clean_title(title) if title else "",
|
|
137
|
-
description = description,
|
|
138
|
-
tags = tags,
|
|
139
|
-
year = year,
|
|
140
|
-
rating = rating,
|
|
141
|
-
actors = actors,
|
|
142
|
-
duration = int(duration) if duration else None,
|
|
107
|
+
url=url, poster=poster, title=title or "Bilinmiyor", description=description,
|
|
108
|
+
tags=tags, year=str(year) if year else None, rating=rating, actors=actors, duration=duration
|
|
143
109
|
)
|
|
144
110
|
|
|
145
111
|
def _get_iframe(self, source_code: str) -> str:
|