KekikStream 2.3.3__py3-none-any.whl → 2.3.5__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/HTMLHelper.py +134 -0
- KekikStream/Core/Plugin/PluginBase.py +12 -2
- KekikStream/Core/__init__.py +2 -0
- KekikStream/Extractors/CloseLoad.py +12 -13
- KekikStream/Extractors/ContentX.py +33 -31
- KekikStream/Extractors/DonilasPlay.py +10 -10
- KekikStream/Extractors/DzenRu.py +3 -3
- KekikStream/Extractors/ExPlay.py +10 -10
- KekikStream/Extractors/Filemoon.py +11 -16
- KekikStream/Extractors/JetTv.py +4 -4
- KekikStream/Extractors/MixPlayHD.py +10 -11
- KekikStream/Extractors/MolyStream.py +15 -9
- KekikStream/Extractors/Odnoklassniki.py +4 -4
- KekikStream/Extractors/PeaceMakerst.py +3 -3
- KekikStream/Extractors/PixelDrain.py +6 -5
- KekikStream/Extractors/PlayerFilmIzle.py +6 -10
- KekikStream/Extractors/RapidVid.py +8 -7
- KekikStream/Extractors/SetPlay.py +10 -10
- KekikStream/Extractors/SetPrime.py +3 -6
- KekikStream/Extractors/SibNet.py +4 -5
- KekikStream/Extractors/Sobreatsesuyp.py +5 -5
- KekikStream/Extractors/TRsTX.py +5 -5
- KekikStream/Extractors/TurboImgz.py +3 -4
- KekikStream/Extractors/TurkeyPlayer.py +5 -5
- KekikStream/Extractors/VidHide.py +4 -7
- KekikStream/Extractors/VidMoly.py +24 -25
- KekikStream/Extractors/VidMoxy.py +8 -9
- KekikStream/Extractors/VidPapi.py +5 -7
- KekikStream/Extractors/VideoSeyred.py +3 -3
- KekikStream/Plugins/BelgeselX.py +40 -51
- KekikStream/Plugins/DiziBox.py +53 -81
- KekikStream/Plugins/DiziPal.py +41 -74
- KekikStream/Plugins/DiziWatch.py +217 -0
- KekikStream/Plugins/DiziYou.py +95 -88
- KekikStream/Plugins/Dizilla.py +54 -72
- KekikStream/Plugins/FilmBip.py +24 -49
- KekikStream/Plugins/FilmMakinesi.py +35 -52
- KekikStream/Plugins/FilmModu.py +27 -41
- KekikStream/Plugins/FullHDFilm.py +50 -72
- KekikStream/Plugins/FullHDFilmizlesene.py +35 -51
- KekikStream/Plugins/HDFilmCehennemi.py +48 -62
- KekikStream/Plugins/JetFilmizle.py +32 -50
- KekikStream/Plugins/KultFilmler.py +42 -67
- KekikStream/Plugins/RecTV.py +7 -4
- KekikStream/Plugins/RoketDizi.py +30 -50
- KekikStream/Plugins/SelcukFlix.py +15 -29
- KekikStream/Plugins/SetFilmIzle.py +41 -70
- KekikStream/Plugins/SezonlukDizi.py +47 -65
- KekikStream/Plugins/Sinefy.py +39 -50
- KekikStream/Plugins/SinemaCX.py +31 -55
- KekikStream/Plugins/Sinezy.py +27 -54
- KekikStream/Plugins/SuperFilmGeldi.py +25 -44
- KekikStream/Plugins/UgurFilm.py +23 -48
- KekikStream/Plugins/YabanciDizi.py +274 -0
- {kekikstream-2.3.3.dist-info → kekikstream-2.3.5.dist-info}/METADATA +1 -1
- kekikstream-2.3.5.dist-info/RECORD +85 -0
- kekikstream-2.3.3.dist-info/RECORD +0 -82
- {kekikstream-2.3.3.dist-info → kekikstream-2.3.5.dist-info}/WHEEL +0 -0
- {kekikstream-2.3.3.dist-info → kekikstream-2.3.5.dist-info}/entry_points.txt +0 -0
- {kekikstream-2.3.3.dist-info → kekikstream-2.3.5.dist-info}/licenses/LICENSE +0 -0
- {kekikstream-2.3.3.dist-info → kekikstream-2.3.5.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, SeriesInfo, Episode, ExtractResult, Subtitle
|
|
4
|
-
|
|
5
|
-
import re, base64
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, SeriesInfo, Episode, ExtractResult, Subtitle, HTMLHelper
|
|
4
|
+
import base64
|
|
6
5
|
|
|
7
6
|
class FullHDFilm(PluginBase):
|
|
8
7
|
name = "FullHDFilm"
|
|
@@ -48,16 +47,13 @@ class FullHDFilm(PluginBase):
|
|
|
48
47
|
})
|
|
49
48
|
|
|
50
49
|
istek = await self.httpx.get(page_url)
|
|
51
|
-
secici =
|
|
50
|
+
secici = HTMLHelper(istek.text)
|
|
52
51
|
|
|
53
52
|
results = []
|
|
54
|
-
for veri in secici.
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
alt = img_el.attrs.get("alt") if img_el else None
|
|
59
|
-
poster = img_el.attrs.get("src") if img_el else None
|
|
60
|
-
href = link_el.attrs.get("href") if link_el else None
|
|
53
|
+
for veri in secici.select("div.movie-poster"):
|
|
54
|
+
alt = secici.select_attr("img", "alt", veri)
|
|
55
|
+
poster = secici.select_attr("img", "src", veri)
|
|
56
|
+
href = secici.select_attr("a", "href", veri)
|
|
61
57
|
|
|
62
58
|
if alt and href:
|
|
63
59
|
results.append(MainPageResult(
|
|
@@ -71,16 +67,13 @@ class FullHDFilm(PluginBase):
|
|
|
71
67
|
|
|
72
68
|
async def search(self, query: str) -> list[SearchResult]:
|
|
73
69
|
istek = await self.httpx.get(f"{self.main_url}/?s={query}")
|
|
74
|
-
secici =
|
|
70
|
+
secici = HTMLHelper(istek.text)
|
|
75
71
|
|
|
76
72
|
results = []
|
|
77
|
-
for veri in secici.
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
alt = img_el.attrs.get("alt") if img_el else None
|
|
82
|
-
poster = img_el.attrs.get("src") if img_el else None
|
|
83
|
-
href = link_el.attrs.get("href") if link_el else None
|
|
73
|
+
for veri in secici.select("div.movie-poster"):
|
|
74
|
+
alt = secici.select_attr("img", "alt", veri)
|
|
75
|
+
poster = secici.select_attr("img", "src", veri)
|
|
76
|
+
href = secici.select_attr("a", "href", veri)
|
|
84
77
|
|
|
85
78
|
if alt and href:
|
|
86
79
|
results.append(SearchResult(
|
|
@@ -93,75 +86,59 @@ class FullHDFilm(PluginBase):
|
|
|
93
86
|
|
|
94
87
|
async def load_item(self, url: str) -> MovieInfo | SeriesInfo:
|
|
95
88
|
istek = await self.httpx.get(url)
|
|
96
|
-
secici =
|
|
89
|
+
secici = HTMLHelper(istek.text)
|
|
97
90
|
html_text = istek.text
|
|
98
91
|
|
|
99
|
-
|
|
100
|
-
title = title_el.text(strip=True) if title_el else ""
|
|
92
|
+
title = secici.select_text("h1") or ""
|
|
101
93
|
|
|
102
|
-
|
|
103
|
-
poster
|
|
94
|
+
poster = secici.select_attr("div.poster img", "src") or ""
|
|
95
|
+
poster = self.fix_url(poster)
|
|
104
96
|
|
|
105
|
-
actors_el = secici.css_first("div.oyuncular.info")
|
|
106
97
|
actors = []
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
actors = [a.strip() for a in actors_text.split(",")]
|
|
98
|
+
actors_text = secici.select_text("div.oyuncular.info")
|
|
99
|
+
if actors_text:
|
|
100
|
+
actors_text = actors_text.replace("Oyuncular:", "").strip()
|
|
101
|
+
actors = [a.strip() for a in actors_text.split(",")]
|
|
112
102
|
|
|
113
103
|
# Year: önce div.yayin-tarihi.info dene
|
|
114
|
-
year =
|
|
115
|
-
|
|
116
|
-
if year_el:
|
|
117
|
-
year_text = year_el.text(strip=True)
|
|
118
|
-
year_match = re.search(r"(\d{4})", year_text)
|
|
119
|
-
if year_match:
|
|
120
|
-
year = year_match.group(1)
|
|
121
|
-
|
|
104
|
+
year = secici.extract_year("div.yayin-tarihi.info")
|
|
105
|
+
|
|
122
106
|
# Fallback: h1'in parent'ından (2019) formatında ara
|
|
123
|
-
if not year
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
year = year_match.group(1)
|
|
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})\)")
|
|
130
113
|
|
|
131
|
-
tags =
|
|
114
|
+
tags = secici.select_all_text("div.tur.info a")
|
|
132
115
|
|
|
133
116
|
# Rating: regex
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
rating_match = re.search(r"IMDb\s*([\d\.]+)", rating_text)
|
|
137
|
-
rating = rating_match.group(1) if rating_match else None
|
|
117
|
+
rating_text = secici.select_text("div.imdb") or ""
|
|
118
|
+
rating = HTMLHelper(rating_text).regex_first(r"IMDb\s*([\d\.]+)")
|
|
138
119
|
|
|
139
120
|
# Description: önce div.film dene, yoksa og:description meta tag'ını kullan
|
|
140
|
-
description =
|
|
141
|
-
desc_el = secici.css_first("div.film")
|
|
142
|
-
if desc_el:
|
|
143
|
-
description = desc_el.text(strip=True)
|
|
121
|
+
description = secici.select_text("div.film")
|
|
144
122
|
|
|
145
123
|
# Fallback: og:description meta tag'ı
|
|
146
124
|
if not description:
|
|
147
|
-
og_desc = secici.
|
|
125
|
+
og_desc = secici.select_attr("meta[property='og:description']", "content")
|
|
148
126
|
if og_desc:
|
|
149
|
-
description = og_desc
|
|
127
|
+
description = og_desc
|
|
150
128
|
|
|
151
129
|
# Kotlin referansı: URL'de -dizi kontrolü veya tags içinde "dizi" kontrolü
|
|
152
130
|
is_series = "-dizi" in url.lower() or any("dizi" in tag.lower() for tag in tags)
|
|
153
131
|
|
|
154
132
|
if is_series:
|
|
155
133
|
episodes = []
|
|
156
|
-
part_elements = secici.
|
|
134
|
+
part_elements = secici.select("li.psec")
|
|
157
135
|
|
|
158
136
|
# pdata değerlerini çıkar
|
|
159
|
-
pdata_matches =
|
|
137
|
+
pdata_matches = HTMLHelper(html_text).regex_all(r"pdata\['([^']+)'\]\s*=\s*'([^']+)'")
|
|
160
138
|
|
|
161
139
|
for idx, el in enumerate(part_elements):
|
|
162
140
|
part_id = el.attrs.get("id")
|
|
163
|
-
|
|
164
|
-
part_name = link_el.text(strip=True) if link_el else None
|
|
141
|
+
part_name = secici.select_text("a", el)
|
|
165
142
|
|
|
166
143
|
if not part_name:
|
|
167
144
|
continue
|
|
@@ -171,11 +148,11 @@ class FullHDFilm(PluginBase):
|
|
|
171
148
|
continue
|
|
172
149
|
|
|
173
150
|
# Sezon ve bölüm numarası çıkar
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
sz_num = int(
|
|
178
|
-
ep_num = int(
|
|
151
|
+
sz_val = HTMLHelper(part_id.lower() if part_id else "").regex_first(r'(\d+)\s*sezon')
|
|
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
|
|
179
156
|
|
|
180
157
|
# pdata'dan video URL'si çık (varsa)
|
|
181
158
|
video_url = url # Varsayılan olarak ana URL kullan
|
|
@@ -214,14 +191,14 @@ class FullHDFilm(PluginBase):
|
|
|
214
191
|
|
|
215
192
|
def _get_iframe(self, source_code: str) -> str:
|
|
216
193
|
"""Base64 kodlu iframe'i çözümle"""
|
|
217
|
-
|
|
218
|
-
if not
|
|
194
|
+
script_val = HTMLHelper(source_code).regex_first(r'<script[^>]*>(PCEtLWJhc2xpazp[^<]*)</script>')
|
|
195
|
+
if not script_val:
|
|
219
196
|
return ""
|
|
220
197
|
|
|
221
198
|
try:
|
|
222
|
-
decoded_html = base64.b64decode(
|
|
223
|
-
|
|
224
|
-
return self.fix_url(
|
|
199
|
+
decoded_html = base64.b64decode(script_val).decode("utf-8")
|
|
200
|
+
iframe_src = HTMLHelper(decoded_html).regex_first(r'<iframe[^>]+src=["\']([^"\']+)["\']')
|
|
201
|
+
return self.fix_url(iframe_src) if iframe_src else ""
|
|
225
202
|
except Exception:
|
|
226
203
|
return ""
|
|
227
204
|
|
|
@@ -234,8 +211,9 @@ class FullHDFilm(PluginBase):
|
|
|
234
211
|
]
|
|
235
212
|
|
|
236
213
|
for pattern in patterns:
|
|
237
|
-
|
|
238
|
-
|
|
214
|
+
val = HTMLHelper(source_code).regex_first(pattern)
|
|
215
|
+
if val:
|
|
216
|
+
return val
|
|
239
217
|
|
|
240
218
|
return None
|
|
241
219
|
|
|
@@ -1,9 +1,8 @@
|
|
|
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
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, ExtractResult, HTMLHelper
|
|
5
4
|
from Kekik.Sifreleme import StringCodec
|
|
6
|
-
import json
|
|
5
|
+
import json
|
|
7
6
|
|
|
8
7
|
class FullHDFilmizlesene(PluginBase):
|
|
9
8
|
name = "FullHDFilmizlesene"
|
|
@@ -42,17 +41,13 @@ class FullHDFilmizlesene(PluginBase):
|
|
|
42
41
|
|
|
43
42
|
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
44
43
|
istek = self.cloudscraper.get(f"{url}{page}")
|
|
45
|
-
secici =
|
|
44
|
+
secici = HTMLHelper(istek.text)
|
|
46
45
|
|
|
47
46
|
results = []
|
|
48
|
-
for veri in secici.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
title = title_el.text(strip=True) if title_el else None
|
|
54
|
-
href = link_el.attrs.get("href") if link_el else None
|
|
55
|
-
poster = img_el.attrs.get("data-src") if img_el else None
|
|
47
|
+
for veri in secici.select("li.film"):
|
|
48
|
+
title = secici.select_text("span.film-title", veri)
|
|
49
|
+
href = secici.select_attr("a", "href", veri)
|
|
50
|
+
poster = secici.select_attr("img", "data-src", veri)
|
|
56
51
|
|
|
57
52
|
if title and href:
|
|
58
53
|
results.append(MainPageResult(
|
|
@@ -66,17 +61,13 @@ class FullHDFilmizlesene(PluginBase):
|
|
|
66
61
|
|
|
67
62
|
async def search(self, query: str) -> list[SearchResult]:
|
|
68
63
|
istek = await self.httpx.get(f"{self.main_url}/arama/{query}")
|
|
69
|
-
secici =
|
|
64
|
+
secici = HTMLHelper(istek.text)
|
|
70
65
|
|
|
71
66
|
results = []
|
|
72
|
-
for film in secici.
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
title = title_el.text(strip=True) if title_el else None
|
|
78
|
-
href = link_el.attrs.get("href") if link_el else None
|
|
79
|
-
poster = img_el.attrs.get("data-src") if img_el else None
|
|
67
|
+
for film in secici.select("li.film"):
|
|
68
|
+
title = secici.select_text("span.film-title", film)
|
|
69
|
+
href = secici.select_attr("a", "href", film)
|
|
70
|
+
poster = secici.select_attr("img", "data-src", film)
|
|
80
71
|
|
|
81
72
|
if title and href:
|
|
82
73
|
results.append(SearchResult(
|
|
@@ -89,49 +80,42 @@ class FullHDFilmizlesene(PluginBase):
|
|
|
89
80
|
|
|
90
81
|
async def load_item(self, url: str) -> MovieInfo:
|
|
91
82
|
istek = await self.httpx.get(url)
|
|
92
|
-
secici =
|
|
83
|
+
secici = HTMLHelper(istek.text)
|
|
93
84
|
html_text = istek.text
|
|
94
85
|
|
|
95
86
|
# Title: normalize-space yerine doğrudan class ile
|
|
96
|
-
|
|
97
|
-
title = title_el.text(strip=True) if title_el else ""
|
|
87
|
+
title = secici.select_text("div.izle-titles") or ""
|
|
98
88
|
|
|
99
|
-
|
|
100
|
-
poster =
|
|
89
|
+
poster = secici.select_attr("div img[data-src]", "data-src") or ""
|
|
90
|
+
poster = poster.strip()
|
|
101
91
|
|
|
102
|
-
|
|
103
|
-
description = desc_el.text(strip=True) if desc_el else ""
|
|
92
|
+
description = secici.select_text("div.ozet-ic p") or ""
|
|
104
93
|
|
|
105
|
-
tags =
|
|
94
|
+
tags = secici.select_all_text("a[rel='category tag']")
|
|
106
95
|
|
|
107
96
|
# Rating: normalize-space yerine doğrudan class ile ve son kelimeyi al
|
|
108
|
-
|
|
97
|
+
rating_text = secici.select_text("div.puanx-puan") or None
|
|
109
98
|
rating = None
|
|
110
|
-
if
|
|
111
|
-
|
|
112
|
-
if
|
|
113
|
-
parts = rating_text.split()
|
|
114
|
-
rating = parts[-1] if parts else None
|
|
99
|
+
if rating_text:
|
|
100
|
+
parts = rating_text.split()
|
|
101
|
+
rating = parts[-1] if parts else None
|
|
115
102
|
|
|
116
103
|
# Year: ilk yıl formatında değer
|
|
117
|
-
|
|
104
|
+
year_text = secici.select_text("div.dd a.category") or None
|
|
118
105
|
year = None
|
|
119
|
-
if
|
|
120
|
-
|
|
121
|
-
if
|
|
122
|
-
parts = year_text.split()
|
|
123
|
-
year = parts[0] if parts else None
|
|
106
|
+
if year_text:
|
|
107
|
+
parts = year_text.split()
|
|
108
|
+
year = parts[0] if parts else None
|
|
124
109
|
|
|
125
110
|
# Actors: nth-child yerine tüm li'leri alıp 2. index
|
|
126
|
-
lis = secici.
|
|
111
|
+
lis = secici.select("div.film-info ul li")
|
|
127
112
|
actors = []
|
|
128
113
|
if len(lis) >= 2:
|
|
129
|
-
actors =
|
|
114
|
+
actors = secici.select_all_text("a > span", lis[1])
|
|
130
115
|
|
|
131
|
-
duration_el = secici.css_first("span.sure")
|
|
132
116
|
duration = "0"
|
|
133
|
-
|
|
134
|
-
|
|
117
|
+
duration_text = secici.select_text("span.sure") or None
|
|
118
|
+
if duration_text:
|
|
135
119
|
duration_parts = duration_text.split()
|
|
136
120
|
duration = duration_parts[0] if duration_parts else "0"
|
|
137
121
|
|
|
@@ -149,18 +133,18 @@ class FullHDFilmizlesene(PluginBase):
|
|
|
149
133
|
|
|
150
134
|
async def load_links(self, url: str) -> list[ExtractResult]:
|
|
151
135
|
istek = await self.httpx.get(url)
|
|
152
|
-
secici =
|
|
136
|
+
secici = HTMLHelper(istek.text)
|
|
153
137
|
html_text = istek.text
|
|
154
138
|
|
|
155
139
|
# İlk script'i al (xpath (//script)[1] yerine)
|
|
156
|
-
scripts = secici.
|
|
140
|
+
scripts = secici.select("script")
|
|
157
141
|
script_content = scripts[0].text() if scripts else ""
|
|
158
142
|
|
|
159
|
-
|
|
160
|
-
if not
|
|
143
|
+
scx_json = HTMLHelper(script_content).regex_first(r"scx = (.*?);")
|
|
144
|
+
if not scx_json:
|
|
161
145
|
return []
|
|
162
146
|
|
|
163
|
-
scx_data = json.loads(
|
|
147
|
+
scx_data = json.loads(scx_json)
|
|
164
148
|
scx_keys = list(scx_data.keys())
|
|
165
149
|
|
|
166
150
|
link_list = []
|
|
@@ -1,14 +1,13 @@
|
|
|
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, SeriesInfo, Episode, Subtitle, ExtractResult
|
|
4
|
-
from selectolax.parser import HTMLParser
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, SeriesInfo, Episode, Subtitle, ExtractResult, HTMLHelper
|
|
5
4
|
from Kekik.Sifreleme import Packer, StreamDecoder
|
|
6
|
-
import random, string
|
|
5
|
+
import random, string
|
|
7
6
|
|
|
8
7
|
class HDFilmCehennemi(PluginBase):
|
|
9
8
|
name = "HDFilmCehennemi"
|
|
10
9
|
language = "tr"
|
|
11
|
-
main_url = "https://www.hdfilmcehennemi.
|
|
10
|
+
main_url = "https://www.hdfilmcehennemi.nl"
|
|
12
11
|
favicon = f"https://www.google.com/s2/favicons?domain={main_url}&sz=64"
|
|
13
12
|
description = "Türkiye'nin en hızlı hd film izleme sitesi. Tek ve gerçek hdfilmcehennemi sitesi."
|
|
14
13
|
|
|
@@ -31,16 +30,13 @@ class HDFilmCehennemi(PluginBase):
|
|
|
31
30
|
|
|
32
31
|
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
33
32
|
istek = await self.httpx.get(f"{url}", follow_redirects=True)
|
|
34
|
-
secici =
|
|
33
|
+
secici = HTMLHelper(istek.text)
|
|
35
34
|
|
|
36
35
|
results = []
|
|
37
|
-
for veri in secici.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
title = title_el.text(strip=True) if title_el else None
|
|
42
|
-
href = veri.attrs.get("href")
|
|
43
|
-
poster = img_el.attrs.get("data-src") if img_el else None
|
|
36
|
+
for veri in secici.select("div.section-content a.poster"):
|
|
37
|
+
title = secici.select_text("strong.poster-title", veri)
|
|
38
|
+
href = veri.attrs.get("href")
|
|
39
|
+
poster = secici.select_attr("img", "data-src", veri)
|
|
44
40
|
|
|
45
41
|
if title and href:
|
|
46
42
|
results.append(MainPageResult(
|
|
@@ -64,14 +60,10 @@ class HDFilmCehennemi(PluginBase):
|
|
|
64
60
|
|
|
65
61
|
results = []
|
|
66
62
|
for veri in istek.json().get("results", []):
|
|
67
|
-
secici =
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
title = title_el.text(strip=True) if title_el else None
|
|
73
|
-
href = link_el.attrs.get("href") if link_el else None
|
|
74
|
-
poster = (img_el.attrs.get("data-src") or img_el.attrs.get("src")) if img_el else None
|
|
63
|
+
secici = HTMLHelper(veri)
|
|
64
|
+
title = secici.select_text("h4.title")
|
|
65
|
+
href = secici.select_attr("a", "href")
|
|
66
|
+
poster = secici.select_attr("img", "data-src") or secici.select_attr("img", "src")
|
|
75
67
|
|
|
76
68
|
if title and href:
|
|
77
69
|
results.append(SearchResult(
|
|
@@ -84,53 +76,47 @@ class HDFilmCehennemi(PluginBase):
|
|
|
84
76
|
|
|
85
77
|
async def load_item(self, url: str) -> MovieInfo | SeriesInfo:
|
|
86
78
|
istek = await self.httpx.get(url, headers = {"Referer": f"{self.main_url}/"})
|
|
87
|
-
secici =
|
|
79
|
+
secici = HTMLHelper(istek.text)
|
|
88
80
|
|
|
89
|
-
|
|
90
|
-
title = title_el.text(strip=True) if title_el else ""
|
|
81
|
+
title = secici.select_text("h1.section-title") or ""
|
|
91
82
|
|
|
92
|
-
|
|
93
|
-
poster
|
|
83
|
+
poster = secici.select_attr("aside.post-info-poster img.lazyload", "data-src") or ""
|
|
84
|
+
poster = poster.strip()
|
|
94
85
|
|
|
95
|
-
|
|
96
|
-
description = desc_el.text(strip=True) if desc_el else ""
|
|
86
|
+
description = secici.select_text("article.post-info-content > p") or ""
|
|
97
87
|
|
|
98
|
-
tags
|
|
88
|
+
tags = secici.select_all_text("div.post-info-genres a")
|
|
99
89
|
|
|
100
|
-
|
|
101
|
-
rating = rating_el.text(strip=True) if rating_el else ""
|
|
90
|
+
rating = secici.select_text("div.post-info-imdb-rating span") or ""
|
|
102
91
|
|
|
103
|
-
|
|
104
|
-
year = year_el.text(strip=True) if year_el else ""
|
|
92
|
+
year = secici.select_text("div.post-info-year-country a") or ""
|
|
105
93
|
|
|
106
|
-
actors =
|
|
94
|
+
actors = secici.select_all_text("div.post-info-cast a > strong")
|
|
107
95
|
|
|
108
|
-
|
|
109
|
-
duration_str = duration_el.text(strip=True) if duration_el else "0"
|
|
96
|
+
duration_str = secici.select_text("div.post-info-duration") or "0"
|
|
110
97
|
duration_str = duration_str.replace("dakika", "").strip()
|
|
111
98
|
|
|
112
99
|
try:
|
|
113
|
-
|
|
114
|
-
duration_minutes = int(
|
|
100
|
+
duration_val = HTMLHelper(duration_str).regex_first(r'\d+')
|
|
101
|
+
duration_minutes = int(duration_val) if duration_val else 0
|
|
115
102
|
except Exception:
|
|
116
103
|
duration_minutes = 0
|
|
117
104
|
|
|
118
105
|
# Dizi mi film mi kontrol et (Kotlin referansı: div.seasons kontrolü)
|
|
119
|
-
is_series = len(secici.
|
|
106
|
+
is_series = len(secici.select("div.seasons")) > 0
|
|
120
107
|
|
|
121
108
|
if is_series:
|
|
122
109
|
episodes = []
|
|
123
|
-
for ep in secici.
|
|
124
|
-
|
|
125
|
-
ep_name = ep_name_el.text(strip=True) if ep_name_el else None
|
|
110
|
+
for ep in secici.select("div.seasons-tab-content a"):
|
|
111
|
+
ep_name = secici.select_text("h4", ep)
|
|
126
112
|
ep_href = ep.attrs.get("href")
|
|
127
113
|
|
|
128
114
|
if ep_name and ep_href:
|
|
129
115
|
# Regex ile sezon ve bölüm numarası çıkar
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
ep_num = int(
|
|
133
|
-
sz_num = int(
|
|
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
|
|
134
120
|
|
|
135
121
|
episodes.append(Episode(
|
|
136
122
|
season = sz_num,
|
|
@@ -208,19 +194,19 @@ class HDFilmCehennemi(PluginBase):
|
|
|
208
194
|
def _extract_from_json_ld(self, html: str) -> str | None:
|
|
209
195
|
"""JSON-LD script tag'inden contentUrl'i çıkar (Kotlin versiyonundaki gibi)"""
|
|
210
196
|
# Önce JSON-LD'den dene
|
|
211
|
-
|
|
212
|
-
if
|
|
197
|
+
json_ld = HTMLHelper(html).regex_first(r'(?s)<script[^>]+type=["\']application/ld\+json["\'][^>]*>(.*?)</script>')
|
|
198
|
+
if json_ld:
|
|
213
199
|
try:
|
|
214
200
|
import json
|
|
215
|
-
data = json.loads(
|
|
201
|
+
data = json.loads(json_ld.strip())
|
|
216
202
|
if content_url := data.get("contentUrl"):
|
|
217
203
|
if content_url.startswith("http"):
|
|
218
204
|
return content_url
|
|
219
205
|
except Exception:
|
|
220
206
|
# Regex ile contentUrl'i çıkarmayı dene
|
|
221
|
-
|
|
222
|
-
if
|
|
223
|
-
return
|
|
207
|
+
content_url = HTMLHelper(html).regex_first(r'"contentUrl"\s*:\s*"([^"]+)"')
|
|
208
|
+
if content_url and content_url.startswith("http"):
|
|
209
|
+
return content_url
|
|
224
210
|
return None
|
|
225
211
|
|
|
226
212
|
async def invoke_local_source(self, iframe: str, source: str, url: str):
|
|
@@ -239,12 +225,12 @@ class HDFilmCehennemi(PluginBase):
|
|
|
239
225
|
# Fallback: Packed JavaScript'ten çıkar
|
|
240
226
|
if not video_url:
|
|
241
227
|
# eval(function...) içeren packed script bul
|
|
242
|
-
|
|
243
|
-
if not
|
|
228
|
+
eval_script = HTMLHelper(istek.text).regex_first(r'(eval\(function[\s\S]+)')
|
|
229
|
+
if not eval_script:
|
|
244
230
|
return await self.cehennempass(iframe.split("/")[-1])
|
|
245
231
|
|
|
246
232
|
try:
|
|
247
|
-
unpacked = Packer.unpack(
|
|
233
|
+
unpacked = Packer.unpack(eval_script)
|
|
248
234
|
video_url = StreamDecoder.extract_stream_url(unpacked)
|
|
249
235
|
except Exception:
|
|
250
236
|
return await self.cehennempass(iframe.split("/")[-1])
|
|
@@ -255,10 +241,10 @@ class HDFilmCehennemi(PluginBase):
|
|
|
255
241
|
subtitles = []
|
|
256
242
|
try:
|
|
257
243
|
sub_data = istek.text.split("tracks: [")[1].split("]")[0]
|
|
258
|
-
for
|
|
244
|
+
for file_url, lang in HTMLHelper(sub_data).regex_all(r'(?s)file":"([^\\"]+)".*?"language":"([^\\"]+)"'):
|
|
259
245
|
subtitles.append(Subtitle(
|
|
260
|
-
name =
|
|
261
|
-
url = self.fix_url(
|
|
246
|
+
name = lang.upper(),
|
|
247
|
+
url = self.fix_url(file_url.replace("\\", "")),
|
|
262
248
|
))
|
|
263
249
|
except Exception:
|
|
264
250
|
pass
|
|
@@ -272,13 +258,13 @@ class HDFilmCehennemi(PluginBase):
|
|
|
272
258
|
|
|
273
259
|
async def load_links(self, url: str) -> list[ExtractResult]:
|
|
274
260
|
istek = await self.httpx.get(url)
|
|
275
|
-
secici =
|
|
261
|
+
secici = HTMLHelper(istek.text)
|
|
276
262
|
|
|
277
263
|
results = []
|
|
278
|
-
for alternatif in secici.
|
|
264
|
+
for alternatif in secici.select("div.alternative-links"):
|
|
279
265
|
lang_code = alternatif.attrs.get("data-lang", "").upper()
|
|
280
266
|
|
|
281
|
-
for link in
|
|
267
|
+
for link in secici.select("button.alternative-link", alternatif):
|
|
282
268
|
source_text = link.text(strip=True).replace('(HDrip Xbet)', '').strip()
|
|
283
269
|
source = f"{source_text} {lang_code}"
|
|
284
270
|
video_id = link.attrs.get("data-video")
|
|
@@ -295,8 +281,8 @@ class HDFilmCehennemi(PluginBase):
|
|
|
295
281
|
},
|
|
296
282
|
)
|
|
297
283
|
|
|
298
|
-
|
|
299
|
-
iframe =
|
|
284
|
+
iframe = HTMLHelper(api_get.text).regex_first(r'data-src=\\\"([^\"]+)')
|
|
285
|
+
iframe = iframe.replace("\\", "") if iframe else None
|
|
300
286
|
|
|
301
287
|
if not iframe:
|
|
302
288
|
continue
|