KekikStream 2.2.8__py3-none-any.whl → 2.3.9__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/HTMLHelper.py +134 -0
- KekikStream/Core/Plugin/PluginBase.py +22 -4
- KekikStream/Core/Plugin/PluginLoader.py +3 -2
- KekikStream/Core/Plugin/PluginManager.py +2 -2
- KekikStream/Core/__init__.py +2 -0
- KekikStream/Extractors/CloseLoad.py +12 -13
- KekikStream/Extractors/ContentX.py +33 -31
- KekikStream/Extractors/DonilasPlay.py +10 -10
- KekikStream/Extractors/DzenRu.py +3 -3
- KekikStream/Extractors/ExPlay.py +10 -10
- KekikStream/Extractors/Filemoon.py +47 -37
- KekikStream/Extractors/JetTv.py +4 -4
- KekikStream/Extractors/MixPlayHD.py +10 -11
- KekikStream/Extractors/MolyStream.py +16 -9
- KekikStream/Extractors/Odnoklassniki.py +4 -4
- KekikStream/Extractors/PeaceMakerst.py +3 -3
- KekikStream/Extractors/PixelDrain.py +6 -5
- KekikStream/Extractors/PlayerFilmIzle.py +6 -10
- KekikStream/Extractors/RapidVid.py +8 -7
- KekikStream/Extractors/SetPlay.py +10 -10
- KekikStream/Extractors/SetPrime.py +3 -6
- KekikStream/Extractors/SibNet.py +4 -5
- KekikStream/Extractors/Sobreatsesuyp.py +5 -5
- KekikStream/Extractors/TRsTX.py +5 -5
- KekikStream/Extractors/TurboImgz.py +3 -4
- KekikStream/Extractors/TurkeyPlayer.py +5 -5
- KekikStream/Extractors/VidHide.py +4 -7
- KekikStream/Extractors/VidMoly.py +37 -25
- KekikStream/Extractors/VidMoxy.py +8 -9
- KekikStream/Extractors/VidPapi.py +5 -7
- KekikStream/Extractors/VideoSeyred.py +3 -3
- KekikStream/Plugins/BelgeselX.py +40 -51
- KekikStream/Plugins/DiziBox.py +53 -81
- KekikStream/Plugins/DiziPal.py +50 -72
- KekikStream/Plugins/DiziYou.py +96 -83
- KekikStream/Plugins/Dizilla.py +101 -86
- KekikStream/Plugins/FilmBip.py +29 -50
- KekikStream/Plugins/FilmMakinesi.py +84 -46
- KekikStream/Plugins/FilmModu.py +27 -41
- KekikStream/Plugins/FullHDFilm.py +57 -62
- KekikStream/Plugins/FullHDFilmizlesene.py +32 -57
- KekikStream/Plugins/HDFilmCehennemi.py +51 -65
- KekikStream/Plugins/JetFilmizle.py +38 -51
- KekikStream/Plugins/KultFilmler.py +43 -67
- KekikStream/Plugins/RecTV.py +34 -9
- KekikStream/Plugins/RoketDizi.py +89 -111
- KekikStream/Plugins/SelcukFlix.py +102 -93
- KekikStream/Plugins/SetFilmIzle.py +110 -117
- KekikStream/Plugins/SezonlukDizi.py +88 -106
- KekikStream/Plugins/Sinefy.py +70 -70
- KekikStream/Plugins/SinemaCX.py +31 -55
- KekikStream/Plugins/Sinezy.py +27 -54
- KekikStream/Plugins/SuperFilmGeldi.py +25 -44
- KekikStream/Plugins/UgurFilm.py +23 -48
- KekikStream/Plugins/YabanciDizi.py +285 -0
- {kekikstream-2.2.8.dist-info → kekikstream-2.3.9.dist-info}/METADATA +1 -1
- kekikstream-2.3.9.dist-info/RECORD +84 -0
- kekikstream-2.2.8.dist-info/RECORD +0 -82
- {kekikstream-2.2.8.dist-info → kekikstream-2.3.9.dist-info}/WHEEL +0 -0
- {kekikstream-2.2.8.dist-info → kekikstream-2.3.9.dist-info}/entry_points.txt +0 -0
- {kekikstream-2.2.8.dist-info → kekikstream-2.3.9.dist-info}/licenses/LICENSE +0 -0
- {kekikstream-2.2.8.dist-info → kekikstream-2.3.9.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 import ExtractorBase, ExtractResult, Subtitle
|
|
4
|
-
import json
|
|
3
|
+
from KekikStream.Core import ExtractorBase, ExtractResult, Subtitle, HTMLHelper
|
|
4
|
+
import json
|
|
5
5
|
|
|
6
6
|
class VideoSeyred(ExtractorBase):
|
|
7
7
|
name = "VideoSeyred"
|
|
@@ -16,7 +16,7 @@ class VideoSeyred(ExtractorBase):
|
|
|
16
16
|
kontrol = await self.httpx.get(url)
|
|
17
17
|
kontrol.raise_for_status()
|
|
18
18
|
|
|
19
|
-
video_id =
|
|
19
|
+
video_id = HTMLHelper(kontrol.text).regex_first(r"playlist\/(.*)\.json")
|
|
20
20
|
|
|
21
21
|
video_url = f"{self.main_url}/playlist/{video_id}.json"
|
|
22
22
|
|
KekikStream/Plugins/BelgeselX.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, SeriesInfo, Episode, ExtractResult
|
|
4
|
-
from selectolax.parser import HTMLParser
|
|
5
|
-
import re
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, SeriesInfo, Episode, ExtractResult, HTMLHelper
|
|
6
4
|
|
|
7
5
|
class BelgeselX(PluginBase):
|
|
8
6
|
name = "BelgeselX"
|
|
@@ -43,22 +41,17 @@ class BelgeselX(PluginBase):
|
|
|
43
41
|
|
|
44
42
|
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
45
43
|
istek = self.cloudscraper.get(f"{url}{page}")
|
|
46
|
-
secici =
|
|
44
|
+
secici = HTMLHelper(istek.text)
|
|
47
45
|
|
|
48
46
|
results = []
|
|
49
47
|
# xpath kullanamıyoruz, en üst seviye gen-movie-contain'leri alıp içlerinden bilgileri çekelim
|
|
50
|
-
for container in secici.
|
|
48
|
+
for container in secici.select("div.gen-movie-contain"):
|
|
51
49
|
# Poster için img'i container'ın içinden alalım
|
|
52
|
-
|
|
53
|
-
poster = img_el.attrs.get("src") if img_el else None
|
|
50
|
+
poster = secici.select_attr("div.gen-movie-img img", "src", container)
|
|
54
51
|
|
|
55
52
|
# Title ve href için gen-movie-info
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
continue
|
|
59
|
-
|
|
60
|
-
title = h3_link.text(strip=True)
|
|
61
|
-
href = h3_link.attrs.get("href")
|
|
53
|
+
title = secici.select_text("div.gen-movie-info h3 a", container)
|
|
54
|
+
href = secici.select_attr("div.gen-movie-info h3 a", "href", container)
|
|
62
55
|
|
|
63
56
|
if title and href:
|
|
64
57
|
results.append(MainPageResult(
|
|
@@ -77,15 +70,13 @@ class BelgeselX(PluginBase):
|
|
|
77
70
|
token_resp = self.cloudscraper.get(f"https://cse.google.com/cse.js?cx={cx}")
|
|
78
71
|
token_text = token_resp.text
|
|
79
72
|
|
|
80
|
-
|
|
81
|
-
|
|
73
|
+
secici = HTMLHelper(token_text)
|
|
74
|
+
cse_lib = secici.regex_first(r'cselibVersion": "(.*)"')
|
|
75
|
+
cse_tok = secici.regex_first(r'cse_token": "(.*)"')
|
|
82
76
|
|
|
83
|
-
if not
|
|
77
|
+
if not cse_lib or not cse_tok:
|
|
84
78
|
return []
|
|
85
79
|
|
|
86
|
-
cse_lib = cse_lib_match.group(1)
|
|
87
|
-
cse_tok = cse_tok_match.group(1)
|
|
88
|
-
|
|
89
80
|
search_url = (
|
|
90
81
|
f"https://cse.google.com/cse/element/v1?"
|
|
91
82
|
f"rsz=filtered_cse&num=100&hl=tr&source=gcsc&cselibv={cse_lib}&cx={cx}"
|
|
@@ -96,9 +87,10 @@ class BelgeselX(PluginBase):
|
|
|
96
87
|
resp = self.cloudscraper.get(search_url)
|
|
97
88
|
resp_text = resp.text
|
|
98
89
|
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
90
|
+
secici2 = HTMLHelper(resp_text)
|
|
91
|
+
titles = secici2.regex_all(r'"titleNoFormatting": "(.*?)"')
|
|
92
|
+
urls = secici2.regex_all(r'"url": "(.*?)"')
|
|
93
|
+
images = secici2.regex_all(r'"ogImage": "(.*?)"')
|
|
102
94
|
|
|
103
95
|
results = []
|
|
104
96
|
for i, title in enumerate(titles):
|
|
@@ -109,7 +101,8 @@ class BelgeselX(PluginBase):
|
|
|
109
101
|
# URL'den belgesel linkini oluştur
|
|
110
102
|
if poster and "diziresimleri" in poster:
|
|
111
103
|
file_name = poster.rsplit("/", 1)[-1]
|
|
112
|
-
|
|
104
|
+
secici3 = HTMLHelper(file_name)
|
|
105
|
+
file_name = secici3.regex_replace(r"\.(jpe?g|png|webp)$", "")
|
|
113
106
|
url_val = f"{self.main_url}/belgeseldizi/{file_name}"
|
|
114
107
|
else:
|
|
115
108
|
continue
|
|
@@ -125,45 +118,37 @@ class BelgeselX(PluginBase):
|
|
|
125
118
|
|
|
126
119
|
async def load_item(self, url: str) -> SeriesInfo:
|
|
127
120
|
istek = await self.httpx.get(url)
|
|
128
|
-
secici =
|
|
121
|
+
secici = HTMLHelper(istek.text)
|
|
129
122
|
|
|
130
|
-
|
|
131
|
-
title = title_el.text(strip=True) if title_el else None
|
|
123
|
+
title = secici.select_text("h2.gen-title")
|
|
132
124
|
|
|
133
|
-
|
|
134
|
-
poster = poster_el.attrs.get("src") if poster_el else None
|
|
125
|
+
poster = secici.select_attr("div.gen-tv-show-top img", "src")
|
|
135
126
|
|
|
136
|
-
|
|
137
|
-
description = desc_el.text(strip=True) if desc_el else None
|
|
127
|
+
description = secici.select_text("div.gen-single-tv-show-info p")
|
|
138
128
|
|
|
139
129
|
tags = []
|
|
140
|
-
for tag_link in secici.
|
|
141
|
-
tag_href =
|
|
130
|
+
for tag_link in secici.select("div.gen-socail-share a[href*='belgeselkanali']"):
|
|
131
|
+
tag_href = secici.select_attr("a", "href", tag_link)
|
|
142
132
|
if tag_href:
|
|
143
133
|
tag_name = tag_href.rsplit("/", 1)[-1].replace("-", " ")
|
|
144
134
|
tags.append(self._to_title_case(tag_name))
|
|
145
135
|
|
|
146
136
|
episodes = []
|
|
147
137
|
counter = 0
|
|
148
|
-
for ep_item in secici.
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
continue
|
|
152
|
-
|
|
153
|
-
ep_name = ep_link.text(strip=True)
|
|
154
|
-
ep_href = ep_link.attrs.get("href")
|
|
138
|
+
for ep_item in secici.select("div.gen-movie-contain"):
|
|
139
|
+
ep_name = secici.select_text("div.gen-movie-info h3 a", ep_item)
|
|
140
|
+
ep_href = secici.select_attr("div.gen-movie-info h3 a", "href", ep_item)
|
|
155
141
|
|
|
156
142
|
if not ep_name or not ep_href:
|
|
157
143
|
continue
|
|
158
144
|
|
|
159
|
-
|
|
160
|
-
season_text = meta_el.text(strip=True) if meta_el else ""
|
|
145
|
+
season_text = secici.select_text("div.gen-single-meta-holder ul li", ep_item)
|
|
161
146
|
|
|
162
|
-
|
|
163
|
-
|
|
147
|
+
episode_num = secici.regex_first(r"Bölüm (\d+)", season_text)
|
|
148
|
+
season_num = secici.regex_first(r"Sezon (\d+)", season_text)
|
|
164
149
|
|
|
165
|
-
ep_episode = int(
|
|
166
|
-
ep_season = int(
|
|
150
|
+
ep_episode = int(episode_num) if episode_num else counter
|
|
151
|
+
ep_season = int(season_num) if season_num else 1
|
|
167
152
|
|
|
168
153
|
counter += 1
|
|
169
154
|
|
|
@@ -187,21 +172,25 @@ class BelgeselX(PluginBase):
|
|
|
187
172
|
istek = await self.httpx.get(url)
|
|
188
173
|
text = istek.text
|
|
189
174
|
|
|
175
|
+
secici = HTMLHelper(text)
|
|
190
176
|
# fnc_addWatch div'inden data-episode ID'sini al
|
|
191
|
-
|
|
192
|
-
if not
|
|
177
|
+
episode_id = secici.regex_first(r'<div[^>]*class=["\'][^"\']*fnc_addWatch[^"\']*["\'][^>]*data-episode=["\'](\d+)["\']')
|
|
178
|
+
if not episode_id:
|
|
193
179
|
return []
|
|
194
180
|
|
|
195
|
-
episode_id = ep_match.group(1)
|
|
196
181
|
iframe_url = f"{self.main_url}/video/data/new4.php?id={episode_id}"
|
|
197
182
|
|
|
198
183
|
iframe_resp = await self.httpx.get(iframe_url, headers={"Referer": url})
|
|
199
184
|
iframe_text = iframe_resp.text
|
|
200
185
|
|
|
186
|
+
secici2 = HTMLHelper(iframe_text)
|
|
187
|
+
# file:"url", label: "quality" patternlerini al
|
|
188
|
+
file_matches = secici2.regex_all(r'file:"([^"]+)"')
|
|
189
|
+
label_matches = secici2.regex_all(r'label: "([^"]+)"')
|
|
190
|
+
|
|
201
191
|
links = []
|
|
202
|
-
for
|
|
203
|
-
|
|
204
|
-
quality = match.group(2)
|
|
192
|
+
for i, video_url in enumerate(file_matches):
|
|
193
|
+
quality = label_matches[i] if i < len(label_matches) else "Unknown"
|
|
205
194
|
|
|
206
195
|
source_name = "Google" if quality == "FULL" else self.name
|
|
207
196
|
quality_str = "1080p" if quality == "FULL" else quality
|
KekikStream/Plugins/DiziBox.py
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
2
|
|
|
3
|
-
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, SeriesInfo, Episode, ExtractResult
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, SeriesInfo, Episode, ExtractResult, HTMLHelper
|
|
4
4
|
from Kekik.Sifreleme import CryptoJS
|
|
5
|
-
|
|
6
|
-
import re, urllib.parse, base64, contextlib, asyncio, time
|
|
5
|
+
import urllib.parse, base64, contextlib, asyncio, time
|
|
7
6
|
|
|
8
7
|
class DiziBox(PluginBase):
|
|
9
8
|
name = "DiziBox"
|
|
@@ -49,16 +48,13 @@ class DiziBox(PluginBase):
|
|
|
49
48
|
url = f"{url.replace('SAYFA', str(page))}",
|
|
50
49
|
follow_redirects = True
|
|
51
50
|
)
|
|
52
|
-
secici =
|
|
51
|
+
secici = HTMLHelper(istek.text)
|
|
53
52
|
|
|
54
53
|
results = []
|
|
55
|
-
for veri in secici.
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
title = h3_link.text(strip=True) if h3_link else None
|
|
60
|
-
href = h3_link.attrs.get("href") if h3_link else None
|
|
61
|
-
poster = img_el.attrs.get("src") if img_el else None
|
|
54
|
+
for veri in secici.select("article.detailed-article"):
|
|
55
|
+
title = secici.select_text("h3 a", veri)
|
|
56
|
+
href = secici.select_attr("h3 a", "href", veri)
|
|
57
|
+
poster = secici.select_attr("img", "src", veri)
|
|
62
58
|
|
|
63
59
|
if title and href:
|
|
64
60
|
results.append(MainPageResult(
|
|
@@ -76,16 +72,13 @@ class DiziBox(PluginBase):
|
|
|
76
72
|
"dbxu" : str(time.time() * 1000).split(".")[0]
|
|
77
73
|
})
|
|
78
74
|
istek = await self.httpx.get(f"{self.main_url}/?s={query}")
|
|
79
|
-
secici =
|
|
75
|
+
secici = HTMLHelper(istek.text)
|
|
80
76
|
|
|
81
77
|
results = []
|
|
82
|
-
for item in secici.
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
title = h3_link.text(strip=True) if h3_link else None
|
|
87
|
-
href = h3_link.attrs.get("href") if h3_link else None
|
|
88
|
-
poster = img_el.attrs.get("src") if img_el else None
|
|
78
|
+
for item in secici.select("article.detailed-article"):
|
|
79
|
+
title = secici.select_text("h3 a", item)
|
|
80
|
+
href = secici.select_attr("h3 a", "href", item)
|
|
81
|
+
poster = secici.select_attr("img", "src", item)
|
|
89
82
|
|
|
90
83
|
if title and href:
|
|
91
84
|
results.append(SearchResult(
|
|
@@ -98,58 +91,38 @@ class DiziBox(PluginBase):
|
|
|
98
91
|
|
|
99
92
|
async def load_item(self, url: str) -> SeriesInfo:
|
|
100
93
|
istek = await self.httpx.get(url)
|
|
101
|
-
secici =
|
|
94
|
+
secici = HTMLHelper(istek.text)
|
|
102
95
|
|
|
103
|
-
|
|
104
|
-
title = title_el.text(strip=True) if title_el else None
|
|
96
|
+
title = secici.select_text("div.tv-overview h1 a")
|
|
105
97
|
|
|
106
|
-
|
|
107
|
-
poster = poster_el.attrs.get("src") if poster_el else None
|
|
98
|
+
poster = secici.select_attr("div.tv-overview figure img", "src")
|
|
108
99
|
|
|
109
|
-
|
|
110
|
-
description = desc_el.text(strip=True) if desc_el else None
|
|
100
|
+
description = secici.select_text("div.tv-story p")
|
|
111
101
|
|
|
112
|
-
# year
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
year_match = re.search(r"(\d{4})", year_text)
|
|
116
|
-
year = year_match.group(1) if year_match else None
|
|
102
|
+
# year
|
|
103
|
+
year_text = secici.select_text("a[href*='/yil/']")
|
|
104
|
+
year = secici.regex_first(r"(\d{4})", year_text)
|
|
117
105
|
|
|
118
|
-
tags =
|
|
106
|
+
tags = secici.select_all_text("a[href*='/tur/']")
|
|
119
107
|
|
|
120
|
-
# rating
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
rating_match = re.search(r"[\d.,]+", rating_text)
|
|
124
|
-
rating = rating_match.group() if rating_match else None
|
|
108
|
+
# rating
|
|
109
|
+
rating_text = secici.select_text("span.label-imdb b")
|
|
110
|
+
rating = secici.regex_first(r"[\d.,]+", rating_text)
|
|
125
111
|
|
|
126
|
-
actors =
|
|
112
|
+
actors = secici.select_all_text("a[href*='/oyuncu/']")
|
|
127
113
|
|
|
128
114
|
episodes = []
|
|
129
|
-
for
|
|
130
|
-
sezon_link = sezon_link_el.attrs.get("href")
|
|
131
|
-
if not sezon_link:
|
|
132
|
-
continue
|
|
133
|
-
|
|
115
|
+
for sezon_link in secici.select_all_attr("div#seasons-list a", "href"):
|
|
134
116
|
sezon_url = self.fix_url(sezon_link)
|
|
135
117
|
sezon_istek = await self.httpx.get(sezon_url)
|
|
136
|
-
sezon_secici =
|
|
137
|
-
|
|
138
|
-
for bolum in sezon_secici.css("article.grid-box"):
|
|
139
|
-
ep_link = bolum.css_first("div.post-title a")
|
|
140
|
-
if not ep_link:
|
|
141
|
-
continue
|
|
142
|
-
|
|
143
|
-
ep_title = ep_link.text(strip=True)
|
|
144
|
-
ep_href = ep_link.attrs.get("href")
|
|
118
|
+
sezon_secici = HTMLHelper(sezon_istek.text)
|
|
145
119
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
episode_match = re.search(r"(\d+)\. ?Bölüm", ep_title_text)
|
|
120
|
+
for bolum in sezon_secici.select("article.grid-box"):
|
|
121
|
+
ep_title = sezon_secici.select_text("div.post-title a", bolum)
|
|
122
|
+
ep_href = sezon_secici.select_attr("div.post-title a", "href", bolum)
|
|
150
123
|
|
|
151
|
-
ep_season =
|
|
152
|
-
ep_episode =
|
|
124
|
+
ep_season = sezon_secici.regex_first(r"(\d+)\. ?Sezon", ep_title)
|
|
125
|
+
ep_episode = sezon_secici.regex_first(r"(\d+)\. ?Bölüm", ep_title)
|
|
153
126
|
|
|
154
127
|
if ep_title and ep_href:
|
|
155
128
|
episodes.append(Episode(
|
|
@@ -184,20 +157,20 @@ class DiziBox(PluginBase):
|
|
|
184
157
|
iframe_link = iframe_link.replace("king.php?v=", "king.php?wmode=opaque&v=")
|
|
185
158
|
|
|
186
159
|
istek = await self.httpx.get(iframe_link)
|
|
187
|
-
secici =
|
|
188
|
-
|
|
189
|
-
iframe = iframe_el.attrs.get("src") if iframe_el else None
|
|
160
|
+
secici = HTMLHelper(istek.text)
|
|
161
|
+
iframe = secici.select_attr("div#Player iframe", "src")
|
|
190
162
|
|
|
191
163
|
if iframe:
|
|
192
164
|
self.httpx.headers.update({"Referer": self.main_url})
|
|
193
|
-
|
|
165
|
+
iframe_istek = await self.httpx.get(iframe)
|
|
166
|
+
iframe_secici = HTMLHelper(iframe_istek.text)
|
|
194
167
|
|
|
195
|
-
crypt_data =
|
|
196
|
-
crypt_pass =
|
|
168
|
+
crypt_data = iframe_secici.regex_first(r"CryptoJS\.AES\.decrypt\(\"(.*)\",\"", iframe_istek.text)
|
|
169
|
+
crypt_pass = iframe_secici.regex_first(r"\",\"(.*)\"\);", iframe_istek.text)
|
|
197
170
|
decode = CryptoJS.decrypt(crypt_pass, crypt_data)
|
|
198
171
|
|
|
199
|
-
if video_match :=
|
|
200
|
-
results.append(video_match
|
|
172
|
+
if video_match := iframe_secici.regex_first(r"file: '(.*)',", decode):
|
|
173
|
+
results.append(video_match)
|
|
201
174
|
else:
|
|
202
175
|
results.append(decode)
|
|
203
176
|
|
|
@@ -206,15 +179,16 @@ class DiziBox(PluginBase):
|
|
|
206
179
|
while True:
|
|
207
180
|
await asyncio.sleep(.3)
|
|
208
181
|
with contextlib.suppress(Exception):
|
|
209
|
-
|
|
182
|
+
moly_istek = await self.httpx.get(iframe_link)
|
|
183
|
+
moly_secici = HTMLHelper(moly_istek.text)
|
|
210
184
|
|
|
211
|
-
if atob_data :=
|
|
212
|
-
decoded_atob = urllib.parse.unquote(atob_data
|
|
185
|
+
if atob_data := moly_secici.regex_first(r"unescape\(\"(.*)\"\)", moly_istek.text):
|
|
186
|
+
decoded_atob = urllib.parse.unquote(atob_data)
|
|
213
187
|
str_atob = base64.b64decode(decoded_atob).decode("utf-8")
|
|
214
188
|
|
|
215
|
-
|
|
216
|
-
if
|
|
217
|
-
results.append(
|
|
189
|
+
iframe_src = HTMLHelper(str_atob).select_attr("div#Player iframe", "src")
|
|
190
|
+
if iframe_src:
|
|
191
|
+
results.append(iframe_src)
|
|
218
192
|
|
|
219
193
|
break
|
|
220
194
|
|
|
@@ -226,11 +200,10 @@ class DiziBox(PluginBase):
|
|
|
226
200
|
|
|
227
201
|
async def load_links(self, url: str) -> list[ExtractResult]:
|
|
228
202
|
istek = await self.httpx.get(url)
|
|
229
|
-
secici =
|
|
203
|
+
secici = HTMLHelper(istek.text)
|
|
230
204
|
|
|
231
205
|
results = []
|
|
232
|
-
|
|
233
|
-
main_iframe = main_iframe_el.attrs.get("src") if main_iframe_el else None
|
|
206
|
+
main_iframe = secici.select_attr("div#video-area iframe", "src")
|
|
234
207
|
|
|
235
208
|
if main_iframe:
|
|
236
209
|
if decoded := await self._iframe_decode(self.name, main_iframe, url):
|
|
@@ -239,9 +212,9 @@ class DiziBox(PluginBase):
|
|
|
239
212
|
if data:
|
|
240
213
|
results.append(data)
|
|
241
214
|
|
|
242
|
-
for alternatif in secici.
|
|
243
|
-
alt_name =
|
|
244
|
-
alt_link =
|
|
215
|
+
for alternatif in secici.select("div.video-toolbar option[value]"):
|
|
216
|
+
alt_name = secici.select_text(None, alternatif)
|
|
217
|
+
alt_link = secici.select_attr(None, "value", alternatif)
|
|
245
218
|
|
|
246
219
|
if not alt_link:
|
|
247
220
|
continue
|
|
@@ -250,9 +223,8 @@ class DiziBox(PluginBase):
|
|
|
250
223
|
alt_istek = await self.httpx.get(alt_link)
|
|
251
224
|
alt_istek.raise_for_status()
|
|
252
225
|
|
|
253
|
-
alt_secici =
|
|
254
|
-
|
|
255
|
-
alt_iframe = alt_iframe_el.attrs.get("src") if alt_iframe_el else None
|
|
226
|
+
alt_secici = HTMLHelper(alt_istek.text)
|
|
227
|
+
alt_iframe = alt_secici.select_attr("div#video-area iframe", "src")
|
|
256
228
|
|
|
257
229
|
if alt_iframe:
|
|
258
230
|
if decoded := await self._iframe_decode(alt_name, alt_iframe, url):
|
KekikStream/Plugins/DiziPal.py
CHANGED
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
2
|
|
|
3
|
-
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, SeriesInfo, Episode, Subtitle, ExtractResult
|
|
4
|
-
from selectolax.parser import HTMLParser
|
|
5
|
-
import re
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, SeriesInfo, Episode, Subtitle, ExtractResult, HTMLHelper
|
|
6
4
|
|
|
7
5
|
class DiziPal(PluginBase):
|
|
8
6
|
name = "DiziPal"
|
|
9
7
|
language = "tr"
|
|
10
|
-
main_url = "https://
|
|
8
|
+
main_url = "https://dizipal1225.com"
|
|
11
9
|
favicon = f"https://www.google.com/s2/favicons?domain={main_url}&sz=64"
|
|
12
10
|
description = "dizipal güncel, dizipal yeni ve gerçek adresi. dizipal en yeni dizi ve filmleri güvenli ve hızlı şekilde sunar."
|
|
13
11
|
|
|
@@ -27,21 +25,16 @@ class DiziPal(PluginBase):
|
|
|
27
25
|
|
|
28
26
|
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
29
27
|
istek = await self.httpx.get(url)
|
|
30
|
-
secici =
|
|
28
|
+
secici = HTMLHelper(istek.text)
|
|
31
29
|
|
|
32
30
|
results = []
|
|
33
31
|
|
|
34
32
|
if "/son-bolumler" in url:
|
|
35
|
-
for veri in secici.
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
name = name_el.text(strip=True) if name_el else None
|
|
42
|
-
episode = episode_el.text(strip=True) if episode_el else None
|
|
43
|
-
href = link_el.attrs.get("href") if link_el else None
|
|
44
|
-
poster = img_el.attrs.get("src") if img_el else None
|
|
33
|
+
for veri in secici.select("div.episode-item"):
|
|
34
|
+
name = secici.select_text("div.name", veri)
|
|
35
|
+
episode = secici.select_text("div.episode", veri)
|
|
36
|
+
href = secici.select_attr("a", "href", veri)
|
|
37
|
+
poster = secici.select_attr("img", "src", veri)
|
|
45
38
|
|
|
46
39
|
if name and href:
|
|
47
40
|
ep_text = episode.replace(". Sezon ", "x").replace(". Bölüm", "") if episode else ""
|
|
@@ -56,14 +49,10 @@ class DiziPal(PluginBase):
|
|
|
56
49
|
poster = self.fix_url(poster) if poster else None,
|
|
57
50
|
))
|
|
58
51
|
else:
|
|
59
|
-
for veri in secici.
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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("src") if img_el else None
|
|
52
|
+
for veri in secici.select("article.type2 ul li"):
|
|
53
|
+
title = secici.select_text("span.title", veri)
|
|
54
|
+
href = secici.select_attr("a", "href", veri)
|
|
55
|
+
poster = secici.select_attr("img", "src", veri)
|
|
67
56
|
|
|
68
57
|
if title and href:
|
|
69
58
|
results.append(MainPageResult(
|
|
@@ -113,10 +102,10 @@ class DiziPal(PluginBase):
|
|
|
113
102
|
|
|
114
103
|
return results
|
|
115
104
|
|
|
116
|
-
def _find_sibling_text(self, secici:
|
|
105
|
+
def _find_sibling_text(self, secici: HTMLHelper, label_text: str) -> str | None:
|
|
117
106
|
"""Bir label'ın kardeş div'inden text çıkarır (xpath yerine)"""
|
|
118
|
-
for div in secici.
|
|
119
|
-
if
|
|
107
|
+
for div in secici.select("div"):
|
|
108
|
+
if secici.select_text(element=div) == label_text:
|
|
120
109
|
# Sonraki kardeş elementi bul
|
|
121
110
|
next_sibling = div.next
|
|
122
111
|
while next_sibling:
|
|
@@ -133,50 +122,41 @@ class DiziPal(PluginBase):
|
|
|
133
122
|
self.httpx.headers.pop("X-Requested-With", None)
|
|
134
123
|
|
|
135
124
|
istek = await self.httpx.get(url)
|
|
136
|
-
secici =
|
|
125
|
+
secici = HTMLHelper(istek.text)
|
|
137
126
|
html_text = istek.text
|
|
138
127
|
|
|
139
|
-
|
|
140
|
-
poster = self.fix_url(og_image.attrs.get("content")) if og_image else None
|
|
128
|
+
poster = self.fix_url(secici.select_attr("meta[property='og:image']", "content")) if secici.select_attr("meta[property='og:image']", "content") else None
|
|
141
129
|
|
|
142
|
-
#
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
130
|
+
# Sidebar bilgilerini topla
|
|
131
|
+
info = {}
|
|
132
|
+
for li in secici.select("li"):
|
|
133
|
+
key = secici.select_text("div.key", li)
|
|
134
|
+
val = secici.select_text("div.value", li)
|
|
135
|
+
if key and val:
|
|
136
|
+
info[key.strip(":")] = val.strip()
|
|
147
137
|
|
|
148
|
-
|
|
149
|
-
|
|
138
|
+
year = info.get("Yapım Yılı")
|
|
139
|
+
rating = info.get("IMDB Puanı")
|
|
140
|
+
|
|
141
|
+
tags_raw = info.get("Türler", "")
|
|
142
|
+
tags = [t.strip() for t in tags_raw.split() if t.strip()] if tags_raw else None
|
|
150
143
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
if rating_match:
|
|
154
|
-
rating = rating_match.group(1)
|
|
144
|
+
actors_raw = info.get("Oyuncular")
|
|
145
|
+
actors = [a.strip() for a in actors_raw.split(",") if a.strip()] if actors_raw else None
|
|
155
146
|
|
|
156
|
-
|
|
157
|
-
tags_match = re.search(r'Türler.*?<div[^>]*>([^<]+)</div>', html_text, re.DOTALL | re.IGNORECASE)
|
|
158
|
-
if tags_match:
|
|
159
|
-
tags_raw = tags_match.group(1)
|
|
160
|
-
tags = [t.strip() for t in tags_raw.split() if t.strip()]
|
|
147
|
+
description = secici.select_text("div.summary p")
|
|
161
148
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
if dur_match:
|
|
165
|
-
duration = int(dur_match.group(1))
|
|
149
|
+
duration_raw = info.get("Ortalama Süre")
|
|
150
|
+
duration = int(secici.regex_first(r"(\d+)", duration_raw)) if duration_raw else None
|
|
166
151
|
|
|
167
152
|
if "/dizi/" in url:
|
|
168
|
-
|
|
169
|
-
title = title_el.text(strip=True) if title_el else None
|
|
153
|
+
title = secici.select_text("div.cover h5")
|
|
170
154
|
|
|
171
155
|
episodes = []
|
|
172
|
-
for ep in secici.
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
ep_name = ep_name_el.text(strip=True) if ep_name_el else None
|
|
178
|
-
ep_href = ep_link_el.attrs.get("href") if ep_link_el else None
|
|
179
|
-
ep_text = ep_episode_el.text(strip=True) if ep_episode_el else ""
|
|
156
|
+
for ep in secici.select("div.episode-item"):
|
|
157
|
+
ep_name = secici.select_text("div.name", ep)
|
|
158
|
+
ep_href = secici.select_attr("a", "href", ep)
|
|
159
|
+
ep_text = secici.select_text("div.episode", ep)
|
|
180
160
|
ep_parts = ep_text.split(" ")
|
|
181
161
|
|
|
182
162
|
ep_season = None
|
|
@@ -206,11 +186,12 @@ class DiziPal(PluginBase):
|
|
|
206
186
|
year = year,
|
|
207
187
|
duration = duration,
|
|
208
188
|
episodes = episodes if episodes else None,
|
|
189
|
+
actors = actors,
|
|
209
190
|
)
|
|
210
191
|
else:
|
|
211
192
|
# Film için title - g-title div'lerinin 2. olanı
|
|
212
|
-
g_titles = secici.
|
|
213
|
-
title = g_titles[1]
|
|
193
|
+
g_titles = secici.select("div.g-title div")
|
|
194
|
+
title = secici.select_text(element=g_titles[1]) if len(g_titles) >= 2 else None
|
|
214
195
|
|
|
215
196
|
return MovieInfo(
|
|
216
197
|
url = url,
|
|
@@ -221,6 +202,7 @@ class DiziPal(PluginBase):
|
|
|
221
202
|
rating = rating,
|
|
222
203
|
year = year,
|
|
223
204
|
duration = duration,
|
|
205
|
+
actors = actors,
|
|
224
206
|
)
|
|
225
207
|
|
|
226
208
|
async def load_links(self, url: str) -> list[ExtractResult]:
|
|
@@ -231,13 +213,11 @@ class DiziPal(PluginBase):
|
|
|
231
213
|
self.httpx.headers.pop("X-Requested-With", None)
|
|
232
214
|
|
|
233
215
|
istek = await self.httpx.get(url)
|
|
234
|
-
secici =
|
|
216
|
+
secici = HTMLHelper(istek.text)
|
|
235
217
|
|
|
236
|
-
|
|
237
|
-
if not iframe_el:
|
|
238
|
-
iframe_el = secici.css_first("div#vast_new iframe")
|
|
218
|
+
# iframe presence checked via select_attr below
|
|
239
219
|
|
|
240
|
-
iframe =
|
|
220
|
+
iframe = secici.select_attr(".series-player-container iframe", "src") or secici.select_attr("div#vast_new iframe", "src")
|
|
241
221
|
if not iframe:
|
|
242
222
|
return []
|
|
243
223
|
|
|
@@ -248,15 +228,13 @@ class DiziPal(PluginBase):
|
|
|
248
228
|
i_text = i_istek.text
|
|
249
229
|
|
|
250
230
|
# m3u link çıkar
|
|
251
|
-
|
|
252
|
-
if
|
|
253
|
-
m3u_link = m3u_match[1]
|
|
231
|
+
m3u_link = secici.regex_first(r'file:"([^"]+)"', target=i_text)
|
|
232
|
+
if m3u_link:
|
|
254
233
|
|
|
255
234
|
# Altyazıları çıkar
|
|
235
|
+
sub_text = secici.regex_first(r'"subtitle":"([^"]+)"', target=i_text)
|
|
256
236
|
subtitles = []
|
|
257
|
-
|
|
258
|
-
if sub_match:
|
|
259
|
-
sub_text = sub_match[1]
|
|
237
|
+
if sub_text:
|
|
260
238
|
if "," in sub_text:
|
|
261
239
|
for sub in sub_text.split(","):
|
|
262
240
|
lang = sub.split("[")[1].split("]")[0] if "[" in sub else "Türkçe"
|