KekikStream 2.3.9__py3-none-any.whl → 2.5.3__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/Extractor/ExtractorLoader.py +8 -14
- KekikStream/Core/HTMLHelper.py +120 -49
- KekikStream/Core/Plugin/PluginBase.py +30 -12
- KekikStream/Core/Plugin/PluginLoader.py +12 -14
- KekikStream/Core/Plugin/PluginManager.py +2 -2
- KekikStream/Core/Plugin/PluginModels.py +0 -3
- KekikStream/Extractors/Abstream.py +27 -0
- 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 +21 -46
- KekikStream/Extractors/HDMomPlayer.py +30 -0
- KekikStream/Extractors/HDPlayerSystem.py +13 -31
- KekikStream/Extractors/HotStream.py +27 -0
- KekikStream/Extractors/JFVid.py +3 -24
- KekikStream/Extractors/JetTv.py +21 -34
- KekikStream/Extractors/JetV.py +55 -0
- 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 +40 -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/Veev.py +145 -0
- KekikStream/Extractors/VidBiz.py +62 -0
- KekikStream/Extractors/VidHide.py +58 -30
- 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 +58 -0
- KekikStream/Extractors/Vidoza.py +18 -0
- KekikStream/Extractors/Vtbe.py +38 -0
- KekikStream/Extractors/YTDLP.py +2 -2
- KekikStream/Extractors/YildizKisaFilm.py +13 -31
- KekikStream/Extractors/Zeus.py +61 -0
- KekikStream/Plugins/BelgeselX.py +97 -77
- KekikStream/Plugins/DiziBox.py +28 -45
- KekikStream/Plugins/DiziMom.py +179 -0
- KekikStream/Plugins/DiziPal.py +95 -161
- KekikStream/Plugins/DiziYou.py +51 -147
- KekikStream/Plugins/Dizilla.py +40 -61
- KekikStream/Plugins/FilmBip.py +90 -39
- KekikStream/Plugins/FilmEkseni.py +199 -0
- KekikStream/Plugins/FilmMakinesi.py +72 -73
- KekikStream/Plugins/FilmModu.py +25 -35
- KekikStream/Plugins/Filmatek.py +184 -0
- KekikStream/Plugins/FilmciBaba.py +155 -0
- KekikStream/Plugins/FullHDFilmizlesene.py +16 -37
- KekikStream/Plugins/HDFilm.py +243 -0
- KekikStream/Plugins/HDFilmCehennemi.py +242 -189
- KekikStream/Plugins/JetFilmizle.py +101 -69
- KekikStream/Plugins/KultFilmler.py +138 -104
- KekikStream/Plugins/RecTV.py +52 -73
- KekikStream/Plugins/RoketDizi.py +18 -27
- KekikStream/Plugins/SelcukFlix.py +30 -48
- KekikStream/Plugins/SetFilmIzle.py +76 -104
- KekikStream/Plugins/SezonlukDizi.py +90 -94
- KekikStream/Plugins/Sinefy.py +195 -167
- KekikStream/Plugins/SinemaCX.py +148 -78
- KekikStream/Plugins/Sinezy.py +29 -31
- KekikStream/Plugins/SuperFilmGeldi.py +12 -17
- KekikStream/Plugins/UgurFilm.py +85 -38
- KekikStream/Plugins/Watch32.py +160 -0
- KekikStream/Plugins/YabanciDizi.py +176 -211
- {kekikstream-2.3.9.dist-info → kekikstream-2.5.3.dist-info}/METADATA +1 -1
- kekikstream-2.5.3.dist-info/RECORD +99 -0
- {kekikstream-2.3.9.dist-info → kekikstream-2.5.3.dist-info}/WHEEL +1 -1
- KekikStream/Plugins/FullHDFilm.py +0 -249
- kekikstream-2.3.9.dist-info/RECORD +0 -84
- {kekikstream-2.3.9.dist-info → kekikstream-2.5.3.dist-info}/entry_points.txt +0 -0
- {kekikstream-2.3.9.dist-info → kekikstream-2.5.3.dist-info}/licenses/LICENSE +0 -0
- {kekikstream-2.3.9.dist-info → kekikstream-2.5.3.dist-info}/top_level.txt +0 -0
KekikStream/Plugins/RecTV.py
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, Episode, SeriesInfo, ExtractResult, HTMLHelper
|
|
4
4
|
from json import dumps, loads
|
|
5
|
+
import re, contextlib
|
|
5
6
|
|
|
6
7
|
class RecTV(PluginBase):
|
|
7
8
|
name = "RecTV"
|
|
@@ -64,82 +65,60 @@ class RecTV(PluginBase):
|
|
|
64
65
|
for veri in tum_veri
|
|
65
66
|
]
|
|
66
67
|
|
|
67
|
-
async def load_item(self, url: str) -> MovieInfo:
|
|
68
|
+
async def load_item(self, url: str) -> MovieInfo | SeriesInfo:
|
|
68
69
|
self.httpx.headers.update({"user-agent": "okhttp/4.12.0"})
|
|
69
70
|
veri = loads(url)
|
|
70
71
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
case _:
|
|
122
|
-
# Süreyi dakikaya çevir
|
|
123
|
-
duration_raw = veri.get("duration")
|
|
124
|
-
duration = None
|
|
125
|
-
if duration_raw:
|
|
126
|
-
try:
|
|
127
|
-
h = int(HTMLHelper(duration_raw).regex_first(r"(\d+)h") or 0)
|
|
128
|
-
m = int(HTMLHelper(duration_raw).regex_first(r"(\d+)min") or 0)
|
|
129
|
-
duration = h * 60 + m
|
|
130
|
-
except: pass
|
|
131
|
-
|
|
132
|
-
return MovieInfo(
|
|
133
|
-
url = url,
|
|
134
|
-
poster = self.fix_url(veri.get("image")),
|
|
135
|
-
title = veri.get("title"),
|
|
136
|
-
description = veri.get("description"),
|
|
137
|
-
tags = [genre.get("title") for genre in veri.get("genres")] if veri.get("genres") else [],
|
|
138
|
-
rating = str(veri.get("imdb") or veri.get("rating") or ""),
|
|
139
|
-
year = str(veri.get("year") or ""),
|
|
140
|
-
actors = [],
|
|
141
|
-
duration = duration
|
|
142
|
-
)
|
|
72
|
+
# Süreyi dakikaya çevir (Örn: "1h 59min")
|
|
73
|
+
duration_raw = veri.get("duration")
|
|
74
|
+
duration = None
|
|
75
|
+
if duration_raw:
|
|
76
|
+
with contextlib.suppress(Exception):
|
|
77
|
+
h = int(HTMLHelper(duration_raw).regex_first(r"(\d+)h") or 0)
|
|
78
|
+
m = int(HTMLHelper(duration_raw).regex_first(r"(\d+)min") or 0)
|
|
79
|
+
duration = h * 60 + m
|
|
80
|
+
|
|
81
|
+
common_info = {
|
|
82
|
+
"url" : url,
|
|
83
|
+
"poster" : self.fix_url(veri.get("image")),
|
|
84
|
+
"title" : veri.get("title"),
|
|
85
|
+
"description" : veri.get("description"),
|
|
86
|
+
"tags" : [genre.get("title") for genre in veri.get("genres")] if veri.get("genres") else [],
|
|
87
|
+
"rating" : str(veri.get("imdb") or veri.get("rating") or ""),
|
|
88
|
+
"year" : str(veri.get("year") or ""),
|
|
89
|
+
"duration" : duration
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if veri.get("type") == "serie":
|
|
93
|
+
dizi_istek = await self.httpx.get(f"{self.main_url}/api/season/by/serie/{veri.get('id')}/{self.sw_key}/")
|
|
94
|
+
dizi_veri = dizi_istek.json()
|
|
95
|
+
|
|
96
|
+
episodes = []
|
|
97
|
+
for season in dizi_veri:
|
|
98
|
+
s_title = season.get("title", "").strip()
|
|
99
|
+
s, _ = HTMLHelper.extract_season_episode(s_title)
|
|
100
|
+
for ep in season.get("episodes"):
|
|
101
|
+
e_title = ep.get("title", "").strip()
|
|
102
|
+
_, e = HTMLHelper.extract_season_episode(e_title)
|
|
103
|
+
for source in ep.get("sources"):
|
|
104
|
+
tag = ""
|
|
105
|
+
clean_s = s_title
|
|
106
|
+
if "dublaj" in s_title.lower():
|
|
107
|
+
tag = " (Dublaj)"; clean_s = re.sub(r"\s*dublaj\s*", "", s_title, flags=re.I).strip()
|
|
108
|
+
elif "altyaz" in s_title.lower():
|
|
109
|
+
tag = " (Altyazı)"; clean_s = re.sub(r"\s*altyaz[ıi]\s*", "", s_title, flags=re.I).strip()
|
|
110
|
+
|
|
111
|
+
ep_data = {"url": self.fix_url(source.get("url")), "title": f"{veri.get('title')} | {s_title} {e_title} - {source.get('title')}", "is_episode": True}
|
|
112
|
+
episodes.append(Episode(
|
|
113
|
+
season = s or 1,
|
|
114
|
+
episode = e or 1,
|
|
115
|
+
title = f"{clean_s} {e_title}{tag} - {source.get('title')}",
|
|
116
|
+
url = dumps(ep_data)
|
|
117
|
+
))
|
|
118
|
+
|
|
119
|
+
return SeriesInfo(**common_info, episodes=episodes, actors=[])
|
|
120
|
+
|
|
121
|
+
return MovieInfo(**common_info, actors=[])
|
|
143
122
|
|
|
144
123
|
async def load_links(self, url: str) -> list[ExtractResult]:
|
|
145
124
|
try:
|
KekikStream/Plugins/RoketDizi.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
2
|
|
|
3
|
-
from KekikStream.Core
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, SeriesInfo, Episode, ExtractResult, MovieInfo, HTMLHelper
|
|
4
4
|
import base64, json
|
|
5
5
|
|
|
6
6
|
class RoketDizi(PluginBase):
|
|
@@ -26,8 +26,6 @@ class RoketDizi(PluginBase):
|
|
|
26
26
|
secici = HTMLHelper(istek.text)
|
|
27
27
|
|
|
28
28
|
results = []
|
|
29
|
-
|
|
30
|
-
# Use div.new-added-list to find the container, then get items
|
|
31
29
|
for item in secici.select("div.new-added-list > span"):
|
|
32
30
|
title = secici.select_text("span.line-clamp-1", item)
|
|
33
31
|
href = secici.select_attr("a", "href", item)
|
|
@@ -38,7 +36,7 @@ class RoketDizi(PluginBase):
|
|
|
38
36
|
category = category,
|
|
39
37
|
title = self.clean_title(title),
|
|
40
38
|
url = self.fix_url(href),
|
|
41
|
-
poster = self.fix_url(poster)
|
|
39
|
+
poster = self.fix_url(poster)
|
|
42
40
|
))
|
|
43
41
|
|
|
44
42
|
return results
|
|
@@ -52,7 +50,7 @@ class RoketDizi(PluginBase):
|
|
|
52
50
|
"Referer" : f"{self.main_url}/",
|
|
53
51
|
}
|
|
54
52
|
)
|
|
55
|
-
|
|
53
|
+
|
|
56
54
|
try:
|
|
57
55
|
veri = istek.json()
|
|
58
56
|
encoded = veri.get("response", "")
|
|
@@ -76,7 +74,7 @@ class RoketDizi(PluginBase):
|
|
|
76
74
|
results.append(SearchResult(
|
|
77
75
|
title = self.clean_title(title.strip()),
|
|
78
76
|
url = self.fix_url(f"{self.main_url}/{slug}"),
|
|
79
|
-
poster = self.fix_url(poster)
|
|
77
|
+
poster = self.fix_url(poster)
|
|
80
78
|
))
|
|
81
79
|
|
|
82
80
|
return results
|
|
@@ -87,39 +85,33 @@ class RoketDizi(PluginBase):
|
|
|
87
85
|
async def load_item(self, url: str) -> MovieInfo | SeriesInfo:
|
|
88
86
|
resp = await self.httpx.get(url)
|
|
89
87
|
sel = HTMLHelper(resp.text)
|
|
90
|
-
|
|
88
|
+
|
|
91
89
|
next_data_text = sel.select_text("script#__NEXT_DATA__")
|
|
92
90
|
if not next_data_text:
|
|
93
91
|
return SeriesInfo(url=url, title=sel.select_text("h1") or "Bilinmeyen")
|
|
94
92
|
|
|
95
93
|
try:
|
|
96
|
-
next_data
|
|
94
|
+
next_data = json.loads(next_data_text)
|
|
97
95
|
secure_data_raw = next_data["props"]["pageProps"]["secureData"]
|
|
98
|
-
secure_data
|
|
99
|
-
|
|
96
|
+
secure_data = json.loads(base64.b64decode(secure_data_raw).decode('utf-8'))
|
|
97
|
+
|
|
100
98
|
content_item = secure_data.get("contentItem", {})
|
|
101
99
|
content = secure_data.get("content", {}).get("result", {})
|
|
102
|
-
|
|
100
|
+
|
|
103
101
|
title = content_item.get("original_title") or content_item.get("culture_title")
|
|
104
102
|
poster = content_item.get("poster_url") or content_item.get("face_url")
|
|
105
103
|
description = content_item.get("description")
|
|
106
104
|
rating = str(content_item.get("imdb_point") or "")
|
|
107
105
|
year = str(content_item.get("release_year") or "")
|
|
108
106
|
tags = content_item.get("categories", "").split(",")
|
|
109
|
-
|
|
110
|
-
# Actors extraction from getSerieCastsById or getMovieCastsById
|
|
107
|
+
|
|
111
108
|
actors = []
|
|
112
109
|
casts_data = content.get("getSerieCastsById") or content.get("getMovieCastsById")
|
|
113
110
|
if casts_data and casts_data.get("result"):
|
|
114
111
|
actors = [cast.get("name") for cast in casts_data["result"] if cast.get("name")]
|
|
115
112
|
|
|
116
|
-
# Episodes extraction
|
|
117
113
|
episodes = []
|
|
118
114
|
if "Series" in str(content.get("FindedType")):
|
|
119
|
-
# Check for episodes in SecureData -> RelatedResults -> getEpisodeSources (this might be for the current episode)
|
|
120
|
-
# Usually full episode list isn't in secureData, but we can get it from HTML or another API
|
|
121
|
-
# However, many times Next.js pages have them in props
|
|
122
|
-
# Let's fallback to the previous regex method for episodes if not in JSON
|
|
123
115
|
all_urls = HTMLHelper(resp.text).regex_all(r'"url":"([^"]*)"')
|
|
124
116
|
episodes_dict = {}
|
|
125
117
|
for u in all_urls:
|
|
@@ -138,7 +130,7 @@ class RoketDizi(PluginBase):
|
|
|
138
130
|
|
|
139
131
|
return SeriesInfo(
|
|
140
132
|
url = url,
|
|
141
|
-
poster = self.fix_url(poster)
|
|
133
|
+
poster = self.fix_url(poster),
|
|
142
134
|
title = self.clean_title(title),
|
|
143
135
|
description = description,
|
|
144
136
|
tags = tags,
|
|
@@ -150,7 +142,7 @@ class RoketDizi(PluginBase):
|
|
|
150
142
|
else:
|
|
151
143
|
return MovieInfo(
|
|
152
144
|
url = url,
|
|
153
|
-
poster = self.fix_url(poster)
|
|
145
|
+
poster = self.fix_url(poster),
|
|
154
146
|
title = self.clean_title(title),
|
|
155
147
|
description = description,
|
|
156
148
|
tags = tags,
|
|
@@ -169,17 +161,16 @@ class RoketDizi(PluginBase):
|
|
|
169
161
|
async def load_links(self, url: str) -> list[ExtractResult]:
|
|
170
162
|
resp = await self.httpx.get(url)
|
|
171
163
|
sel = HTMLHelper(resp.text)
|
|
172
|
-
|
|
164
|
+
|
|
173
165
|
next_data = sel.select_text("script#__NEXT_DATA__")
|
|
174
166
|
if not next_data:
|
|
175
167
|
return []
|
|
176
168
|
|
|
177
169
|
try:
|
|
178
|
-
data
|
|
179
|
-
secure_data
|
|
170
|
+
data = json.loads(next_data)
|
|
171
|
+
secure_data = data["props"]["pageProps"]["secureData"]
|
|
180
172
|
decoded_json = json.loads(base64.b64decode(secure_data).decode('utf-8'))
|
|
181
173
|
|
|
182
|
-
# secureData içindeki RelatedResults -> getEpisodeSources -> result dizisini al
|
|
183
174
|
sources = decoded_json.get("RelatedResults", {}).get("getEpisodeSources", {}).get("result", [])
|
|
184
175
|
|
|
185
176
|
seen_urls = set()
|
|
@@ -191,7 +182,7 @@ class RoketDizi(PluginBase):
|
|
|
191
182
|
iframe_url = HTMLHelper(source_content).regex_first(r'<iframe[^>]*src=["\']([^"\']*)["\']')
|
|
192
183
|
if not iframe_url:
|
|
193
184
|
continue
|
|
194
|
-
|
|
185
|
+
|
|
195
186
|
# Fix URL protocol
|
|
196
187
|
if not iframe_url.startswith("http"):
|
|
197
188
|
if iframe_url.startswith("//"):
|
|
@@ -200,8 +191,8 @@ class RoketDizi(PluginBase):
|
|
|
200
191
|
iframe_url = "https://" + iframe_url
|
|
201
192
|
|
|
202
193
|
iframe_url = self.fix_url(iframe_url)
|
|
203
|
-
|
|
204
|
-
# Deduplicate
|
|
194
|
+
|
|
195
|
+
# Deduplicate
|
|
205
196
|
if iframe_url in seen_urls:
|
|
206
197
|
continue
|
|
207
198
|
seen_urls.add(iframe_url)
|
|
@@ -52,7 +52,7 @@ class SelcukFlix(PluginBase):
|
|
|
52
52
|
category = category,
|
|
53
53
|
title = title,
|
|
54
54
|
url = final_url,
|
|
55
|
-
poster = self.fix_url(poster)
|
|
55
|
+
poster = self.fix_url(poster)
|
|
56
56
|
))
|
|
57
57
|
except Exception:
|
|
58
58
|
pass
|
|
@@ -187,54 +187,55 @@ class SelcukFlix(PluginBase):
|
|
|
187
187
|
|
|
188
188
|
next_data_text = sel.select_text("script#__NEXT_DATA__")
|
|
189
189
|
if not next_data_text:
|
|
190
|
-
return SeriesInfo(url=url, title=sel.select_text("h1") or "Bilinmeyen")
|
|
190
|
+
return SeriesInfo(url=url, title=self.clean_title(sel.select_text("h1")) or "Bilinmeyen")
|
|
191
191
|
|
|
192
192
|
try:
|
|
193
193
|
next_data = json.loads(next_data_text)
|
|
194
194
|
secure_data_raw = next_data["props"]["pageProps"].get("secureData")
|
|
195
195
|
if not secure_data_raw:
|
|
196
|
-
|
|
196
|
+
return SeriesInfo(url=url, title=self.clean_title(sel.select_text("h1")) or "Bilinmeyen")
|
|
197
197
|
|
|
198
198
|
# Clean possible quotes from string before decoding
|
|
199
199
|
if isinstance(secure_data_raw, str):
|
|
200
200
|
secure_data_raw = secure_data_raw.strip('"')
|
|
201
201
|
|
|
202
|
-
|
|
203
|
-
content_details = json.loads(
|
|
204
|
-
|
|
205
|
-
# Sometimes content_details might be a string (double encoded)
|
|
206
|
-
if isinstance(content_details, str):
|
|
207
|
-
content_details = json.loads(content_details)
|
|
202
|
+
content_details = json.loads(base64.b64decode(secure_data_raw).decode('utf-8'))
|
|
203
|
+
if isinstance(content_details, str): content_details = json.loads(content_details)
|
|
208
204
|
|
|
209
|
-
print(f"DEBUG: type(content_details)={type(content_details)}")
|
|
210
205
|
item = content_details.get("contentItem", {})
|
|
211
|
-
print(f"DEBUG: type(item)={type(item)}")
|
|
212
206
|
related_results = content_details.get("RelatedResults", {})
|
|
213
207
|
|
|
214
|
-
title
|
|
215
|
-
poster
|
|
216
|
-
description
|
|
217
|
-
rating
|
|
218
|
-
year
|
|
219
|
-
duration
|
|
208
|
+
title = self.clean_title(item.get("original_title") or item.get("culture_title") or item.get("originalTitle") or "")
|
|
209
|
+
poster = self.clean_image_url(item.get("poster_url") or item.get("posterUrl") or item.get("face_url"))
|
|
210
|
+
description = item.get("description") or item.get("used_description")
|
|
211
|
+
rating = str(item.get("imdb_point") or item.get("imdbPoint") or "")
|
|
212
|
+
year = str(item.get("release_year") or item.get("releaseYear") or "")
|
|
213
|
+
duration = item.get("total_minutes") or item.get("totalMinutes")
|
|
220
214
|
|
|
221
215
|
tags = []
|
|
222
216
|
tags_raw = item.get("category_names") or item.get("categoryNames") or item.get("categories")
|
|
223
217
|
if isinstance(tags_raw, str):
|
|
224
|
-
tags = [t.strip() for t in tags_raw.split(",")]
|
|
218
|
+
tags = [t.strip() for t in tags_raw.split(",") if t.strip()]
|
|
225
219
|
elif isinstance(tags_raw, list):
|
|
226
220
|
tags = [c.get("title") if isinstance(c, dict) else str(c) for c in tags_raw]
|
|
227
221
|
|
|
228
222
|
actors = []
|
|
229
|
-
actors_raw = item.get("actor_names") or item.get("actorNames")
|
|
230
|
-
if isinstance(actors_raw, str):
|
|
231
|
-
actors = [a.strip() for a in actors_raw.split(",")]
|
|
232
|
-
|
|
233
|
-
# Casts from RelatedResults
|
|
234
223
|
casts_data = related_results.get("getSerieCastsById") or related_results.get("getMovieCastsById")
|
|
235
224
|
if casts_data and isinstance(casts_data, dict) and casts_data.get("result"):
|
|
236
225
|
actors = [cast.get("name") for cast in casts_data["result"] if cast.get("name")]
|
|
237
226
|
|
|
227
|
+
common_info = {
|
|
228
|
+
"url" : url,
|
|
229
|
+
"poster" : poster,
|
|
230
|
+
"title" : title,
|
|
231
|
+
"description" : description,
|
|
232
|
+
"tags" : tags,
|
|
233
|
+
"rating" : rating,
|
|
234
|
+
"year" : year,
|
|
235
|
+
"actors" : actors,
|
|
236
|
+
"duration" : duration
|
|
237
|
+
}
|
|
238
|
+
|
|
238
239
|
series_data = related_results.get("getSerieSeasonAndEpisodes")
|
|
239
240
|
if series_data and isinstance(series_data, dict) and series_data.get("result"):
|
|
240
241
|
episodes = []
|
|
@@ -249,31 +250,12 @@ class SelcukFlix(PluginBase):
|
|
|
249
250
|
title = ep.get("ep_text") or ep.get("epText") or "",
|
|
250
251
|
url = self.fix_url(ep_slug)
|
|
251
252
|
))
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
tags = tags,
|
|
259
|
-
rating = rating,
|
|
260
|
-
year = year,
|
|
261
|
-
actors = actors,
|
|
262
|
-
duration = duration,
|
|
263
|
-
episodes = episodes
|
|
264
|
-
)
|
|
265
|
-
else:
|
|
266
|
-
return MovieInfo(
|
|
267
|
-
url = url,
|
|
268
|
-
poster = poster,
|
|
269
|
-
title = self.clean_title(title),
|
|
270
|
-
description = description,
|
|
271
|
-
tags = tags,
|
|
272
|
-
rating = rating,
|
|
273
|
-
year = year,
|
|
274
|
-
actors = actors,
|
|
275
|
-
duration = duration
|
|
276
|
-
)
|
|
253
|
+
return SeriesInfo(**common_info, episodes=episodes)
|
|
254
|
+
|
|
255
|
+
return MovieInfo(**common_info)
|
|
256
|
+
|
|
257
|
+
except Exception:
|
|
258
|
+
return SeriesInfo(url=url, title=self.clean_title(sel.select_text("h1")) or "Bilinmeyen")
|
|
277
259
|
|
|
278
260
|
except Exception:
|
|
279
261
|
return SeriesInfo(url=url, title=self.clean_title(sel.select_text("h1")) or "Bilinmeyen")
|