KekikStream 2.4.6__py3-none-any.whl → 2.4.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.
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 +27 -19
- KekikStream/Plugins/DiziBox.py +11 -8
- KekikStream/Plugins/DiziMom.py +71 -53
- KekikStream/Plugins/DiziPal.py +37 -23
- KekikStream/Plugins/DiziYou.py +23 -11
- KekikStream/Plugins/Dizilla.py +35 -30
- KekikStream/Plugins/FilmBip.py +90 -18
- KekikStream/Plugins/FilmEkseni.py +78 -40
- KekikStream/Plugins/FilmMakinesi.py +29 -14
- KekikStream/Plugins/FilmModu.py +17 -19
- KekikStream/Plugins/Filmatek.py +103 -91
- KekikStream/Plugins/Full4kizle.py +6 -6
- KekikStream/Plugins/FullHDFilm.py +6 -6
- KekikStream/Plugins/FullHDFilmizlesene.py +6 -7
- KekikStream/Plugins/HDFilmCehennemi.py +3 -3
- 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.7.dist-info}/METADATA +1 -1
- {kekikstream-2.4.6.dist-info → kekikstream-2.4.7.dist-info}/RECORD +37 -37
- {kekikstream-2.4.6.dist-info → kekikstream-2.4.7.dist-info}/WHEEL +0 -0
- {kekikstream-2.4.6.dist-info → kekikstream-2.4.7.dist-info}/entry_points.txt +0 -0
- {kekikstream-2.4.6.dist-info → kekikstream-2.4.7.dist-info}/licenses/LICENSE +0 -0
- {kekikstream-2.4.6.dist-info → kekikstream-2.4.7.dist-info}/top_level.txt +0 -0
KekikStream/Core/HTMLHelper.py
CHANGED
|
@@ -41,14 +41,14 @@ class HTMLHelper:
|
|
|
41
41
|
val = el.text(strip=True)
|
|
42
42
|
return val or None
|
|
43
43
|
|
|
44
|
-
def select_texts(self, selector: str, element: Node | None = None) -> list[str]:
|
|
44
|
+
def select_texts(self, selector: str, element: Node | None = None) -> list[str] | None:
|
|
45
45
|
"""CSS selector ile tüm eşleşen elementlerin text içeriklerini döndür."""
|
|
46
46
|
out: list[str] = []
|
|
47
47
|
for el in self.select(selector, element):
|
|
48
48
|
txt = el.text(strip=True)
|
|
49
49
|
if txt:
|
|
50
50
|
out.append(txt)
|
|
51
|
-
return out
|
|
51
|
+
return out or None
|
|
52
52
|
|
|
53
53
|
def select_attr(self, selector: str | None, attr: str, element: Node | None = None) -> str | None:
|
|
54
54
|
"""CSS selector ile element bul ve attribute değerini döndür."""
|
|
@@ -106,7 +106,13 @@ class PluginBase(ABC):
|
|
|
106
106
|
url = f"https:{url}" if url.startswith("//") else urljoin(self.main_url, url)
|
|
107
107
|
return url.replace("\\", "")
|
|
108
108
|
|
|
109
|
-
async def extract(
|
|
109
|
+
async def extract(
|
|
110
|
+
self,
|
|
111
|
+
url: str,
|
|
112
|
+
referer: str = None,
|
|
113
|
+
prefix: str | None = None,
|
|
114
|
+
name_override: str | None = None
|
|
115
|
+
) -> ExtractResult | list[ExtractResult] | None:
|
|
110
116
|
"""
|
|
111
117
|
Extractor ile video URL'sini çıkarır.
|
|
112
118
|
|
|
@@ -114,6 +120,7 @@ class PluginBase(ABC):
|
|
|
114
120
|
url: Iframe veya video URL'si
|
|
115
121
|
referer: Referer header (varsayılan: plugin main_url)
|
|
116
122
|
prefix: İsmin başına eklenecek opsiyonel etiket (örn: "Türkçe Dublaj")
|
|
123
|
+
name_override: İsmi tamamen değiştirecek opsiyonel etiket (Extractor adını ezer)
|
|
117
124
|
|
|
118
125
|
Returns:
|
|
119
126
|
ExtractResult: Extractor sonucu (name prefix ile birleştirilmiş) veya None
|
|
@@ -131,15 +138,19 @@ class PluginBase(ABC):
|
|
|
131
138
|
try:
|
|
132
139
|
data = await extractor.extract(url, referer=referer)
|
|
133
140
|
|
|
134
|
-
# Liste ise her bir öğe için prefix ekle
|
|
141
|
+
# Liste ise her bir öğe için prefix/override ekle
|
|
135
142
|
if isinstance(data, list):
|
|
136
143
|
for item in data:
|
|
137
|
-
if
|
|
144
|
+
if name_override:
|
|
145
|
+
item.name = name_override
|
|
146
|
+
elif prefix and item.name:
|
|
138
147
|
item.name = f"{prefix} | {item.name}"
|
|
139
148
|
return data
|
|
140
149
|
|
|
141
150
|
# Tekil öğe ise
|
|
142
|
-
if
|
|
151
|
+
if name_override:
|
|
152
|
+
data.name = name_override
|
|
153
|
+
elif prefix and data.name:
|
|
143
154
|
data.name = f"{prefix} | {data.name}"
|
|
144
155
|
|
|
145
156
|
return data
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
2
|
|
|
3
3
|
from KekikStream.Core import ExtractorBase, ExtractResult, HTMLHelper
|
|
4
|
-
import json
|
|
4
|
+
import json, html
|
|
5
5
|
|
|
6
6
|
class Odnoklassniki(ExtractorBase):
|
|
7
7
|
name = "Odnoklassniki"
|
|
@@ -19,12 +19,18 @@ class Odnoklassniki(ExtractorBase):
|
|
|
19
19
|
resp = await self.httpx.get(url, follow_redirects=True)
|
|
20
20
|
sel = HTMLHelper(resp.text)
|
|
21
21
|
|
|
22
|
-
|
|
22
|
+
# Metadata içinden videos array'ini al (esnek regex)
|
|
23
|
+
v_data = sel.regex_first(r'videos[^:]+:(\[.*?\])')
|
|
23
24
|
if not v_data:
|
|
25
|
+
if "Видео заблокировано" in resp.text or "copyrightsRestricted" in resp.text:
|
|
26
|
+
raise ValueError("Odnoklassniki: Video telif nedeniyle silinmiş/erişilemiyor.")
|
|
24
27
|
raise ValueError(f"Odnoklassniki: Video verisi bulunamadı. {url}")
|
|
25
28
|
|
|
26
29
|
# Kalite sıralaması (En yüksekten düşüğe)
|
|
27
30
|
order = ["ULTRA", "QUAD", "FULL", "HD", "SD", "LOW", "MOBILE"]
|
|
31
|
+
# Escaped string'i temizle
|
|
32
|
+
v_data = html.unescape(v_data)
|
|
33
|
+
v_data = v_data.replace('\\"', '"').replace('\\/', '/')
|
|
28
34
|
videos = json.loads(v_data)
|
|
29
35
|
|
|
30
36
|
best_url = None
|
|
@@ -38,4 +44,10 @@ class Odnoklassniki(ExtractorBase):
|
|
|
38
44
|
if not best_url:
|
|
39
45
|
raise ValueError("Odnoklassniki: Geçerli video URL'si bulunamadı.")
|
|
40
46
|
|
|
47
|
+
# URL temizliği (u0026 -> & ve olası unicode kaçışları)
|
|
48
|
+
best_url = best_url.replace("u0026", "&").replace("\\u0026", "&")
|
|
49
|
+
# Eğer hala \uXXXX formatında unicode kaçışları varsa çöz
|
|
50
|
+
if "\\u" in best_url:
|
|
51
|
+
best_url = best_url.encode().decode('unicode-escape')
|
|
52
|
+
|
|
41
53
|
return ExtractResult(name=self.name, url=self.fix_url(best_url), referer=referer)
|
KekikStream/Extractors/YTDLP.py
CHANGED
|
@@ -151,8 +151,8 @@ class YTDLP(ExtractorBase):
|
|
|
151
151
|
ydl_opts = {
|
|
152
152
|
"quiet" : True,
|
|
153
153
|
"no_warnings" : True,
|
|
154
|
-
"extract_flat" : False,
|
|
155
|
-
"format" : "best", # En iyi kalite
|
|
154
|
+
"extract_flat" : False, # Tam bilgi al
|
|
155
|
+
"format" : "best/all", # En iyi kalite, yoksa herhangi biri
|
|
156
156
|
"no_check_certificates" : True,
|
|
157
157
|
"socket_timeout" : 3,
|
|
158
158
|
"retries" : 1
|
KekikStream/Plugins/BelgeselX.py
CHANGED
|
@@ -36,15 +36,15 @@ class BelgeselX(PluginBase):
|
|
|
36
36
|
"""Türkçe için title case dönüşümü."""
|
|
37
37
|
if not text:
|
|
38
38
|
return ""
|
|
39
|
-
|
|
40
|
-
words
|
|
39
|
+
|
|
40
|
+
words = text.split()
|
|
41
41
|
new_words = []
|
|
42
|
-
|
|
42
|
+
|
|
43
43
|
for word in words:
|
|
44
44
|
# Önce Türkçe karakterleri koruyarak küçült
|
|
45
45
|
# İ -> i, I -> ı
|
|
46
46
|
word = word.replace("İ", "i").replace("I", "ı").lower()
|
|
47
|
-
|
|
47
|
+
|
|
48
48
|
# Sonra ilk harfi Türkçe kurallarına göre büyüt
|
|
49
49
|
if word:
|
|
50
50
|
if word[0] == "i":
|
|
@@ -53,9 +53,9 @@ class BelgeselX(PluginBase):
|
|
|
53
53
|
word = "I" + word[1:]
|
|
54
54
|
else:
|
|
55
55
|
word = word[0].upper() + word[1:]
|
|
56
|
-
|
|
56
|
+
|
|
57
57
|
new_words.append(word)
|
|
58
|
-
|
|
58
|
+
|
|
59
59
|
return " ".join(new_words)
|
|
60
60
|
|
|
61
61
|
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
@@ -63,21 +63,17 @@ class BelgeselX(PluginBase):
|
|
|
63
63
|
secici = HTMLHelper(istek.text)
|
|
64
64
|
|
|
65
65
|
results = []
|
|
66
|
-
# xpath kullanamıyoruz, en üst seviye gen-movie-contain'leri alıp içlerinden bilgileri çekelim
|
|
67
66
|
for container in secici.select("div.gen-movie-contain"):
|
|
68
|
-
# Poster için img'i container'ın içinden alalım
|
|
69
67
|
poster = secici.select_attr("div.gen-movie-img img", "src", container)
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
title = secici.select_text("div.gen-movie-info h3 a", container)
|
|
73
|
-
href = secici.select_attr("div.gen-movie-info h3 a", "href", container)
|
|
68
|
+
title = secici.select_text("div.gen-movie-info h3 a", container)
|
|
69
|
+
href = secici.select_attr("div.gen-movie-info h3 a", "href", container)
|
|
74
70
|
|
|
75
71
|
if title and href:
|
|
76
72
|
results.append(MainPageResult(
|
|
77
73
|
category = category,
|
|
78
74
|
title = self._to_title_case(title),
|
|
79
75
|
url = self.fix_url(href),
|
|
80
|
-
poster = self.fix_url(poster)
|
|
76
|
+
poster = self.fix_url(poster)
|
|
81
77
|
))
|
|
82
78
|
|
|
83
79
|
return results
|
|
@@ -117,7 +113,6 @@ class BelgeselX(PluginBase):
|
|
|
117
113
|
poster = images[i] if i < len(images) else None
|
|
118
114
|
|
|
119
115
|
if not url_val or "diziresimleri" not in url_val:
|
|
120
|
-
# URL'den belgesel linkini oluştur
|
|
121
116
|
if poster and "diziresimleri" in poster:
|
|
122
117
|
file_name = poster.rsplit("/", 1)[-1]
|
|
123
118
|
file_name = HTMLHelper(file_name).regex_replace(r"\.(jpe?g|png|webp)$", "")
|
|
@@ -154,6 +149,7 @@ class BelgeselX(PluginBase):
|
|
|
154
149
|
if not rating:
|
|
155
150
|
if r_match := secici.regex_first(r"%\s*(\d+)\s*Puan", item):
|
|
156
151
|
rating = float(r_match) / 10
|
|
152
|
+
rating = rating or None
|
|
157
153
|
|
|
158
154
|
episodes = []
|
|
159
155
|
for i, ep in enumerate(secici.select("div.gen-movie-contain")):
|
|
@@ -166,12 +162,23 @@ class BelgeselX(PluginBase):
|
|
|
166
162
|
final_url = self.fix_url(href)
|
|
167
163
|
if item_id:
|
|
168
164
|
final_url = f"{final_url}?id={item_id}"
|
|
169
|
-
|
|
170
|
-
episodes.append(Episode(
|
|
165
|
+
|
|
166
|
+
episodes.append(Episode(
|
|
167
|
+
season = s or 1,
|
|
168
|
+
episode = e or (i + 1),
|
|
169
|
+
title = name,
|
|
170
|
+
url = final_url
|
|
171
|
+
))
|
|
171
172
|
|
|
172
173
|
return SeriesInfo(
|
|
173
|
-
url=url,
|
|
174
|
-
|
|
174
|
+
url = url,
|
|
175
|
+
poster = self.fix_url(poster),
|
|
176
|
+
title = title,
|
|
177
|
+
description = description,
|
|
178
|
+
tags = tags,
|
|
179
|
+
year = year,
|
|
180
|
+
rating = rating,
|
|
181
|
+
episodes = episodes
|
|
175
182
|
)
|
|
176
183
|
|
|
177
184
|
async def load_links(self, url: str) -> list[ExtractResult]:
|
|
@@ -198,6 +205,7 @@ class BelgeselX(PluginBase):
|
|
|
198
205
|
|
|
199
206
|
for i, video_url in enumerate(files):
|
|
200
207
|
quality = labels[i] if i < len(labels) else "HD"
|
|
208
|
+
name = f"{'Google' if 'google' in video_url.lower() or 'blogspot' in video_url.lower() or quality == 'FULL' else self.name} | {'1080p' if quality == 'FULL' else quality}"
|
|
201
209
|
|
|
202
210
|
# belgeselx.php redirect'ini çöz
|
|
203
211
|
if "belgeselx.php" in video_url or "belgeselx2.php" in video_url:
|
|
@@ -210,7 +218,7 @@ class BelgeselX(PluginBase):
|
|
|
210
218
|
|
|
211
219
|
links.append(ExtractResult(
|
|
212
220
|
url = video_url,
|
|
213
|
-
name =
|
|
221
|
+
name = name,
|
|
214
222
|
referer = main_url
|
|
215
223
|
))
|
|
216
224
|
|
KekikStream/Plugins/DiziBox.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 Kekik.Sifreleme
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, SeriesInfo, Episode, ExtractResult, HTMLHelper
|
|
4
|
+
from Kekik.Sifreleme import CryptoJS
|
|
5
5
|
import urllib.parse, base64, contextlib, asyncio, time
|
|
6
6
|
|
|
7
7
|
class DiziBox(PluginBase):
|
|
@@ -61,7 +61,7 @@ class DiziBox(PluginBase):
|
|
|
61
61
|
category = category,
|
|
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
|
|
@@ -84,7 +84,7 @@ class DiziBox(PluginBase):
|
|
|
84
84
|
results.append(SearchResult(
|
|
85
85
|
title = title,
|
|
86
86
|
url = self.fix_url(href),
|
|
87
|
-
poster = self.fix_url(poster)
|
|
87
|
+
poster = self.fix_url(poster),
|
|
88
88
|
))
|
|
89
89
|
|
|
90
90
|
return results
|
|
@@ -114,12 +114,12 @@ class DiziBox(PluginBase):
|
|
|
114
114
|
|
|
115
115
|
return SeriesInfo(
|
|
116
116
|
url = url,
|
|
117
|
-
poster = self.fix_url(poster)
|
|
117
|
+
poster = self.fix_url(poster),
|
|
118
118
|
title = title,
|
|
119
119
|
description = description,
|
|
120
120
|
tags = tags,
|
|
121
121
|
rating = rating,
|
|
122
|
-
year =
|
|
122
|
+
year = year,
|
|
123
123
|
episodes = episodes,
|
|
124
124
|
actors = actors,
|
|
125
125
|
)
|
|
@@ -182,13 +182,16 @@ class DiziBox(PluginBase):
|
|
|
182
182
|
istek = await self.httpx.get(url)
|
|
183
183
|
secici = HTMLHelper(istek.text)
|
|
184
184
|
|
|
185
|
+
# Aktif kaynağın adını bul (DBX Pro vs.)
|
|
186
|
+
current_source_name = secici.select_text("div.video-toolbar option[selected]") or self.name
|
|
187
|
+
|
|
185
188
|
results = []
|
|
186
189
|
main_iframe = secici.select_attr("div#video-area iframe", "src")
|
|
187
190
|
|
|
188
191
|
if main_iframe:
|
|
189
192
|
if decoded := await self._iframe_decode(self.name, main_iframe, url):
|
|
190
193
|
for iframe in decoded:
|
|
191
|
-
data = await self.extract(iframe)
|
|
194
|
+
data = await self.extract(iframe, name_override=current_source_name)
|
|
192
195
|
if data:
|
|
193
196
|
results.append(data)
|
|
194
197
|
|
|
@@ -209,7 +212,7 @@ class DiziBox(PluginBase):
|
|
|
209
212
|
if alt_iframe:
|
|
210
213
|
if decoded := await self._iframe_decode(alt_name, alt_iframe, url):
|
|
211
214
|
for iframe in decoded:
|
|
212
|
-
data = await self.extract(iframe,
|
|
215
|
+
data = await self.extract(iframe, name_override=alt_name)
|
|
213
216
|
if data:
|
|
214
217
|
results.append(data)
|
|
215
218
|
|
KekikStream/Plugins/DiziMom.py
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
2
|
|
|
3
|
-
from KekikStream.Core import PluginBase, MainPageResult, SearchResult,
|
|
4
|
-
from json import dumps, loads
|
|
5
|
-
import re
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, SeriesInfo, Episode, ExtractResult, HTMLHelper
|
|
6
4
|
|
|
7
5
|
class DiziMom(PluginBase):
|
|
8
6
|
name = "DiziMom"
|
|
@@ -31,23 +29,33 @@ class DiziMom(PluginBase):
|
|
|
31
29
|
href = helper.select_attr("div.episode-name a", "href", item)
|
|
32
30
|
img = helper.select_poster("div.cat-img img", item)
|
|
33
31
|
if title and href:
|
|
34
|
-
results.append(MainPageResult(
|
|
32
|
+
results.append(MainPageResult(
|
|
33
|
+
category = category,
|
|
34
|
+
title = title.split(" izle")[0],
|
|
35
|
+
url = self.fix_url(href),
|
|
36
|
+
poster = self.fix_url(img)
|
|
37
|
+
))
|
|
35
38
|
else:
|
|
36
39
|
for item in helper.select("div.single-item"):
|
|
37
40
|
title = helper.select_text("div.categorytitle a", item)
|
|
38
41
|
href = helper.select_attr("div.categorytitle a", "href", item)
|
|
39
42
|
img = helper.select_poster("div.cat-img img", item)
|
|
40
43
|
if title and href:
|
|
41
|
-
results.append(MainPageResult(
|
|
44
|
+
results.append(MainPageResult(
|
|
45
|
+
category = category,
|
|
46
|
+
title = title.split(" izle")[0],
|
|
47
|
+
url = self.fix_url(href),
|
|
48
|
+
poster = self.fix_url(img)
|
|
49
|
+
))
|
|
42
50
|
|
|
43
51
|
return results
|
|
44
52
|
|
|
45
53
|
async def search(self, query: str) -> list[SearchResult]:
|
|
46
|
-
url
|
|
47
|
-
istek
|
|
54
|
+
url = f"{self.main_url}/?s={query}"
|
|
55
|
+
istek = await self.httpx.get(url)
|
|
48
56
|
helper = HTMLHelper(istek.text)
|
|
49
|
-
items
|
|
50
|
-
|
|
57
|
+
items = helper.select("div.single-item")
|
|
58
|
+
|
|
51
59
|
return [
|
|
52
60
|
SearchResult(
|
|
53
61
|
title = helper.select_text("div.categorytitle a", item).split(" izle")[0],
|
|
@@ -78,68 +86,78 @@ class DiziMom(PluginBase):
|
|
|
78
86
|
episodes.append(Episode(
|
|
79
87
|
season = s or 1,
|
|
80
88
|
episode = e or 1,
|
|
81
|
-
title = self.clean_title(name.replace(title
|
|
89
|
+
title = self.clean_title(name.replace(title, "").strip()),
|
|
82
90
|
url = self.fix_url(href)
|
|
83
91
|
))
|
|
84
92
|
|
|
85
93
|
return SeriesInfo(
|
|
86
94
|
url = url,
|
|
87
|
-
poster = self.fix_url(poster)
|
|
88
|
-
title = title
|
|
95
|
+
poster = self.fix_url(poster),
|
|
96
|
+
title = title,
|
|
89
97
|
description = description,
|
|
90
98
|
tags = tags,
|
|
91
99
|
rating = rating,
|
|
92
|
-
year =
|
|
100
|
+
year = year,
|
|
93
101
|
actors = actors,
|
|
94
102
|
episodes = episodes
|
|
95
103
|
)
|
|
96
104
|
|
|
97
105
|
async def load_links(self, url: str) -> list[ExtractResult]:
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
await self.httpx.post(login_url, headers=headers, data=login_data)
|
|
116
|
-
|
|
117
|
-
istek = await self.httpx.get(url, headers=headers)
|
|
106
|
+
await self.httpx.post(
|
|
107
|
+
url = f"{self.main_url}/wp-login.php",
|
|
108
|
+
headers = {
|
|
109
|
+
"User-Agent" : "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36",
|
|
110
|
+
"sec-ch-ua" : 'Not/A)Brand";v="8", "Chromium";v="137", "Google Chrome";v="137"',
|
|
111
|
+
"sec-ch-ua-mobile" : "?1",
|
|
112
|
+
"sec-ch-ua-platform" : "Android"
|
|
113
|
+
},
|
|
114
|
+
data = {
|
|
115
|
+
"log" : "keyiflerolsun",
|
|
116
|
+
"pwd" : "12345",
|
|
117
|
+
"rememberme" : "forever",
|
|
118
|
+
"redirect_to" : self.main_url
|
|
119
|
+
}
|
|
120
|
+
)
|
|
121
|
+
|
|
122
|
+
istek = await self.httpx.get(url)
|
|
118
123
|
helper = HTMLHelper(istek.text)
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
124
|
+
|
|
125
|
+
iframe_data = []
|
|
126
|
+
|
|
127
|
+
# Aktif kaynağın (main iframe) adını bul
|
|
128
|
+
current_name = helper.select_text("div.sources span.current_dil") or ""
|
|
122
129
|
main_iframe = helper.select_attr("iframe[src]", "src")
|
|
130
|
+
|
|
131
|
+
# Bazen iframe doğrudan video p içinde olabilir
|
|
132
|
+
if not main_iframe:
|
|
133
|
+
main_iframe = helper.select_attr("div.video p iframe", "src")
|
|
134
|
+
|
|
123
135
|
if main_iframe:
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
136
|
+
iframe_data.append((main_iframe, current_name))
|
|
137
|
+
|
|
138
|
+
# Diğer kaynakları (Partlar) gez
|
|
139
|
+
sources = helper.select("div.sources a.post-page-numbers")
|
|
127
140
|
for source in sources:
|
|
128
|
-
href =
|
|
141
|
+
href = helper.select_attr(None, "href", source)
|
|
142
|
+
name = helper.select_text("span.dil", source)
|
|
143
|
+
|
|
129
144
|
if href:
|
|
130
|
-
|
|
145
|
+
# Part sayfasına git
|
|
146
|
+
sub_istek = await self.httpx.get(href)
|
|
131
147
|
sub_helper = HTMLHelper(sub_istek.text)
|
|
132
|
-
sub_iframe = sub_helper.select_attr("div.video p iframe", "src")
|
|
148
|
+
sub_iframe = sub_helper.select_attr("div.video p iframe", "src") or sub_helper.select_attr("iframe[src]", "src")
|
|
149
|
+
|
|
133
150
|
if sub_iframe:
|
|
134
|
-
|
|
135
|
-
|
|
151
|
+
iframe_data.append((sub_iframe, name or f"{len(iframe_data)+1}.Kısım"))
|
|
152
|
+
|
|
136
153
|
results = []
|
|
137
|
-
for iframe_url in
|
|
138
|
-
#
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
extract_result = await self.extract(iframe_url)
|
|
154
|
+
for iframe_url, source_name in iframe_data:
|
|
155
|
+
# URL düzeltme
|
|
156
|
+
iframe_url = self.fix_url(iframe_url)
|
|
157
|
+
|
|
158
|
+
# Prefix olarak kaynak adını kullan (1.Kısım | HDMomPlayer)
|
|
159
|
+
extract_result = await self.extract(iframe_url, prefix=source_name)
|
|
160
|
+
|
|
143
161
|
if extract_result:
|
|
144
162
|
if isinstance(extract_result, list):
|
|
145
163
|
results.extend(extract_result)
|
|
@@ -147,9 +165,9 @@ class DiziMom(PluginBase):
|
|
|
147
165
|
results.append(extract_result)
|
|
148
166
|
else:
|
|
149
167
|
results.append(ExtractResult(
|
|
150
|
-
url
|
|
151
|
-
name
|
|
168
|
+
url = iframe_url,
|
|
169
|
+
name = f"{source_name} | External",
|
|
152
170
|
referer = self.main_url
|
|
153
171
|
))
|
|
154
|
-
|
|
172
|
+
|
|
155
173
|
return results
|
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 or None,
|
|
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
|
|