KekikStream 2.2.3__py3-none-any.whl → 2.2.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/Extractors/CloseLoad.py +7 -8
- KekikStream/Extractors/Filemoon.py +7 -6
- KekikStream/Extractors/MolyStream.py +6 -5
- 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 +57 -28
- 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 +78 -53
- KekikStream/Plugins/JetFilmizle.py +78 -50
- KekikStream/Plugins/KultFilmler.py +64 -34
- KekikStream/Plugins/RoketDizi.py +43 -26
- KekikStream/Plugins/SelcukFlix.py +27 -14
- KekikStream/Plugins/SetFilmIzle.py +69 -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.2.3.dist-info → kekikstream-2.2.5.dist-info}/METADATA +2 -2
- {kekikstream-2.2.3.dist-info → kekikstream-2.2.5.dist-info}/RECORD +34 -34
- {kekikstream-2.2.3.dist-info → kekikstream-2.2.5.dist-info}/WHEEL +0 -0
- {kekikstream-2.2.3.dist-info → kekikstream-2.2.5.dist-info}/entry_points.txt +0 -0
- {kekikstream-2.2.3.dist-info → kekikstream-2.2.5.dist-info}/licenses/LICENSE +0 -0
- {kekikstream-2.2.3.dist-info → kekikstream-2.2.5.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,68 @@ 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")
|
|
129
|
+
raw_title = title_el.text(strip=True) if title_el else ""
|
|
130
|
+
title = re.sub(r"\s*izle.*$", "", raw_title, flags=re.IGNORECASE).strip()
|
|
131
|
+
|
|
132
|
+
poster_el = secici.css_first("div.poster img")
|
|
133
|
+
poster = poster_el.attrs.get("src") if poster_el else None
|
|
134
|
+
|
|
135
|
+
desc_el = secici.css_first("div.wp-content p")
|
|
136
|
+
description = desc_el.text(strip=True) if desc_el else None
|
|
137
|
+
|
|
138
|
+
year_el = secici.css_first("div.extra span.C a")
|
|
139
|
+
year = None
|
|
140
|
+
if year_el:
|
|
141
|
+
year_text = year_el.text(strip=True)
|
|
142
|
+
year_match = re.search(r"\d{4}", year_text)
|
|
126
143
|
year = year_match.group() if year_match else None
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
144
|
+
|
|
145
|
+
tags = [a.text(strip=True) for a in secici.css("div.sgeneros a") if a.text(strip=True)]
|
|
146
|
+
|
|
147
|
+
duration_el = secici.css_first("span.runtime")
|
|
148
|
+
duration = None
|
|
149
|
+
if duration_el:
|
|
150
|
+
duration_text = duration_el.text(strip=True)
|
|
151
|
+
dur_match = re.search(r"\d+", duration_text)
|
|
131
152
|
duration = int(dur_match.group()) if dur_match else None
|
|
132
153
|
|
|
133
|
-
actors = [span.
|
|
154
|
+
actors = [span.text(strip=True) for span in secici.css("span.valor a > span") if span.text(strip=True)]
|
|
134
155
|
|
|
135
|
-
trailer_match = re.search(r'embed/([^?]*)\?rel',
|
|
156
|
+
trailer_match = re.search(r'embed/([^?]*)\?rel', html_text)
|
|
136
157
|
trailer = f"https://www.youtube.com/embed/{trailer_match.group(1)}" if trailer_match else None
|
|
137
158
|
|
|
138
159
|
# Dizi mi film mi kontrol et
|
|
139
160
|
is_series = "/dizi/" in url
|
|
140
161
|
|
|
141
162
|
if is_series:
|
|
142
|
-
|
|
143
|
-
if
|
|
163
|
+
year_link_el = secici.css_first("a[href*='/yil/']")
|
|
164
|
+
if year_link_el:
|
|
165
|
+
year_elem = year_link_el.text(strip=True)
|
|
144
166
|
year_match = re.search(r"\d{4}", year_elem)
|
|
145
167
|
year = year_match.group() if year_match else year
|
|
146
168
|
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
169
|
+
# Duration from info section
|
|
170
|
+
for span in secici.css("div#info span"):
|
|
171
|
+
span_text = span.text(strip=True) if span.text() else ""
|
|
172
|
+
if "Dakika" in span_text:
|
|
173
|
+
dur_match = re.search(r"\d+", span_text)
|
|
174
|
+
duration = int(dur_match.group()) if dur_match else duration
|
|
175
|
+
break
|
|
151
176
|
|
|
152
177
|
episodes = []
|
|
153
178
|
for ep_item in secici.css("div#episodes ul.episodios li"):
|
|
154
|
-
|
|
155
|
-
|
|
179
|
+
ep_title_el = ep_item.css_first("h4.episodiotitle a")
|
|
180
|
+
ep_href = ep_title_el.attrs.get("href") if ep_title_el else None
|
|
181
|
+
ep_name = ep_title_el.text(strip=True) if ep_title_el else None
|
|
156
182
|
|
|
157
183
|
if not ep_href or not ep_name:
|
|
158
184
|
continue
|
|
159
185
|
|
|
160
|
-
ep_detail = ep_name
|
|
186
|
+
ep_detail = ep_name
|
|
161
187
|
season_match = re.search(r"(\d+)\.\s*Sezon", ep_detail)
|
|
162
188
|
episode_match = re.search(r"Sezon\s+(\d+)\.\s*Bölüm", ep_detail)
|
|
163
189
|
|
|
@@ -167,7 +193,7 @@ class SetFilmIzle(PluginBase):
|
|
|
167
193
|
episodes.append(Episode(
|
|
168
194
|
season = ep_season,
|
|
169
195
|
episode = ep_episode,
|
|
170
|
-
title = ep_name
|
|
196
|
+
title = ep_name,
|
|
171
197
|
url = self.fix_url(ep_href)
|
|
172
198
|
))
|
|
173
199
|
|
|
@@ -175,7 +201,7 @@ class SetFilmIzle(PluginBase):
|
|
|
175
201
|
url = url,
|
|
176
202
|
poster = self.fix_url(poster) if poster else None,
|
|
177
203
|
title = title,
|
|
178
|
-
description = description
|
|
204
|
+
description = description,
|
|
179
205
|
tags = tags,
|
|
180
206
|
year = year,
|
|
181
207
|
duration = duration,
|
|
@@ -187,7 +213,7 @@ class SetFilmIzle(PluginBase):
|
|
|
187
213
|
url = url,
|
|
188
214
|
poster = self.fix_url(poster) if poster else None,
|
|
189
215
|
title = title,
|
|
190
|
-
description = description
|
|
216
|
+
description = description,
|
|
191
217
|
tags = tags,
|
|
192
218
|
year = year,
|
|
193
219
|
duration = duration,
|
|
@@ -196,7 +222,7 @@ class SetFilmIzle(PluginBase):
|
|
|
196
222
|
|
|
197
223
|
async def load_links(self, url: str) -> list[ExtractResult]:
|
|
198
224
|
istek = await self.httpx.get(url)
|
|
199
|
-
secici =
|
|
225
|
+
secici = HTMLParser(istek.text)
|
|
200
226
|
|
|
201
227
|
nonce = self._get_nonce("video_nonce", referer=url)
|
|
202
228
|
|
|
@@ -209,9 +235,9 @@ class SetFilmIzle(PluginBase):
|
|
|
209
235
|
|
|
210
236
|
links = []
|
|
211
237
|
for player in secici.css("nav.player a"):
|
|
212
|
-
source_id = player.
|
|
213
|
-
player_name = player.
|
|
214
|
-
part_key = player.
|
|
238
|
+
source_id = player.attrs.get("data-post-id")
|
|
239
|
+
player_name = player.attrs.get("data-player-name")
|
|
240
|
+
part_key = player.attrs.get("data-part-key")
|
|
215
241
|
|
|
216
242
|
if not source_id or "event" in source_id or source_id == "":
|
|
217
243
|
continue
|