KekikStream 2.4.6__py3-none-any.whl → 2.4.8__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.
Potentially problematic release.
This version of KekikStream might be problematic. Click here for more details.
- KekikStream/Core/HTMLHelper.py +2 -2
- KekikStream/Core/Plugin/PluginBase.py +15 -4
- KekikStream/Extractors/Odnoklassniki.py +14 -2
- KekikStream/Extractors/YTDLP.py +2 -2
- KekikStream/Plugins/BelgeselX.py +30 -23
- KekikStream/Plugins/DiziBox.py +14 -11
- KekikStream/Plugins/DiziMom.py +110 -86
- KekikStream/Plugins/DiziPal.py +37 -23
- KekikStream/Plugins/DiziYou.py +23 -11
- KekikStream/Plugins/Dizilla.py +35 -30
- KekikStream/Plugins/FilmBip.py +83 -18
- KekikStream/Plugins/FilmEkseni.py +100 -58
- KekikStream/Plugins/FilmMakinesi.py +71 -19
- KekikStream/Plugins/FilmModu.py +17 -20
- KekikStream/Plugins/Filmatek.py +103 -98
- KekikStream/Plugins/{Full4kizle.py → FilmciBaba.py} +61 -80
- KekikStream/Plugins/FullHDFilmizlesene.py +12 -14
- KekikStream/Plugins/HDFilm.py +243 -0
- KekikStream/Plugins/HDFilmCehennemi.py +194 -125
- KekikStream/Plugins/JetFilmizle.py +5 -5
- KekikStream/Plugins/KultFilmler.py +6 -6
- KekikStream/Plugins/RoketDizi.py +5 -5
- KekikStream/Plugins/SelcukFlix.py +2 -2
- KekikStream/Plugins/SetFilmIzle.py +5 -5
- KekikStream/Plugins/SezonlukDizi.py +4 -4
- KekikStream/Plugins/Sinefy.py +5 -5
- KekikStream/Plugins/SinemaCX.py +5 -5
- KekikStream/Plugins/Sinezy.py +5 -5
- KekikStream/Plugins/SuperFilmGeldi.py +5 -5
- KekikStream/Plugins/UgurFilm.py +4 -4
- KekikStream/Plugins/YabanciDizi.py +5 -5
- {kekikstream-2.4.6.dist-info → kekikstream-2.4.8.dist-info}/METADATA +1 -1
- {kekikstream-2.4.6.dist-info → kekikstream-2.4.8.dist-info}/RECORD +37 -37
- KekikStream/Plugins/FullHDFilm.py +0 -179
- {kekikstream-2.4.6.dist-info → kekikstream-2.4.8.dist-info}/WHEEL +0 -0
- {kekikstream-2.4.6.dist-info → kekikstream-2.4.8.dist-info}/entry_points.txt +0 -0
- {kekikstream-2.4.6.dist-info → kekikstream-2.4.8.dist-info}/licenses/LICENSE +0 -0
- {kekikstream-2.4.6.dist-info → kekikstream-2.4.8.dist-info}/top_level.txt +0 -0
KekikStream/Plugins/DiziPal.py
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
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, MovieInfo, SeriesInfo, Episode, Subtitle, ExtractResult, HTMLHelper
|
|
4
4
|
|
|
5
5
|
class DiziPal(PluginBase):
|
|
6
6
|
name = "DiziPal"
|
|
7
7
|
language = "tr"
|
|
8
|
-
main_url = "https://dizipal.
|
|
8
|
+
main_url = "https://dizipal.uk"
|
|
9
9
|
favicon = f"https://www.google.com/s2/favicons?domain={main_url}&sz=64"
|
|
10
10
|
description = "dizipal güncel, dizipal yeni ve gerçek adresi. dizipal en yeni dizi ve filmleri güvenli ve hızlı şekilde sunar."
|
|
11
11
|
|
|
@@ -46,7 +46,7 @@ class DiziPal(PluginBase):
|
|
|
46
46
|
category = category,
|
|
47
47
|
title = title,
|
|
48
48
|
url = self.fix_url(href),
|
|
49
|
-
poster = self.fix_url(poster)
|
|
49
|
+
poster = self.fix_url(poster),
|
|
50
50
|
))
|
|
51
51
|
|
|
52
52
|
return results
|
|
@@ -65,7 +65,7 @@ class DiziPal(PluginBase):
|
|
|
65
65
|
results.append(SearchResult(
|
|
66
66
|
title = title,
|
|
67
67
|
url = self.fix_url(href),
|
|
68
|
-
poster = self.fix_url(poster)
|
|
68
|
+
poster = self.fix_url(poster),
|
|
69
69
|
))
|
|
70
70
|
|
|
71
71
|
return results
|
|
@@ -82,8 +82,8 @@ class DiziPal(PluginBase):
|
|
|
82
82
|
rating = secici.meta_value("IMDB Puanı")
|
|
83
83
|
duration_raw = secici.meta_value("Süre")
|
|
84
84
|
if duration_raw:
|
|
85
|
-
parts
|
|
86
|
-
saat
|
|
85
|
+
parts = duration_raw.split()
|
|
86
|
+
saat = 0
|
|
87
87
|
dakika = 0
|
|
88
88
|
|
|
89
89
|
for p in parts:
|
|
@@ -95,7 +95,7 @@ class DiziPal(PluginBase):
|
|
|
95
95
|
duration = saat * 60 + dakika
|
|
96
96
|
else:
|
|
97
97
|
duration = None
|
|
98
|
-
|
|
98
|
+
|
|
99
99
|
tags = secici.meta_list("Tür")
|
|
100
100
|
actors = secici.meta_list("Oyuncular")
|
|
101
101
|
if not actors:
|
|
@@ -104,36 +104,50 @@ class DiziPal(PluginBase):
|
|
|
104
104
|
if "/dizi/" in url:
|
|
105
105
|
episodes = []
|
|
106
106
|
for ep in secici.select("div.episode-item"):
|
|
107
|
-
name
|
|
108
|
-
href
|
|
107
|
+
name = secici.select_text("h4 a", ep)
|
|
108
|
+
href = secici.select_attr("a", "href", ep)
|
|
109
109
|
link_title = secici.select_attr("a", "title", ep)
|
|
110
|
-
|
|
110
|
+
|
|
111
111
|
h4_texts = secici.select_texts("h4", ep)
|
|
112
|
-
text
|
|
112
|
+
text = h4_texts[1] if len(h4_texts) > 1 else (h4_texts[0] if h4_texts else "")
|
|
113
113
|
|
|
114
114
|
full_text = f"{text} {link_title}" if link_title else text
|
|
115
115
|
|
|
116
116
|
if name and href:
|
|
117
117
|
s, e = secici.extract_season_episode(full_text or "")
|
|
118
|
-
episodes.append(Episode(
|
|
118
|
+
episodes.append(Episode(
|
|
119
|
+
season = s,
|
|
120
|
+
episode = e,
|
|
121
|
+
title = name,
|
|
122
|
+
url = self.fix_url(href)
|
|
123
|
+
))
|
|
119
124
|
|
|
120
125
|
return SeriesInfo(
|
|
121
|
-
url=url,
|
|
122
|
-
|
|
126
|
+
url = url,
|
|
127
|
+
poster = poster.replace("https://test4test.online", self.main_url),
|
|
128
|
+
title = title,
|
|
129
|
+
description = description,
|
|
130
|
+
tags = tags,
|
|
131
|
+
rating = rating,
|
|
132
|
+
year = year,
|
|
133
|
+
duration = duration,
|
|
134
|
+
episodes = episodes,
|
|
135
|
+
actors = actors
|
|
123
136
|
)
|
|
124
|
-
|
|
137
|
+
|
|
125
138
|
return MovieInfo(
|
|
126
|
-
url=url,
|
|
127
|
-
|
|
139
|
+
url = url,
|
|
140
|
+
poster = poster.replace("https://test4test.online", self.main_url),
|
|
141
|
+
title = title,
|
|
142
|
+
description = description,
|
|
143
|
+
tags = tags,
|
|
144
|
+
rating = rating,
|
|
145
|
+
year = year,
|
|
146
|
+
duration = duration,
|
|
147
|
+
actors = actors
|
|
128
148
|
)
|
|
129
149
|
|
|
130
150
|
async def load_links(self, url: str) -> list[ExtractResult]:
|
|
131
|
-
# Reset headers to get HTML response
|
|
132
|
-
self.httpx.headers.update({
|
|
133
|
-
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
|
|
134
|
-
})
|
|
135
|
-
self.httpx.headers.pop("X-Requested-With", None)
|
|
136
|
-
|
|
137
151
|
istek = await self.httpx.get(url)
|
|
138
152
|
secici = HTMLHelper(istek.text)
|
|
139
153
|
|
KekikStream/Plugins/DiziYou.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, Subtitle, ExtractResult, HTMLHelper
|
|
4
4
|
|
|
5
5
|
class DiziYou(PluginBase):
|
|
6
6
|
name = "DiziYou"
|
|
@@ -42,7 +42,7 @@ class DiziYou(PluginBase):
|
|
|
42
42
|
category = category,
|
|
43
43
|
title = title,
|
|
44
44
|
url = self.fix_url(href),
|
|
45
|
-
poster = self.fix_url(poster)
|
|
45
|
+
poster = self.fix_url(poster),
|
|
46
46
|
))
|
|
47
47
|
|
|
48
48
|
return results
|
|
@@ -61,7 +61,7 @@ class DiziYou(PluginBase):
|
|
|
61
61
|
results.append(SearchResult(
|
|
62
62
|
title = title,
|
|
63
63
|
url = self.fix_url(href),
|
|
64
|
-
poster = self.fix_url(poster)
|
|
64
|
+
poster = self.fix_url(poster),
|
|
65
65
|
))
|
|
66
66
|
|
|
67
67
|
return results
|
|
@@ -76,8 +76,8 @@ class DiziYou(PluginBase):
|
|
|
76
76
|
tags = secici.select_texts("div.genres a")
|
|
77
77
|
rating = secici.regex_first(r"(?is)IMDB\s*:\s*</span>([0-9.]+)", secici.html)
|
|
78
78
|
year = secici.extract_year("div#icerikcat2")
|
|
79
|
-
|
|
80
|
-
actors = [
|
|
79
|
+
raw_actors = secici.meta_value("Oyuncular", container_selector="div#icerikcat2")
|
|
80
|
+
actors = [x.strip() for x in raw_actors.split(",")] if raw_actors else None
|
|
81
81
|
|
|
82
82
|
episodes = []
|
|
83
83
|
for link in secici.select("div#scrollbar-container a"):
|
|
@@ -86,23 +86,35 @@ class DiziYou(PluginBase):
|
|
|
86
86
|
name = secici.select_text("div.bolumismi", link).strip("()")
|
|
87
87
|
s, e = secici.extract_season_episode(f"{name} {href}")
|
|
88
88
|
if e:
|
|
89
|
-
episodes.append(Episode(
|
|
89
|
+
episodes.append(Episode(
|
|
90
|
+
season = s or 1,
|
|
91
|
+
episode = e,
|
|
92
|
+
title = name,
|
|
93
|
+
url = self.fix_url(href)
|
|
94
|
+
))
|
|
90
95
|
|
|
91
96
|
return SeriesInfo(
|
|
92
|
-
url=url,
|
|
93
|
-
|
|
97
|
+
url = url,
|
|
98
|
+
poster = poster,
|
|
99
|
+
title = title,
|
|
100
|
+
description = description,
|
|
101
|
+
tags = tags,
|
|
102
|
+
rating = rating,
|
|
103
|
+
year = year,
|
|
104
|
+
episodes = episodes,
|
|
105
|
+
actors = actors
|
|
94
106
|
)
|
|
95
107
|
|
|
96
108
|
async def load_links(self, url: str) -> list[ExtractResult]:
|
|
97
109
|
istek = await self.httpx.get(url)
|
|
98
110
|
secici = HTMLHelper(istek.text)
|
|
99
|
-
|
|
111
|
+
|
|
100
112
|
# Player iframe'inden ID'yi yakala
|
|
101
113
|
iframe_src = secici.select_attr("iframe#diziyouPlayer", "src") or secici.select_attr("iframe[src*='/player/']", "src")
|
|
102
114
|
if not iframe_src:
|
|
103
115
|
return []
|
|
104
116
|
|
|
105
|
-
item_id
|
|
117
|
+
item_id = iframe_src.split("/")[-1].replace(".html", "")
|
|
106
118
|
base_storage = self.main_url.replace("www", "storage")
|
|
107
119
|
|
|
108
120
|
subtitles = []
|
|
@@ -132,4 +144,4 @@ class DiziYou(PluginBase):
|
|
|
132
144
|
subtitles = subtitles
|
|
133
145
|
))
|
|
134
146
|
|
|
135
|
-
return results
|
|
147
|
+
return results
|
KekikStream/Plugins/Dizilla.py
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
2
|
|
|
3
|
-
from KekikStream.Core
|
|
4
|
-
from json
|
|
5
|
-
from urllib.parse
|
|
6
|
-
from Crypto.Cipher
|
|
7
|
-
from base64
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, SeriesInfo, Episode, ExtractResult, HTMLHelper
|
|
4
|
+
from json import loads
|
|
5
|
+
from urllib.parse import urlparse, urlunparse
|
|
6
|
+
from Crypto.Cipher import AES
|
|
7
|
+
from base64 import b64decode
|
|
8
8
|
|
|
9
9
|
class Dizilla(PluginBase):
|
|
10
10
|
name = "Dizilla"
|
|
@@ -44,7 +44,7 @@ class Dizilla(PluginBase):
|
|
|
44
44
|
category = category,
|
|
45
45
|
title = veri.get("original_title"),
|
|
46
46
|
url = self.fix_url(f"{self.main_url}/{veri.get('used_slug')}"),
|
|
47
|
-
poster = self.fix_poster_url(self.fix_url(veri.get("
|
|
47
|
+
poster = self.fix_poster_url(self.fix_url(veri.get("poster_url"))),
|
|
48
48
|
)
|
|
49
49
|
for veri in veriler
|
|
50
50
|
])
|
|
@@ -54,21 +54,21 @@ class Dizilla(PluginBase):
|
|
|
54
54
|
|
|
55
55
|
# Genel olarak dizi sayfalarına giden linkleri al
|
|
56
56
|
for veri in secici.select('a[href*="/dizi/"]'):
|
|
57
|
-
href
|
|
57
|
+
href = secici.select_attr('a', 'href', veri)
|
|
58
58
|
title = secici.select_text(None, veri)
|
|
59
59
|
if not href or not title:
|
|
60
60
|
continue
|
|
61
61
|
|
|
62
62
|
# Detay sayfasından poster vb. bilgileri al
|
|
63
|
-
ep_req
|
|
63
|
+
ep_req = await self.httpx.get(self.fix_url(href))
|
|
64
64
|
ep_secici = HTMLHelper(ep_req.text)
|
|
65
|
-
poster
|
|
65
|
+
poster = ep_secici.select_poster('img.imgt') or ep_secici.select_poster('img')
|
|
66
66
|
|
|
67
67
|
ana_sayfa.append(MainPageResult(
|
|
68
68
|
category = category,
|
|
69
69
|
title = title,
|
|
70
70
|
url = self.fix_url(href),
|
|
71
|
-
poster = self.fix_url(poster)
|
|
71
|
+
poster = self.fix_url(poster)
|
|
72
72
|
))
|
|
73
73
|
|
|
74
74
|
return ana_sayfa
|
|
@@ -138,15 +138,18 @@ class Dizilla(PluginBase):
|
|
|
138
138
|
secici = HTMLHelper(istek.text)
|
|
139
139
|
|
|
140
140
|
next_data_text = secici.select_text("script#__NEXT_DATA__")
|
|
141
|
-
if not next_data_text:
|
|
141
|
+
if not next_data_text:
|
|
142
|
+
return None
|
|
142
143
|
|
|
143
144
|
next_data = loads(next_data_text)
|
|
144
145
|
secure_data = next_data.get("props", {}).get("pageProps", {}).get("secureData")
|
|
145
|
-
if not secure_data:
|
|
146
|
+
if not secure_data:
|
|
147
|
+
return None
|
|
146
148
|
|
|
147
149
|
decrypted = await self.decrypt_response(secure_data)
|
|
148
150
|
content = decrypted.get("contentItem", {})
|
|
149
|
-
if not content:
|
|
151
|
+
if not content:
|
|
152
|
+
return None
|
|
150
153
|
|
|
151
154
|
title = content.get("original_title") or content.get("used_title")
|
|
152
155
|
description = content.get("description") or content.get("used_description")
|
|
@@ -165,29 +168,34 @@ class Dizilla(PluginBase):
|
|
|
165
168
|
slug = ep.get("used_slug")
|
|
166
169
|
name = ep.get("episode_text") or ""
|
|
167
170
|
if not any(e.season == s_no and e.episode == e_no for e in episodes):
|
|
168
|
-
episodes.append(Episode(
|
|
171
|
+
episodes.append(Episode(
|
|
172
|
+
season = s_no,
|
|
173
|
+
episode = e_no,
|
|
174
|
+
title = name,
|
|
175
|
+
url = self.fix_url(f"{self.main_url}/{slug}")
|
|
176
|
+
))
|
|
169
177
|
|
|
170
178
|
return SeriesInfo(
|
|
171
179
|
url = url,
|
|
172
180
|
poster = poster,
|
|
173
|
-
title = title
|
|
181
|
+
title = title,
|
|
174
182
|
description = description,
|
|
175
183
|
tags = tags,
|
|
176
|
-
rating =
|
|
177
|
-
year =
|
|
184
|
+
rating = rating,
|
|
185
|
+
year = year,
|
|
178
186
|
episodes = episodes,
|
|
179
187
|
actors = actors
|
|
180
188
|
)
|
|
181
189
|
|
|
182
190
|
async def load_links(self, url: str) -> list[ExtractResult]:
|
|
183
|
-
istek
|
|
184
|
-
secici
|
|
191
|
+
istek = await self.httpx.get(url)
|
|
192
|
+
secici = HTMLHelper(istek.text)
|
|
185
193
|
|
|
186
194
|
next_data_text = secici.select_text("script#__NEXT_DATA__")
|
|
187
195
|
if not next_data_text:
|
|
188
196
|
return []
|
|
189
197
|
|
|
190
|
-
next_data
|
|
198
|
+
next_data = loads(next_data_text)
|
|
191
199
|
secure_data = next_data.get("props", {}).get("pageProps", {}).get("secureData", {})
|
|
192
200
|
decrypted = await self.decrypt_response(secure_data)
|
|
193
201
|
results = decrypted.get("RelatedResults", {}).get("getEpisodeSources", {}).get("result", [])
|
|
@@ -195,24 +203,21 @@ class Dizilla(PluginBase):
|
|
|
195
203
|
if not results:
|
|
196
204
|
return []
|
|
197
205
|
|
|
198
|
-
|
|
199
|
-
first_result = results[0]
|
|
206
|
+
first_result = results[0]
|
|
200
207
|
source_content = str(first_result.get("source_content", ""))
|
|
201
|
-
|
|
202
|
-
# Clean the source_content string (matching Kotlin: .replace("\"", "").replace("\\", ""))
|
|
208
|
+
|
|
203
209
|
cleaned_source = source_content.replace('"', '').replace('\\', '')
|
|
204
|
-
|
|
205
|
-
# Parse cleaned HTML
|
|
210
|
+
|
|
206
211
|
iframe_secici = HTMLHelper(cleaned_source)
|
|
207
|
-
iframe_src
|
|
208
|
-
|
|
209
|
-
# Referer check (matching Kotlin: loadExtractor(iframe, "${mainUrl}/", ...))
|
|
212
|
+
iframe_src = iframe_secici.select_attr("iframe", "src")
|
|
213
|
+
|
|
210
214
|
iframe_url = self.fix_url(iframe_src) if iframe_src else None
|
|
211
|
-
|
|
215
|
+
|
|
212
216
|
if not iframe_url:
|
|
213
217
|
return []
|
|
214
218
|
|
|
215
219
|
data = await self.extract(iframe_url, referer=f"{self.main_url}/", prefix=first_result.get('language_name', 'Unknown'))
|
|
216
220
|
if not data:
|
|
217
221
|
return []
|
|
222
|
+
|
|
218
223
|
return data if isinstance(data, list) else [data]
|
KekikStream/Plugins/FilmBip.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
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, MovieInfo, ExtractResult, HTMLHelper
|
|
4
|
+
from contextlib import suppress
|
|
4
5
|
|
|
5
6
|
class FilmBip(PluginBase):
|
|
6
7
|
name = "FilmBip"
|
|
@@ -39,8 +40,8 @@ class FilmBip(PluginBase):
|
|
|
39
40
|
|
|
40
41
|
results = []
|
|
41
42
|
for veri in secici.select("div.poster-long"):
|
|
42
|
-
title
|
|
43
|
-
href
|
|
43
|
+
title = secici.select_attr("a.block img.lazy", "alt", veri)
|
|
44
|
+
href = secici.select_attr("a.block", "href", veri)
|
|
44
45
|
poster = secici.select_poster("a.block img.lazy", veri)
|
|
45
46
|
|
|
46
47
|
if title and href:
|
|
@@ -48,7 +49,7 @@ class FilmBip(PluginBase):
|
|
|
48
49
|
category = category,
|
|
49
50
|
title = title,
|
|
50
51
|
url = self.fix_url(href),
|
|
51
|
-
poster = self.fix_url(poster)
|
|
52
|
+
poster = self.fix_url(poster),
|
|
52
53
|
))
|
|
53
54
|
|
|
54
55
|
return results
|
|
@@ -87,7 +88,7 @@ class FilmBip(PluginBase):
|
|
|
87
88
|
results.append(SearchResult(
|
|
88
89
|
title = title.strip(),
|
|
89
90
|
url = self.fix_url(href),
|
|
90
|
-
poster = self.fix_url(poster)
|
|
91
|
+
poster = self.fix_url(poster),
|
|
91
92
|
))
|
|
92
93
|
|
|
93
94
|
return results
|
|
@@ -108,13 +109,13 @@ class FilmBip(PluginBase):
|
|
|
108
109
|
|
|
109
110
|
return MovieInfo(
|
|
110
111
|
url = url,
|
|
111
|
-
poster = self.fix_url(poster)
|
|
112
|
-
title = title
|
|
112
|
+
poster = self.fix_url(poster),
|
|
113
|
+
title = title,
|
|
113
114
|
description = description,
|
|
114
115
|
tags = tags,
|
|
115
|
-
year =
|
|
116
|
+
year = year,
|
|
116
117
|
rating = rating,
|
|
117
|
-
duration =
|
|
118
|
+
duration = duration,
|
|
118
119
|
actors = actors,
|
|
119
120
|
)
|
|
120
121
|
|
|
@@ -123,14 +124,78 @@ class FilmBip(PluginBase):
|
|
|
123
124
|
secici = HTMLHelper(istek.text)
|
|
124
125
|
|
|
125
126
|
results = []
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
127
|
+
for tab in secici.select("ul.tab.alternative-group li[data-number]"):
|
|
128
|
+
tab_id = tab.attrs.get("data-number")
|
|
129
|
+
tab_name = secici.select_text(None, tab)
|
|
130
|
+
tab_hash = tab.attrs.get("data-group-hash")
|
|
131
|
+
|
|
132
|
+
if not tab_id:
|
|
133
|
+
continue
|
|
134
|
+
|
|
135
|
+
button_data = [] # (player_name, iframe_url)
|
|
136
|
+
|
|
137
|
+
# İlgili content divini bul
|
|
138
|
+
content_div = secici.select_first(f"div#{tab_id}")
|
|
139
|
+
|
|
140
|
+
# Eğer div var ve içi doluysa oradan al
|
|
141
|
+
if content_div and secici.select("ul li button", content_div):
|
|
142
|
+
buttons = secici.select("ul li button", content_div)
|
|
143
|
+
for btn in buttons:
|
|
144
|
+
button_data.append((btn.text(strip=True), btn.attrs.get("data-hhs")))
|
|
145
|
+
|
|
146
|
+
elif tab_hash:
|
|
147
|
+
# Div yok veya boş, AJAX ile çek
|
|
148
|
+
with suppress(Exception):
|
|
149
|
+
hash_resp = await self.httpx.post(
|
|
150
|
+
url = f"{self.main_url}/get/video/group",
|
|
151
|
+
headers = {
|
|
152
|
+
"X-Requested-With" : "XMLHttpRequest",
|
|
153
|
+
"Content-Type" : "application/x-www-form-urlencoded; charset=UTF-8",
|
|
154
|
+
"Referer" : url
|
|
155
|
+
},
|
|
156
|
+
data = {"hash": tab_hash}
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
if hash_resp.status_code == 200:
|
|
160
|
+
json_data = hash_resp.json()
|
|
161
|
+
if json_data.get("success"):
|
|
162
|
+
# 1. Videos listesi (API yanıtı)
|
|
163
|
+
if videos := json_data.get("videos"):
|
|
164
|
+
for vid in videos:
|
|
165
|
+
button_data.append((vid.get("name"), vid.get("link")))
|
|
166
|
+
|
|
167
|
+
# 2. HTML content (Fallback)
|
|
168
|
+
else:
|
|
169
|
+
html_content = json_data.get("content") or json_data.get("html") or json_data.get("theme")
|
|
170
|
+
if html_content:
|
|
171
|
+
sub_helper = HTMLHelper(html_content)
|
|
172
|
+
sub_btns = sub_helper.select("ul li button")
|
|
173
|
+
for btn in sub_btns:
|
|
174
|
+
button_data.append((btn.text(strip=True), btn.attrs.get("data-hhs")))
|
|
175
|
+
|
|
176
|
+
for player_name, iframe_url in button_data:
|
|
177
|
+
with suppress(Exception):
|
|
178
|
+
if iframe_url:
|
|
179
|
+
data = await self.extract(
|
|
180
|
+
url = self.fix_url(iframe_url),
|
|
181
|
+
name_override = f"{tab_name} | {player_name}"
|
|
182
|
+
)
|
|
183
|
+
if data:
|
|
184
|
+
if isinstance(data, list):
|
|
185
|
+
results.extend(data)
|
|
186
|
+
else:
|
|
187
|
+
results.append(data)
|
|
188
|
+
|
|
189
|
+
# Eğer hiç sonuç bulunamazsa fallback
|
|
190
|
+
if not results:
|
|
191
|
+
for player in secici.select("div#tv-spoox2"):
|
|
192
|
+
if iframe := secici.select_attr("iframe", "src", player):
|
|
193
|
+
iframe = self.fix_url(iframe)
|
|
194
|
+
data = await self.extract(iframe)
|
|
195
|
+
if data:
|
|
196
|
+
if isinstance(data, list):
|
|
197
|
+
results.extend(data)
|
|
198
|
+
else:
|
|
199
|
+
results.append(data)
|
|
135
200
|
|
|
136
201
|
return results
|