KekikStream 2.1.9__py3-none-any.whl → 2.2.7__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/Extractors/CloseLoad.py +7 -8
- KekikStream/Extractors/Filemoon.py +7 -6
- KekikStream/Extractors/JFVid.py +40 -0
- KekikStream/Extractors/MolyStream.py +6 -5
- KekikStream/Extractors/PlayerFilmIzle.py +6 -2
- KekikStream/Extractors/VidHide.py +0 -1
- KekikStream/Extractors/VidMoly.py +17 -9
- KekikStream/Plugins/BelgeselX.py +39 -20
- KekikStream/Plugins/DiziBox.py +115 -59
- KekikStream/Plugins/DiziPal.py +87 -40
- KekikStream/Plugins/DiziYou.py +105 -64
- KekikStream/Plugins/Dizilla.py +58 -29
- KekikStream/Plugins/FilmBip.py +60 -31
- KekikStream/Plugins/FilmMakinesi.py +75 -51
- KekikStream/Plugins/FilmModu.py +73 -36
- KekikStream/Plugins/FullHDFilm.py +82 -48
- KekikStream/Plugins/FullHDFilmizlesene.py +94 -39
- KekikStream/Plugins/HDFilmCehennemi.py +79 -54
- KekikStream/Plugins/JetFilmizle.py +98 -51
- KekikStream/Plugins/KultFilmler.py +64 -34
- KekikStream/Plugins/RoketDizi.py +43 -26
- KekikStream/Plugins/SelcukFlix.py +27 -14
- KekikStream/Plugins/SetFilmIzle.py +74 -43
- KekikStream/Plugins/SezonlukDizi.py +102 -46
- KekikStream/Plugins/Sinefy.py +130 -101
- KekikStream/Plugins/SinemaCX.py +82 -37
- KekikStream/Plugins/Sinezy.py +61 -47
- KekikStream/Plugins/SuperFilmGeldi.py +72 -36
- KekikStream/Plugins/UgurFilm.py +72 -34
- KekikStream/requirements.txt +1 -1
- {kekikstream-2.1.9.dist-info → kekikstream-2.2.7.dist-info}/METADATA +40 -32
- {kekikstream-2.1.9.dist-info → kekikstream-2.2.7.dist-info}/RECORD +36 -35
- {kekikstream-2.1.9.dist-info → kekikstream-2.2.7.dist-info}/WHEEL +0 -0
- {kekikstream-2.1.9.dist-info → kekikstream-2.2.7.dist-info}/entry_points.txt +0 -0
- {kekikstream-2.1.9.dist-info → kekikstream-2.2.7.dist-info}/licenses/LICENSE +0 -0
- {kekikstream-2.1.9.dist-info → kekikstream-2.2.7.dist-info}/top_level.txt +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
2
|
|
|
3
|
-
from KekikStream.Core
|
|
4
|
-
from
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, SeriesInfo, Episode, ExtractResult, Subtitle
|
|
4
|
+
from selectolax.parser import HTMLParser
|
|
5
5
|
import re, base64
|
|
6
6
|
|
|
7
7
|
class KultFilmler(PluginBase):
|
|
@@ -38,67 +38,95 @@ class KultFilmler(PluginBase):
|
|
|
38
38
|
|
|
39
39
|
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
40
40
|
istek = await self.httpx.get(url)
|
|
41
|
-
secici =
|
|
41
|
+
secici = HTMLParser(istek.text)
|
|
42
42
|
|
|
43
43
|
results = []
|
|
44
44
|
for veri in secici.css("div.col-md-12 div.movie-box"):
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
img_el = veri.css_first("div.img img")
|
|
46
|
+
link_el = veri.css_first("a")
|
|
47
|
+
|
|
48
|
+
title = img_el.attrs.get("alt") if img_el else None
|
|
49
|
+
href = link_el.attrs.get("href") if link_el else None
|
|
50
|
+
poster = img_el.attrs.get("src") if img_el else None
|
|
48
51
|
|
|
49
52
|
if title and href:
|
|
50
53
|
results.append(MainPageResult(
|
|
51
54
|
category = category,
|
|
52
55
|
title = title,
|
|
53
|
-
url = href,
|
|
54
|
-
poster = poster,
|
|
56
|
+
url = self.fix_url(href),
|
|
57
|
+
poster = self.fix_url(poster) if poster else None,
|
|
55
58
|
))
|
|
56
59
|
|
|
57
60
|
return results
|
|
58
61
|
|
|
59
62
|
async def search(self, query: str) -> list[SearchResult]:
|
|
60
63
|
istek = await self.httpx.get(f"{self.main_url}?s={query}")
|
|
61
|
-
secici =
|
|
64
|
+
secici = HTMLParser(istek.text)
|
|
62
65
|
|
|
63
66
|
results = []
|
|
64
67
|
for veri in secici.css("div.movie-box"):
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
+
img_el = veri.css_first("div.img img")
|
|
69
|
+
link_el = veri.css_first("a")
|
|
70
|
+
|
|
71
|
+
title = img_el.attrs.get("alt") if img_el else None
|
|
72
|
+
href = link_el.attrs.get("href") if link_el else None
|
|
73
|
+
poster = img_el.attrs.get("src") if img_el else None
|
|
68
74
|
|
|
69
75
|
if title and href:
|
|
70
76
|
results.append(SearchResult(
|
|
71
77
|
title = title,
|
|
72
|
-
url = href,
|
|
73
|
-
poster = poster,
|
|
78
|
+
url = self.fix_url(href),
|
|
79
|
+
poster = self.fix_url(poster) if poster else None,
|
|
74
80
|
))
|
|
75
81
|
|
|
76
82
|
return results
|
|
77
83
|
|
|
78
84
|
async def load_item(self, url: str) -> MovieInfo | SeriesInfo:
|
|
79
85
|
istek = await self.httpx.get(url)
|
|
80
|
-
secici =
|
|
86
|
+
secici = HTMLParser(istek.text)
|
|
87
|
+
|
|
88
|
+
film_img = secici.css_first("div.film-bilgileri img")
|
|
89
|
+
og_title = secici.css_first("[property='og:title']")
|
|
90
|
+
og_image = secici.css_first("[property='og:image']")
|
|
91
|
+
|
|
92
|
+
title = (film_img.attrs.get("alt") if film_img else None) or (og_title.attrs.get("content") if og_title else None)
|
|
93
|
+
poster = self.fix_url(og_image.attrs.get("content")) if og_image else None
|
|
94
|
+
|
|
95
|
+
desc_el = secici.css_first("div.description")
|
|
96
|
+
description = desc_el.text(strip=True) if desc_el else None
|
|
97
|
+
|
|
98
|
+
tags = [a.text(strip=True) for a in secici.css("ul.post-categories a") if a.text(strip=True)]
|
|
81
99
|
|
|
82
|
-
title = secici.css("div.film-bilgileri img::attr(alt)").get() or secici.css("[property='og:title']::attr(content)").get()
|
|
83
|
-
poster = self.fix_url(secici.css("[property='og:image']::attr(content)").get())
|
|
84
|
-
description = secici.css("div.description::text").get()
|
|
85
|
-
tags = secici.css("ul.post-categories a::text").getall()
|
|
86
100
|
# HTML analizine göre güncellenen alanlar
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
101
|
+
year_el = secici.css_first("li.release span a")
|
|
102
|
+
year = year_el.text(strip=True) if year_el else None
|
|
103
|
+
|
|
104
|
+
time_el = secici.css_first("li.time span")
|
|
105
|
+
duration = None
|
|
106
|
+
if time_el:
|
|
107
|
+
time_text = time_el.text(strip=True)
|
|
108
|
+
dur_match = re.search(r"(\d+)", time_text)
|
|
109
|
+
duration = dur_match.group(1) if dur_match else None
|
|
110
|
+
|
|
111
|
+
rating_el = secici.css_first("div.imdb-count")
|
|
112
|
+
rating = rating_el.text(strip=True) if rating_el else None
|
|
113
|
+
|
|
114
|
+
actors = [a.text(strip=True) for a in secici.css("div.actors a") if a.text(strip=True)]
|
|
93
115
|
|
|
94
116
|
# Dizi mi kontrol et
|
|
95
117
|
if "/dizi/" in url:
|
|
96
118
|
episodes = []
|
|
97
119
|
for bolum in secici.css("div.episode-box"):
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
120
|
+
name_link = bolum.css_first("div.name a")
|
|
121
|
+
ep_href = name_link.attrs.get("href") if name_link else None
|
|
122
|
+
|
|
123
|
+
ssn_el = bolum.css_first("span.episodetitle")
|
|
124
|
+
ssn_detail = ssn_el.text(strip=True) if ssn_el else ""
|
|
125
|
+
|
|
126
|
+
ep_b_el = bolum.css_first("span.episodetitle b")
|
|
127
|
+
ep_detail = ep_b_el.text(strip=True) if ep_b_el else ""
|
|
128
|
+
|
|
129
|
+
ep_name = f"{ssn_detail} - {ep_detail}"
|
|
102
130
|
|
|
103
131
|
if ep_href:
|
|
104
132
|
ep_season = re.search(r"(\d+)\.", ssn_detail)
|
|
@@ -108,7 +136,7 @@ class KultFilmler(PluginBase):
|
|
|
108
136
|
season = int(ep_season[1]) if ep_season else 1,
|
|
109
137
|
episode = int(ep_episode[1]) if ep_episode else 1,
|
|
110
138
|
title = ep_name.strip(" -"),
|
|
111
|
-
url = ep_href,
|
|
139
|
+
url = self.fix_url(ep_href),
|
|
112
140
|
))
|
|
113
141
|
|
|
114
142
|
return SeriesInfo(
|
|
@@ -150,8 +178,9 @@ class KultFilmler(PluginBase):
|
|
|
150
178
|
|
|
151
179
|
try:
|
|
152
180
|
decoded = base64.b64decode(atob).decode("utf-8")
|
|
153
|
-
secici =
|
|
154
|
-
|
|
181
|
+
secici = HTMLParser(decoded)
|
|
182
|
+
iframe_el = secici.css_first("iframe")
|
|
183
|
+
return self.fix_url(iframe_el.attrs.get("src")) if iframe_el else ""
|
|
155
184
|
except Exception:
|
|
156
185
|
return ""
|
|
157
186
|
|
|
@@ -162,7 +191,7 @@ class KultFilmler(PluginBase):
|
|
|
162
191
|
|
|
163
192
|
async def load_links(self, url: str) -> list[ExtractResult]:
|
|
164
193
|
istek = await self.httpx.get(url)
|
|
165
|
-
secici =
|
|
194
|
+
secici = HTMLParser(istek.text)
|
|
166
195
|
|
|
167
196
|
iframes = set()
|
|
168
197
|
|
|
@@ -173,7 +202,8 @@ class KultFilmler(PluginBase):
|
|
|
173
202
|
|
|
174
203
|
# Alternatif player'lar
|
|
175
204
|
for player in secici.css("div.container#player"):
|
|
176
|
-
|
|
205
|
+
iframe_el = player.css_first("iframe")
|
|
206
|
+
alt_iframe = self.fix_url(iframe_el.attrs.get("src")) if iframe_el else None
|
|
177
207
|
if alt_iframe:
|
|
178
208
|
alt_istek = await self.httpx.get(alt_iframe)
|
|
179
209
|
alt_frame = self._get_iframe(alt_istek.text)
|
KekikStream/Plugins/RoketDizi.py
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
2
|
|
|
3
|
-
from KekikStream.Core
|
|
4
|
-
from
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, SeriesInfo, Episode, ExtractResult, MovieInfo
|
|
4
|
+
from selectolax.parser import HTMLParser
|
|
5
5
|
import re, base64, json
|
|
6
6
|
|
|
7
7
|
class RoketDizi(PluginBase):
|
|
@@ -24,21 +24,26 @@ class RoketDizi(PluginBase):
|
|
|
24
24
|
|
|
25
25
|
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
26
26
|
istek = await self.httpx.get(f"{url}?&page={page}")
|
|
27
|
-
secici =
|
|
27
|
+
secici = HTMLParser(istek.text)
|
|
28
28
|
|
|
29
29
|
results = []
|
|
30
30
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
# Use div.new-added-list to find the container, then get items
|
|
32
|
+
for item in secici.css("div.new-added-list > span"):
|
|
33
|
+
title_el = item.css_first("span.line-clamp-1")
|
|
34
|
+
link_el = item.css_first("a")
|
|
35
|
+
img_el = item.css_first("img")
|
|
36
|
+
|
|
37
|
+
title = title_el.text(strip=True) if title_el else None
|
|
38
|
+
href = link_el.attrs.get("href") if link_el else None
|
|
39
|
+
poster = img_el.attrs.get("src") if img_el else None
|
|
35
40
|
|
|
36
41
|
if title and href:
|
|
37
42
|
results.append(MainPageResult(
|
|
38
43
|
category = category,
|
|
39
44
|
title = self.clean_title(title),
|
|
40
45
|
url = self.fix_url(href),
|
|
41
|
-
poster = self.fix_url(poster)
|
|
46
|
+
poster = self.fix_url(poster) if poster else None
|
|
42
47
|
))
|
|
43
48
|
|
|
44
49
|
return results
|
|
@@ -87,20 +92,29 @@ class RoketDizi(PluginBase):
|
|
|
87
92
|
async def load_item(self, url: str) -> SeriesInfo:
|
|
88
93
|
# Note: Handling both Movie and Series logic in one, returning SeriesInfo generally or MovieInfo
|
|
89
94
|
resp = await self.httpx.get(url)
|
|
90
|
-
sel =
|
|
95
|
+
sel = HTMLParser(resp.text)
|
|
96
|
+
html_text = resp.text
|
|
97
|
+
|
|
98
|
+
title_el = sel.css_first("h1.text-white")
|
|
99
|
+
title = title_el.text(strip=True) if title_el else None
|
|
91
100
|
|
|
92
|
-
|
|
93
|
-
poster
|
|
94
|
-
|
|
101
|
+
poster_el = sel.css_first("div.w-full.page-top img")
|
|
102
|
+
poster = poster_el.attrs.get("src") if poster_el else None
|
|
103
|
+
|
|
104
|
+
desc_el = sel.css_first("div.mt-2.text-sm")
|
|
105
|
+
description = desc_el.text(strip=True) if desc_el else None
|
|
95
106
|
|
|
96
107
|
# Tags - genre bilgileri (Detaylar bölümünde)
|
|
97
108
|
tags = []
|
|
98
|
-
|
|
99
|
-
if
|
|
100
|
-
|
|
109
|
+
genre_el = sel.css_first("h3.text-white.opacity-90")
|
|
110
|
+
if genre_el:
|
|
111
|
+
genre_text = genre_el.text(strip=True)
|
|
112
|
+
if genre_text:
|
|
113
|
+
tags = [t.strip() for t in genre_text.split(",")]
|
|
101
114
|
|
|
102
115
|
# Rating
|
|
103
|
-
|
|
116
|
+
rating_el = sel.css_first("span.text-white.text-sm.font-bold")
|
|
117
|
+
rating = rating_el.text(strip=True) if rating_el else None
|
|
104
118
|
|
|
105
119
|
# Year ve Actors - Detaylar (Details) bölümünden
|
|
106
120
|
year = None
|
|
@@ -109,14 +123,13 @@ class RoketDizi(PluginBase):
|
|
|
109
123
|
# Detaylar bölümündeki tüm flex-col div'leri al
|
|
110
124
|
detail_items = sel.css("div.flex.flex-col")
|
|
111
125
|
for item in detail_items:
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
126
|
+
label_el = item.css_first("span.text-base")
|
|
127
|
+
value_el = item.css_first("span.text-sm.opacity-90")
|
|
128
|
+
|
|
129
|
+
label = label_el.text(strip=True) if label_el else None
|
|
130
|
+
value = value_el.text(strip=True) if value_el else None
|
|
115
131
|
|
|
116
132
|
if label and value:
|
|
117
|
-
label = label.strip()
|
|
118
|
-
value = value.strip()
|
|
119
|
-
|
|
120
133
|
# Yayın tarihi (yıl)
|
|
121
134
|
if label == "Yayın tarihi":
|
|
122
135
|
# "16 Ekim 2018" formatından yılı çıkar
|
|
@@ -130,7 +143,7 @@ class RoketDizi(PluginBase):
|
|
|
130
143
|
actors.append(value)
|
|
131
144
|
|
|
132
145
|
# Check urls for episodes
|
|
133
|
-
all_urls = re.findall(r'"url":"([^"]*)"',
|
|
146
|
+
all_urls = re.findall(r'"url":"([^"]*)"', html_text)
|
|
134
147
|
is_series = any("bolum-" in u for u in all_urls)
|
|
135
148
|
|
|
136
149
|
episodes = []
|
|
@@ -160,7 +173,7 @@ class RoketDizi(PluginBase):
|
|
|
160
173
|
return SeriesInfo(
|
|
161
174
|
title = title,
|
|
162
175
|
url = url,
|
|
163
|
-
poster = self.fix_url(poster),
|
|
176
|
+
poster = self.fix_url(poster) if poster else None,
|
|
164
177
|
description = description,
|
|
165
178
|
tags = tags,
|
|
166
179
|
rating = rating,
|
|
@@ -171,9 +184,13 @@ class RoketDizi(PluginBase):
|
|
|
171
184
|
|
|
172
185
|
async def load_links(self, url: str) -> list[ExtractResult]:
|
|
173
186
|
resp = await self.httpx.get(url)
|
|
174
|
-
sel =
|
|
187
|
+
sel = HTMLParser(resp.text)
|
|
175
188
|
|
|
176
|
-
|
|
189
|
+
next_data_el = sel.css_first("script#__NEXT_DATA__")
|
|
190
|
+
if not next_data_el:
|
|
191
|
+
return []
|
|
192
|
+
|
|
193
|
+
next_data = next_data_el.text(strip=True)
|
|
177
194
|
if not next_data:
|
|
178
195
|
return []
|
|
179
196
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
2
|
|
|
3
|
-
from KekikStream.Core
|
|
4
|
-
from
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, SeriesInfo, Episode, ExtractResult
|
|
4
|
+
from selectolax.parser import HTMLParser
|
|
5
5
|
import re, base64, json, urllib.parse
|
|
6
6
|
|
|
7
7
|
class SelcukFlix(PluginBase):
|
|
@@ -34,13 +34,17 @@ class SelcukFlix(PluginBase):
|
|
|
34
34
|
if "tum-bolumler" in url:
|
|
35
35
|
try:
|
|
36
36
|
resp = await self.httpx.get(url)
|
|
37
|
-
sel =
|
|
37
|
+
sel = HTMLParser(resp.text)
|
|
38
38
|
|
|
39
39
|
for item in sel.css("div.col-span-3 a"):
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
40
|
+
name_el = item.css_first("h2")
|
|
41
|
+
ep_el = item.css_first("div.opacity-80")
|
|
42
|
+
img_el = item.css_first("div.image img")
|
|
43
|
+
|
|
44
|
+
name = name_el.text(strip=True) if name_el else None
|
|
45
|
+
ep_info = ep_el.text(strip=True) if ep_el else None
|
|
46
|
+
href = item.attrs.get("href")
|
|
47
|
+
poster = img_el.attrs.get("src") if img_el else None
|
|
44
48
|
|
|
45
49
|
if name and href:
|
|
46
50
|
title = f"{name} - {ep_info}" if ep_info else name
|
|
@@ -53,7 +57,7 @@ class SelcukFlix(PluginBase):
|
|
|
53
57
|
category = category,
|
|
54
58
|
title = title,
|
|
55
59
|
url = final_url,
|
|
56
|
-
poster = self.fix_url(poster)
|
|
60
|
+
poster = self.fix_url(poster) if poster else None
|
|
57
61
|
))
|
|
58
62
|
except Exception:
|
|
59
63
|
pass
|
|
@@ -184,9 +188,13 @@ class SelcukFlix(PluginBase):
|
|
|
184
188
|
|
|
185
189
|
async def load_item(self, url: str) -> MovieInfo | SeriesInfo:
|
|
186
190
|
resp = await self.httpx.get(url)
|
|
187
|
-
sel =
|
|
191
|
+
sel = HTMLParser(resp.text)
|
|
192
|
+
|
|
193
|
+
next_data_el = sel.css_first("script#__NEXT_DATA__")
|
|
194
|
+
if not next_data_el:
|
|
195
|
+
return None
|
|
188
196
|
|
|
189
|
-
next_data =
|
|
197
|
+
next_data = next_data_el.text(strip=True)
|
|
190
198
|
if not next_data:
|
|
191
199
|
return None
|
|
192
200
|
|
|
@@ -258,9 +266,13 @@ class SelcukFlix(PluginBase):
|
|
|
258
266
|
|
|
259
267
|
async def load_links(self, url: str) -> list[ExtractResult]:
|
|
260
268
|
resp = await self.httpx.get(url)
|
|
261
|
-
sel =
|
|
269
|
+
sel = HTMLParser(resp.text)
|
|
262
270
|
|
|
263
|
-
|
|
271
|
+
next_data_el = sel.css_first("script#__NEXT_DATA__")
|
|
272
|
+
if not next_data_el:
|
|
273
|
+
return []
|
|
274
|
+
|
|
275
|
+
next_data = next_data_el.text(strip=True)
|
|
264
276
|
if not next_data:
|
|
265
277
|
return []
|
|
266
278
|
|
|
@@ -300,8 +312,9 @@ class SelcukFlix(PluginBase):
|
|
|
300
312
|
source_content = res[0].get("source_content") or res[0].get("sourceContent")
|
|
301
313
|
|
|
302
314
|
if source_content:
|
|
303
|
-
iframe_sel =
|
|
304
|
-
|
|
315
|
+
iframe_sel = HTMLParser(source_content)
|
|
316
|
+
iframe_el = iframe_sel.css_first("iframe")
|
|
317
|
+
iframe_src = iframe_el.attrs.get("src") if iframe_el else None
|
|
305
318
|
if iframe_src:
|
|
306
319
|
iframe_src = self.fix_url(iframe_src)
|
|
307
320
|
# Hotlinger domain değişimi (Kotlin referansı)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
2
|
|
|
3
|
-
from KekikStream.Core
|
|
4
|
-
from
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, SeriesInfo, Episode, ExtractResult
|
|
4
|
+
from selectolax.parser import HTMLParser
|
|
5
5
|
import re, json
|
|
6
6
|
|
|
7
7
|
class SetFilmIzle(PluginBase):
|
|
@@ -53,18 +53,22 @@ class SetFilmIzle(PluginBase):
|
|
|
53
53
|
|
|
54
54
|
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
55
55
|
istek = self.cloudscraper.get(url)
|
|
56
|
-
secici =
|
|
56
|
+
secici = HTMLParser(istek.text)
|
|
57
57
|
|
|
58
58
|
results = []
|
|
59
59
|
for item in secici.css("div.items article"):
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
title_el = item.css_first("h2")
|
|
61
|
+
link_el = item.css_first("a")
|
|
62
|
+
img_el = item.css_first("img")
|
|
63
|
+
|
|
64
|
+
title = title_el.text(strip=True) if title_el else None
|
|
65
|
+
href = link_el.attrs.get("href") if link_el else None
|
|
66
|
+
poster = img_el.attrs.get("data-src") if img_el else None
|
|
63
67
|
|
|
64
68
|
if title and href:
|
|
65
69
|
results.append(MainPageResult(
|
|
66
70
|
category = category,
|
|
67
|
-
title = title
|
|
71
|
+
title = title,
|
|
68
72
|
url = self.fix_url(href),
|
|
69
73
|
poster = self.fix_url(poster) if poster else None
|
|
70
74
|
))
|
|
@@ -95,17 +99,21 @@ class SetFilmIzle(PluginBase):
|
|
|
95
99
|
except:
|
|
96
100
|
return []
|
|
97
101
|
|
|
98
|
-
secici =
|
|
102
|
+
secici = HTMLParser(html)
|
|
99
103
|
results = []
|
|
100
104
|
|
|
101
105
|
for item in secici.css("div.items article"):
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
106
|
+
title_el = item.css_first("h2")
|
|
107
|
+
link_el = item.css_first("a")
|
|
108
|
+
img_el = item.css_first("img")
|
|
109
|
+
|
|
110
|
+
title = title_el.text(strip=True) if title_el else None
|
|
111
|
+
href = link_el.attrs.get("href") if link_el else None
|
|
112
|
+
poster = img_el.attrs.get("data-src") if img_el else None
|
|
105
113
|
|
|
106
114
|
if title and href:
|
|
107
115
|
results.append(SearchResult(
|
|
108
|
-
title = title
|
|
116
|
+
title = title,
|
|
109
117
|
url = self.fix_url(href),
|
|
110
118
|
poster = self.fix_url(poster) if poster else None
|
|
111
119
|
))
|
|
@@ -114,50 +122,73 @@ class SetFilmIzle(PluginBase):
|
|
|
114
122
|
|
|
115
123
|
async def load_item(self, url: str) -> MovieInfo | SeriesInfo:
|
|
116
124
|
istek = await self.httpx.get(url)
|
|
117
|
-
secici =
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
125
|
+
secici = HTMLParser(istek.text)
|
|
126
|
+
html_text = istek.text
|
|
127
|
+
|
|
128
|
+
title_el = secici.css_first("h1") or secici.css_first(".titles h1")
|
|
129
|
+
raw_title = title_el.text(strip=True) if title_el else ""
|
|
130
|
+
if not raw_title:
|
|
131
|
+
# Alternatif title yeri
|
|
132
|
+
title_meta = secici.css_first("meta[property='og:title']")
|
|
133
|
+
raw_title = title_meta.attrs.get("content", "") if title_meta else ""
|
|
134
|
+
|
|
135
|
+
title = re.sub(r"\s*izle.*$", "", raw_title, flags=re.IGNORECASE).strip()
|
|
136
|
+
|
|
137
|
+
poster_el = secici.css_first("div.poster img")
|
|
138
|
+
poster = poster_el.attrs.get("src") if poster_el else None
|
|
139
|
+
|
|
140
|
+
desc_el = secici.css_first("div.wp-content p")
|
|
141
|
+
description = desc_el.text(strip=True) if desc_el else None
|
|
142
|
+
|
|
143
|
+
year_el = secici.css_first("div.extra span.C a")
|
|
144
|
+
year = None
|
|
145
|
+
if year_el:
|
|
146
|
+
year_text = year_el.text(strip=True)
|
|
147
|
+
year_match = re.search(r"\d{4}", year_text)
|
|
126
148
|
year = year_match.group() if year_match else None
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
149
|
+
|
|
150
|
+
tags = [a.text(strip=True) for a in secici.css("div.sgeneros a") if a.text(strip=True)]
|
|
151
|
+
|
|
152
|
+
duration_el = secici.css_first("span.runtime")
|
|
153
|
+
duration = None
|
|
154
|
+
if duration_el:
|
|
155
|
+
duration_text = duration_el.text(strip=True)
|
|
156
|
+
dur_match = re.search(r"\d+", duration_text)
|
|
131
157
|
duration = int(dur_match.group()) if dur_match else None
|
|
132
158
|
|
|
133
|
-
actors = [span.
|
|
159
|
+
actors = [span.text(strip=True) for span in secici.css("span.valor a > span") if span.text(strip=True)]
|
|
134
160
|
|
|
135
|
-
trailer_match = re.search(r'embed/([^?]*)\?rel',
|
|
161
|
+
trailer_match = re.search(r'embed/([^?]*)\?rel', html_text)
|
|
136
162
|
trailer = f"https://www.youtube.com/embed/{trailer_match.group(1)}" if trailer_match else None
|
|
137
163
|
|
|
138
164
|
# Dizi mi film mi kontrol et
|
|
139
165
|
is_series = "/dizi/" in url
|
|
140
166
|
|
|
141
167
|
if is_series:
|
|
142
|
-
|
|
143
|
-
if
|
|
168
|
+
year_link_el = secici.css_first("a[href*='/yil/']")
|
|
169
|
+
if year_link_el:
|
|
170
|
+
year_elem = year_link_el.text(strip=True)
|
|
144
171
|
year_match = re.search(r"\d{4}", year_elem)
|
|
145
172
|
year = year_match.group() if year_match else year
|
|
146
173
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
174
|
+
# Duration from info section
|
|
175
|
+
for span in secici.css("div#info span"):
|
|
176
|
+
span_text = span.text(strip=True) if span.text() else ""
|
|
177
|
+
if "Dakika" in span_text:
|
|
178
|
+
dur_match = re.search(r"\d+", span_text)
|
|
179
|
+
duration = int(dur_match.group()) if dur_match else duration
|
|
180
|
+
break
|
|
151
181
|
|
|
152
182
|
episodes = []
|
|
153
183
|
for ep_item in secici.css("div#episodes ul.episodios li"):
|
|
154
|
-
|
|
155
|
-
|
|
184
|
+
ep_title_el = ep_item.css_first("h4.episodiotitle a")
|
|
185
|
+
ep_href = ep_title_el.attrs.get("href") if ep_title_el else None
|
|
186
|
+
ep_name = ep_title_el.text(strip=True) if ep_title_el else None
|
|
156
187
|
|
|
157
188
|
if not ep_href or not ep_name:
|
|
158
189
|
continue
|
|
159
190
|
|
|
160
|
-
ep_detail = ep_name
|
|
191
|
+
ep_detail = ep_name
|
|
161
192
|
season_match = re.search(r"(\d+)\.\s*Sezon", ep_detail)
|
|
162
193
|
episode_match = re.search(r"Sezon\s+(\d+)\.\s*Bölüm", ep_detail)
|
|
163
194
|
|
|
@@ -167,7 +198,7 @@ class SetFilmIzle(PluginBase):
|
|
|
167
198
|
episodes.append(Episode(
|
|
168
199
|
season = ep_season,
|
|
169
200
|
episode = ep_episode,
|
|
170
|
-
title = ep_name
|
|
201
|
+
title = ep_name,
|
|
171
202
|
url = self.fix_url(ep_href)
|
|
172
203
|
))
|
|
173
204
|
|
|
@@ -175,7 +206,7 @@ class SetFilmIzle(PluginBase):
|
|
|
175
206
|
url = url,
|
|
176
207
|
poster = self.fix_url(poster) if poster else None,
|
|
177
208
|
title = title,
|
|
178
|
-
description = description
|
|
209
|
+
description = description,
|
|
179
210
|
tags = tags,
|
|
180
211
|
year = year,
|
|
181
212
|
duration = duration,
|
|
@@ -187,7 +218,7 @@ class SetFilmIzle(PluginBase):
|
|
|
187
218
|
url = url,
|
|
188
219
|
poster = self.fix_url(poster) if poster else None,
|
|
189
220
|
title = title,
|
|
190
|
-
description = description
|
|
221
|
+
description = description,
|
|
191
222
|
tags = tags,
|
|
192
223
|
year = year,
|
|
193
224
|
duration = duration,
|
|
@@ -196,7 +227,7 @@ class SetFilmIzle(PluginBase):
|
|
|
196
227
|
|
|
197
228
|
async def load_links(self, url: str) -> list[ExtractResult]:
|
|
198
229
|
istek = await self.httpx.get(url)
|
|
199
|
-
secici =
|
|
230
|
+
secici = HTMLParser(istek.text)
|
|
200
231
|
|
|
201
232
|
nonce = self._get_nonce("video_nonce", referer=url)
|
|
202
233
|
|
|
@@ -209,9 +240,9 @@ class SetFilmIzle(PluginBase):
|
|
|
209
240
|
|
|
210
241
|
links = []
|
|
211
242
|
for player in secici.css("nav.player a"):
|
|
212
|
-
source_id = player.
|
|
213
|
-
player_name = player.
|
|
214
|
-
part_key = player.
|
|
243
|
+
source_id = player.attrs.get("data-post-id")
|
|
244
|
+
player_name = player.attrs.get("data-player-name")
|
|
245
|
+
part_key = player.attrs.get("data-part-key")
|
|
215
246
|
|
|
216
247
|
if not source_id or "event" in source_id or source_id == "":
|
|
217
248
|
continue
|