KekikStream 2.3.2__py3-none-any.whl → 2.3.4__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 +4 -1
- KekikStream/Core/__init__.py +2 -0
- KekikStream/Extractors/CloseLoad.py +12 -13
- KekikStream/Extractors/ContentX.py +12 -15
- KekikStream/Extractors/DonilasPlay.py +10 -10
- KekikStream/Extractors/DzenRu.py +3 -3
- KekikStream/Extractors/ExPlay.py +10 -10
- KekikStream/Extractors/Filemoon.py +11 -16
- KekikStream/Extractors/JetTv.py +4 -4
- KekikStream/Extractors/MixPlayHD.py +10 -11
- KekikStream/Extractors/MolyStream.py +5 -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 +24 -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 +41 -74
- KekikStream/Plugins/DiziYou.py +95 -88
- KekikStream/Plugins/Dizilla.py +51 -71
- KekikStream/Plugins/FilmBip.py +24 -49
- KekikStream/Plugins/FilmMakinesi.py +35 -52
- KekikStream/Plugins/FilmModu.py +27 -41
- KekikStream/Plugins/FullHDFilm.py +57 -62
- KekikStream/Plugins/FullHDFilmizlesene.py +35 -51
- KekikStream/Plugins/HDFilmCehennemi.py +48 -62
- KekikStream/Plugins/JetFilmizle.py +32 -50
- KekikStream/Plugins/KultFilmler.py +42 -67
- KekikStream/Plugins/RecTV.py +7 -4
- KekikStream/Plugins/RoketDizi.py +30 -50
- KekikStream/Plugins/SelcukFlix.py +15 -29
- KekikStream/Plugins/SetFilmIzle.py +41 -70
- KekikStream/Plugins/SezonlukDizi.py +47 -65
- KekikStream/Plugins/Sinefy.py +34 -50
- 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-2.3.2.dist-info → kekikstream-2.3.4.dist-info}/METADATA +1 -1
- kekikstream-2.3.4.dist-info/RECORD +83 -0
- kekikstream-2.3.2.dist-info/RECORD +0 -82
- {kekikstream-2.3.2.dist-info → kekikstream-2.3.4.dist-info}/WHEEL +0 -0
- {kekikstream-2.3.2.dist-info → kekikstream-2.3.4.dist-info}/entry_points.txt +0 -0
- {kekikstream-2.3.2.dist-info → kekikstream-2.3.4.dist-info}/licenses/LICENSE +0 -0
- {kekikstream-2.3.2.dist-info → kekikstream-2.3.4.dist-info}/top_level.txt +0 -0
|
@@ -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, MovieInfo, SeriesInfo, Episode, ExtractResult
|
|
4
|
-
from selectolax.parser import HTMLParser
|
|
5
|
-
import re
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, SeriesInfo, Episode, ExtractResult, HTMLHelper
|
|
6
4
|
|
|
7
5
|
class FilmMakinesi(PluginBase):
|
|
8
6
|
name = "FilmMakinesi"
|
|
@@ -37,17 +35,13 @@ class FilmMakinesi(PluginBase):
|
|
|
37
35
|
|
|
38
36
|
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
39
37
|
istek = self.cloudscraper.get(f"{url}{'' if page == 1 else f'page/{page}/'}")
|
|
40
|
-
secici =
|
|
38
|
+
secici = HTMLHelper(istek.text)
|
|
41
39
|
|
|
42
40
|
results = []
|
|
43
|
-
for veri in secici.
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
title = title_el.text(strip=True) if title_el else None
|
|
49
|
-
href = link_el.attrs.get("href") if link_el else None
|
|
50
|
-
poster = (img_el.attrs.get("data-src") or img_el.attrs.get("src")) if img_el else None
|
|
41
|
+
for veri in secici.select("div.item-relative"):
|
|
42
|
+
title = secici.select_text("div.title", veri)
|
|
43
|
+
href = secici.select_attr("a", "href", veri)
|
|
44
|
+
poster = secici.select_poster("img", veri)
|
|
51
45
|
|
|
52
46
|
if title and href:
|
|
53
47
|
results.append(MainPageResult(
|
|
@@ -61,17 +55,13 @@ class FilmMakinesi(PluginBase):
|
|
|
61
55
|
|
|
62
56
|
async def search(self, query: str) -> list[SearchResult]:
|
|
63
57
|
istek = await self.httpx.get(f"{self.main_url}/arama/?s={query}")
|
|
64
|
-
secici =
|
|
58
|
+
secici = HTMLHelper(istek.text)
|
|
65
59
|
|
|
66
60
|
results = []
|
|
67
|
-
for article in secici.
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
title = title_el.text(strip=True) if title_el else None
|
|
73
|
-
href = link_el.attrs.get("href") if link_el else None
|
|
74
|
-
poster = (img_el.attrs.get("data-src") or img_el.attrs.get("src")) if img_el else None
|
|
61
|
+
for article in secici.select("div.item-relative"):
|
|
62
|
+
title = secici.select_text("div.title", article)
|
|
63
|
+
href = secici.select_attr("a", "href", article)
|
|
64
|
+
poster = secici.select_poster("img", article)
|
|
75
65
|
|
|
76
66
|
if title and href:
|
|
77
67
|
results.append(SearchResult(
|
|
@@ -84,48 +74,42 @@ class FilmMakinesi(PluginBase):
|
|
|
84
74
|
|
|
85
75
|
async def load_item(self, url: str) -> MovieInfo | SeriesInfo:
|
|
86
76
|
istek = await self.httpx.get(url)
|
|
87
|
-
secici =
|
|
77
|
+
secici = HTMLHelper(istek.text)
|
|
88
78
|
|
|
89
|
-
|
|
90
|
-
title = title_el.text(strip=True) if title_el else ""
|
|
79
|
+
title = secici.select_text("h1.title") or ""
|
|
91
80
|
|
|
92
|
-
|
|
93
|
-
poster
|
|
81
|
+
poster = secici.select_attr("img.cover-img", "src") or ""
|
|
82
|
+
poster = poster.strip()
|
|
94
83
|
|
|
95
|
-
|
|
96
|
-
description = desc_el.text(strip=True) if desc_el else ""
|
|
84
|
+
description = secici.select_text("div.info-description p") or ""
|
|
97
85
|
|
|
98
|
-
|
|
99
|
-
rating
|
|
100
|
-
if
|
|
101
|
-
|
|
102
|
-
if rating_text:
|
|
103
|
-
rating = rating_text.split()[0]
|
|
86
|
+
rating_text = secici.select_text("div.score") or ""
|
|
87
|
+
rating = None
|
|
88
|
+
if rating_text:
|
|
89
|
+
rating = rating_text.split()[0]
|
|
104
90
|
|
|
105
|
-
|
|
106
|
-
year = year_el.text(strip=True) if year_el else ""
|
|
91
|
+
year = secici.select_text("span.date a") or ""
|
|
107
92
|
|
|
108
|
-
actors =
|
|
109
|
-
tags
|
|
93
|
+
actors = secici.select_all_text("div.cast-name")
|
|
94
|
+
tags = secici.select_all_text("div.genre a")
|
|
110
95
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
if
|
|
114
|
-
duration_text = duration_el.text(strip=True)
|
|
96
|
+
duration = None
|
|
97
|
+
duration_text = secici.select_text("div.time") or None
|
|
98
|
+
if duration_text:
|
|
115
99
|
parts = duration_text.split()
|
|
116
100
|
if len(parts) > 1:
|
|
117
101
|
duration = parts[1].strip()
|
|
118
102
|
|
|
119
103
|
# Dizi mi kontrol et - sezon/bölüm linkleri var mı?
|
|
120
104
|
episodes = []
|
|
121
|
-
all_links = secici.
|
|
105
|
+
all_links = secici.select("a[href]")
|
|
122
106
|
for link in all_links:
|
|
123
107
|
href = link.attrs.get("href", "")
|
|
124
|
-
|
|
125
|
-
if
|
|
126
|
-
season_no = int(
|
|
127
|
-
ep_no = int(
|
|
128
|
-
|
|
108
|
+
pairs = HTMLHelper(href).regex_all(r"/sezon-(\d+)/bolum-(\d+)")
|
|
109
|
+
if pairs:
|
|
110
|
+
season_no = int(pairs[0][0])
|
|
111
|
+
ep_no = int(pairs[0][1])
|
|
112
|
+
|
|
129
113
|
# Bölüm başlığını çıkar - text'ten gerçek ismi al
|
|
130
114
|
# Format: "22 Eylül 2014 / 44 dk /1. Sezon / 1. BölümPilot"
|
|
131
115
|
full_text = link.text(strip=True)
|
|
@@ -184,12 +168,12 @@ class FilmMakinesi(PluginBase):
|
|
|
184
168
|
|
|
185
169
|
async def load_links(self, url: str) -> list[ExtractResult]:
|
|
186
170
|
istek = await self.httpx.get(url)
|
|
187
|
-
secici =
|
|
171
|
+
secici = HTMLHelper(istek.text)
|
|
188
172
|
|
|
189
173
|
response = []
|
|
190
174
|
|
|
191
175
|
# Video parts linklerini ve etiketlerini al
|
|
192
|
-
for link in secici.
|
|
176
|
+
for link in secici.select("div.video-parts a[data-video_url]"):
|
|
193
177
|
video_url = link.attrs.get("data-video_url")
|
|
194
178
|
label = link.text(strip=True) if link.text(strip=True) else ""
|
|
195
179
|
|
|
@@ -200,8 +184,7 @@ class FilmMakinesi(PluginBase):
|
|
|
200
184
|
|
|
201
185
|
# Eğer video-parts yoksa iframe kullan
|
|
202
186
|
if not response:
|
|
203
|
-
|
|
204
|
-
iframe_src = iframe_el.attrs.get("data-src") if iframe_el else None
|
|
187
|
+
iframe_src = secici.select_attr("iframe", "data-src")
|
|
205
188
|
if iframe_src:
|
|
206
189
|
data = await self.extract(iframe_src)
|
|
207
190
|
if data:
|
KekikStream/Plugins/FilmModu.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, MovieInfo, Subtitle, ExtractResult
|
|
4
|
-
from selectolax.parser import HTMLParser
|
|
5
|
-
import re
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, Subtitle, ExtractResult, HTMLHelper
|
|
6
4
|
|
|
7
5
|
class FilmModu(PluginBase):
|
|
8
6
|
name = "FilmModu"
|
|
@@ -42,16 +40,13 @@ class FilmModu(PluginBase):
|
|
|
42
40
|
|
|
43
41
|
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
44
42
|
istek = await self.httpx.get(url.replace("SAYFA", str(page)))
|
|
45
|
-
secici =
|
|
43
|
+
secici = HTMLHelper(istek.text)
|
|
46
44
|
|
|
47
45
|
results = []
|
|
48
|
-
for veri in secici.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
title = link_el.text(strip=True) if link_el else None
|
|
53
|
-
href = link_el.attrs.get("href") if link_el else None
|
|
54
|
-
poster = img_el.attrs.get("data-src") if img_el else None
|
|
46
|
+
for veri in secici.select("div.movie"):
|
|
47
|
+
title = secici.select_text("a", veri)
|
|
48
|
+
href = secici.select_attr("a", "href", veri)
|
|
49
|
+
poster = secici.select_attr("picture img", "data-src", veri)
|
|
55
50
|
|
|
56
51
|
if title and href:
|
|
57
52
|
results.append(MainPageResult(
|
|
@@ -65,16 +60,13 @@ class FilmModu(PluginBase):
|
|
|
65
60
|
|
|
66
61
|
async def search(self, query: str) -> list[SearchResult]:
|
|
67
62
|
istek = await self.httpx.get(f"{self.main_url}/film-ara?term={query}")
|
|
68
|
-
secici =
|
|
63
|
+
secici = HTMLHelper(istek.text)
|
|
69
64
|
|
|
70
65
|
results = []
|
|
71
|
-
for veri in secici.
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
title = link_el.text(strip=True) if link_el else None
|
|
76
|
-
href = link_el.attrs.get("href") if link_el else None
|
|
77
|
-
poster = img_el.attrs.get("data-src") if img_el else None
|
|
66
|
+
for veri in secici.select("div.movie"):
|
|
67
|
+
title = secici.select_text("a", veri)
|
|
68
|
+
href = secici.select_attr("a", "href", veri)
|
|
69
|
+
poster = secici.select_attr("picture img", "data-src", veri)
|
|
78
70
|
|
|
79
71
|
if title and href:
|
|
80
72
|
results.append(SearchResult(
|
|
@@ -87,31 +79,25 @@ class FilmModu(PluginBase):
|
|
|
87
79
|
|
|
88
80
|
async def load_item(self, url: str) -> MovieInfo:
|
|
89
81
|
istek = await self.httpx.get(url)
|
|
90
|
-
secici =
|
|
91
|
-
|
|
92
|
-
org_title_el = secici.css_first("div.titles h1")
|
|
93
|
-
alt_title_el = secici.css_first("div.titles h2")
|
|
82
|
+
secici = HTMLHelper(istek.text)
|
|
94
83
|
|
|
95
|
-
org_title =
|
|
96
|
-
alt_title =
|
|
84
|
+
org_title = secici.select_text("div.titles h1") or ""
|
|
85
|
+
alt_title = secici.select_text("div.titles h2") or ""
|
|
97
86
|
title = f"{org_title} - {alt_title}" if alt_title else org_title
|
|
98
87
|
|
|
99
|
-
|
|
100
|
-
poster = poster_el.attrs.get("src") if poster_el else None
|
|
88
|
+
poster = secici.select_attr("img.img-responsive", "src") if secici.select_attr("img.img-responsive", "src") else None
|
|
101
89
|
|
|
102
|
-
|
|
103
|
-
description = desc_el.text(strip=True) if desc_el else None
|
|
90
|
+
description = secici.select_text("p[itemprop='description']") or None
|
|
104
91
|
|
|
105
|
-
tags =
|
|
92
|
+
tags = secici.select_all_text("a[href*='film-tur/']")
|
|
106
93
|
|
|
107
|
-
|
|
108
|
-
year = year_el.text(strip=True) if year_el else None
|
|
94
|
+
year = secici.select_text("span[itemprop='dateCreated']") or None
|
|
109
95
|
|
|
110
96
|
actors = []
|
|
111
|
-
for a in secici.
|
|
112
|
-
|
|
113
|
-
if
|
|
114
|
-
actors.append(
|
|
97
|
+
for a in secici.select("a[itemprop='actor']"):
|
|
98
|
+
name = secici.select_text("span", a)
|
|
99
|
+
if name:
|
|
100
|
+
actors.append(name)
|
|
115
101
|
|
|
116
102
|
return MovieInfo(
|
|
117
103
|
url = url,
|
|
@@ -125,9 +111,9 @@ class FilmModu(PluginBase):
|
|
|
125
111
|
|
|
126
112
|
async def load_links(self, url: str) -> list[ExtractResult]:
|
|
127
113
|
istek = await self.httpx.get(url)
|
|
128
|
-
secici =
|
|
114
|
+
secici = HTMLHelper(istek.text)
|
|
129
115
|
|
|
130
|
-
alternates = secici.
|
|
116
|
+
alternates = secici.select("div.alternates a")
|
|
131
117
|
if not alternates:
|
|
132
118
|
return []
|
|
133
119
|
|
|
@@ -144,14 +130,14 @@ class FilmModu(PluginBase):
|
|
|
144
130
|
alt_istek = await self.httpx.get(alt_link)
|
|
145
131
|
alt_text = alt_istek.text
|
|
146
132
|
|
|
147
|
-
vid_id =
|
|
148
|
-
vid_type =
|
|
133
|
+
vid_id = HTMLHelper(alt_text).regex_first(r"var videoId = '([^']*)'")
|
|
134
|
+
vid_type = HTMLHelper(alt_text).regex_first(r"var videoType = '([^']*)'")
|
|
149
135
|
|
|
150
136
|
if not vid_id or not vid_type:
|
|
151
137
|
continue
|
|
152
138
|
|
|
153
139
|
source_istek = await self.httpx.get(
|
|
154
|
-
f"{self.main_url}/get-source?movie_id={vid_id
|
|
140
|
+
f"{self.main_url}/get-source?movie_id={vid_id}&type={vid_type}"
|
|
155
141
|
)
|
|
156
142
|
source_data = source_istek.json()
|
|
157
143
|
|
|
@@ -1,8 +1,7 @@
|
|
|
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, ExtractResult, Subtitle
|
|
4
|
-
|
|
5
|
-
import re, base64
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, SeriesInfo, Episode, ExtractResult, Subtitle, HTMLHelper
|
|
4
|
+
import base64
|
|
6
5
|
|
|
7
6
|
class FullHDFilm(PluginBase):
|
|
8
7
|
name = "FullHDFilm"
|
|
@@ -48,16 +47,13 @@ class FullHDFilm(PluginBase):
|
|
|
48
47
|
})
|
|
49
48
|
|
|
50
49
|
istek = await self.httpx.get(page_url)
|
|
51
|
-
secici =
|
|
50
|
+
secici = HTMLHelper(istek.text)
|
|
52
51
|
|
|
53
52
|
results = []
|
|
54
|
-
for veri in secici.
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
alt = img_el.attrs.get("alt") if img_el else None
|
|
59
|
-
poster = img_el.attrs.get("src") if img_el else None
|
|
60
|
-
href = link_el.attrs.get("href") if link_el else None
|
|
53
|
+
for veri in secici.select("div.movie-poster"):
|
|
54
|
+
alt = secici.select_attr("img", "alt", veri)
|
|
55
|
+
poster = secici.select_attr("img", "src", veri)
|
|
56
|
+
href = secici.select_attr("a", "href", veri)
|
|
61
57
|
|
|
62
58
|
if alt and href:
|
|
63
59
|
results.append(MainPageResult(
|
|
@@ -71,16 +67,13 @@ class FullHDFilm(PluginBase):
|
|
|
71
67
|
|
|
72
68
|
async def search(self, query: str) -> list[SearchResult]:
|
|
73
69
|
istek = await self.httpx.get(f"{self.main_url}/?s={query}")
|
|
74
|
-
secici =
|
|
70
|
+
secici = HTMLHelper(istek.text)
|
|
75
71
|
|
|
76
72
|
results = []
|
|
77
|
-
for veri in secici.
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
alt = img_el.attrs.get("alt") if img_el else None
|
|
82
|
-
poster = img_el.attrs.get("src") if img_el else None
|
|
83
|
-
href = link_el.attrs.get("href") if link_el else None
|
|
73
|
+
for veri in secici.select("div.movie-poster"):
|
|
74
|
+
alt = secici.select_attr("img", "alt", veri)
|
|
75
|
+
poster = secici.select_attr("img", "src", veri)
|
|
76
|
+
href = secici.select_attr("a", "href", veri)
|
|
84
77
|
|
|
85
78
|
if alt and href:
|
|
86
79
|
results.append(SearchResult(
|
|
@@ -93,58 +86,59 @@ class FullHDFilm(PluginBase):
|
|
|
93
86
|
|
|
94
87
|
async def load_item(self, url: str) -> MovieInfo | SeriesInfo:
|
|
95
88
|
istek = await self.httpx.get(url)
|
|
96
|
-
secici =
|
|
89
|
+
secici = HTMLHelper(istek.text)
|
|
97
90
|
html_text = istek.text
|
|
98
91
|
|
|
99
|
-
|
|
100
|
-
title = title_el.text(strip=True) if title_el else ""
|
|
92
|
+
title = secici.select_text("h1") or ""
|
|
101
93
|
|
|
102
|
-
|
|
103
|
-
poster
|
|
94
|
+
poster = secici.select_attr("div.poster img", "src") or ""
|
|
95
|
+
poster = self.fix_url(poster)
|
|
104
96
|
|
|
105
|
-
actors_el = secici.css_first("div.oyuncular.info")
|
|
106
97
|
actors = []
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
98
|
+
actors_text = secici.select_text("div.oyuncular.info")
|
|
99
|
+
if actors_text:
|
|
100
|
+
actors_text = actors_text.replace("Oyuncular:", "").strip()
|
|
101
|
+
actors = [a.strip() for a in actors_text.split(",")]
|
|
102
|
+
|
|
103
|
+
# Year: önce div.yayin-tarihi.info dene
|
|
104
|
+
year = secici.extract_year("div.yayin-tarihi.info")
|
|
112
105
|
|
|
113
|
-
#
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
106
|
+
# Fallback: h1'in parent'ından (2019) formatında ara
|
|
107
|
+
if not year:
|
|
108
|
+
# Parent'ın tüm text içeriğinden yıl çıkar
|
|
109
|
+
title_text = secici.select_text("h1")
|
|
110
|
+
if title_text:
|
|
111
|
+
# h1 parent'ındaki (2019) gibi text'i bul
|
|
112
|
+
year = secici.regex_first(r"\((\d{4})\)")
|
|
118
113
|
|
|
119
|
-
tags =
|
|
114
|
+
tags = secici.select_all_text("div.tur.info a")
|
|
120
115
|
|
|
121
116
|
# Rating: regex
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
rating_match = re.search(r"IMDb\s*([\d\.]+)", rating_text)
|
|
125
|
-
rating = rating_match.group(1) if rating_match else None
|
|
117
|
+
rating_text = secici.select_text("div.imdb") or ""
|
|
118
|
+
rating = HTMLHelper(rating_text).regex_first(r"IMDb\s*([\d\.]+)")
|
|
126
119
|
|
|
127
|
-
# Description:
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
if
|
|
132
|
-
|
|
120
|
+
# Description: önce div.film dene, yoksa og:description meta tag'ını kullan
|
|
121
|
+
description = secici.select_text("div.film")
|
|
122
|
+
|
|
123
|
+
# Fallback: og:description meta tag'ı
|
|
124
|
+
if not description:
|
|
125
|
+
og_desc = secici.select_attr("meta[property='og:description']", "content")
|
|
126
|
+
if og_desc:
|
|
127
|
+
description = og_desc
|
|
133
128
|
|
|
134
129
|
# Kotlin referansı: URL'de -dizi kontrolü veya tags içinde "dizi" kontrolü
|
|
135
130
|
is_series = "-dizi" in url.lower() or any("dizi" in tag.lower() for tag in tags)
|
|
136
131
|
|
|
137
132
|
if is_series:
|
|
138
133
|
episodes = []
|
|
139
|
-
part_elements = secici.
|
|
134
|
+
part_elements = secici.select("li.psec")
|
|
140
135
|
|
|
141
136
|
# pdata değerlerini çıkar
|
|
142
|
-
pdata_matches =
|
|
137
|
+
pdata_matches = HTMLHelper(html_text).regex_all(r"pdata\['([^']+)'\]\s*=\s*'([^']+)'")
|
|
143
138
|
|
|
144
139
|
for idx, el in enumerate(part_elements):
|
|
145
140
|
part_id = el.attrs.get("id")
|
|
146
|
-
|
|
147
|
-
part_name = link_el.text(strip=True) if link_el else None
|
|
141
|
+
part_name = secici.select_text("a", el)
|
|
148
142
|
|
|
149
143
|
if not part_name:
|
|
150
144
|
continue
|
|
@@ -154,11 +148,11 @@ class FullHDFilm(PluginBase):
|
|
|
154
148
|
continue
|
|
155
149
|
|
|
156
150
|
# Sezon ve bölüm numarası çıkar
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
sz_num = int(
|
|
161
|
-
ep_num = int(
|
|
151
|
+
sz_val = HTMLHelper(part_id.lower() if part_id else "").regex_first(r'(\d+)\s*sezon')
|
|
152
|
+
ep_val = HTMLHelper(part_name).regex_first(r'^(\d+)\.')
|
|
153
|
+
|
|
154
|
+
sz_num = int(sz_val) if sz_val and sz_val.isdigit() else 1
|
|
155
|
+
ep_num = int(ep_val) if ep_val and ep_val.isdigit() else idx + 1
|
|
162
156
|
|
|
163
157
|
# pdata'dan video URL'si çık (varsa)
|
|
164
158
|
video_url = url # Varsayılan olarak ana URL kullan
|
|
@@ -197,14 +191,14 @@ class FullHDFilm(PluginBase):
|
|
|
197
191
|
|
|
198
192
|
def _get_iframe(self, source_code: str) -> str:
|
|
199
193
|
"""Base64 kodlu iframe'i çözümle"""
|
|
200
|
-
|
|
201
|
-
if not
|
|
194
|
+
script_val = HTMLHelper(source_code).regex_first(r'<script[^>]*>(PCEtLWJhc2xpazp[^<]*)</script>')
|
|
195
|
+
if not script_val:
|
|
202
196
|
return ""
|
|
203
197
|
|
|
204
198
|
try:
|
|
205
|
-
decoded_html = base64.b64decode(
|
|
206
|
-
|
|
207
|
-
return self.fix_url(
|
|
199
|
+
decoded_html = base64.b64decode(script_val).decode("utf-8")
|
|
200
|
+
iframe_src = HTMLHelper(decoded_html).regex_first(r'<iframe[^>]+src=["\']([^"\']+)["\']')
|
|
201
|
+
return self.fix_url(iframe_src) if iframe_src else ""
|
|
208
202
|
except Exception:
|
|
209
203
|
return ""
|
|
210
204
|
|
|
@@ -217,8 +211,9 @@ class FullHDFilm(PluginBase):
|
|
|
217
211
|
]
|
|
218
212
|
|
|
219
213
|
for pattern in patterns:
|
|
220
|
-
|
|
221
|
-
|
|
214
|
+
val = HTMLHelper(source_code).regex_first(pattern)
|
|
215
|
+
if val:
|
|
216
|
+
return val
|
|
222
217
|
|
|
223
218
|
return None
|
|
224
219
|
|
|
@@ -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, MovieInfo, ExtractResult
|
|
4
|
-
from selectolax.parser import HTMLParser
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, ExtractResult, HTMLHelper
|
|
5
4
|
from Kekik.Sifreleme import StringCodec
|
|
6
|
-
import json
|
|
5
|
+
import json
|
|
7
6
|
|
|
8
7
|
class FullHDFilmizlesene(PluginBase):
|
|
9
8
|
name = "FullHDFilmizlesene"
|
|
@@ -42,17 +41,13 @@ class FullHDFilmizlesene(PluginBase):
|
|
|
42
41
|
|
|
43
42
|
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
44
43
|
istek = self.cloudscraper.get(f"{url}{page}")
|
|
45
|
-
secici =
|
|
44
|
+
secici = HTMLHelper(istek.text)
|
|
46
45
|
|
|
47
46
|
results = []
|
|
48
|
-
for veri in secici.
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
title = title_el.text(strip=True) if title_el else None
|
|
54
|
-
href = link_el.attrs.get("href") if link_el else None
|
|
55
|
-
poster = img_el.attrs.get("data-src") if img_el else None
|
|
47
|
+
for veri in secici.select("li.film"):
|
|
48
|
+
title = secici.select_text("span.film-title", veri)
|
|
49
|
+
href = secici.select_attr("a", "href", veri)
|
|
50
|
+
poster = secici.select_attr("img", "data-src", veri)
|
|
56
51
|
|
|
57
52
|
if title and href:
|
|
58
53
|
results.append(MainPageResult(
|
|
@@ -66,17 +61,13 @@ class FullHDFilmizlesene(PluginBase):
|
|
|
66
61
|
|
|
67
62
|
async def search(self, query: str) -> list[SearchResult]:
|
|
68
63
|
istek = await self.httpx.get(f"{self.main_url}/arama/{query}")
|
|
69
|
-
secici =
|
|
64
|
+
secici = HTMLHelper(istek.text)
|
|
70
65
|
|
|
71
66
|
results = []
|
|
72
|
-
for film in secici.
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
title = title_el.text(strip=True) if title_el else None
|
|
78
|
-
href = link_el.attrs.get("href") if link_el else None
|
|
79
|
-
poster = img_el.attrs.get("data-src") if img_el else None
|
|
67
|
+
for film in secici.select("li.film"):
|
|
68
|
+
title = secici.select_text("span.film-title", film)
|
|
69
|
+
href = secici.select_attr("a", "href", film)
|
|
70
|
+
poster = secici.select_attr("img", "data-src", film)
|
|
80
71
|
|
|
81
72
|
if title and href:
|
|
82
73
|
results.append(SearchResult(
|
|
@@ -89,49 +80,42 @@ class FullHDFilmizlesene(PluginBase):
|
|
|
89
80
|
|
|
90
81
|
async def load_item(self, url: str) -> MovieInfo:
|
|
91
82
|
istek = await self.httpx.get(url)
|
|
92
|
-
secici =
|
|
83
|
+
secici = HTMLHelper(istek.text)
|
|
93
84
|
html_text = istek.text
|
|
94
85
|
|
|
95
86
|
# Title: normalize-space yerine doğrudan class ile
|
|
96
|
-
|
|
97
|
-
title = title_el.text(strip=True) if title_el else ""
|
|
87
|
+
title = secici.select_text("div.izle-titles") or ""
|
|
98
88
|
|
|
99
|
-
|
|
100
|
-
poster =
|
|
89
|
+
poster = secici.select_attr("div img[data-src]", "data-src") or ""
|
|
90
|
+
poster = poster.strip()
|
|
101
91
|
|
|
102
|
-
|
|
103
|
-
description = desc_el.text(strip=True) if desc_el else ""
|
|
92
|
+
description = secici.select_text("div.ozet-ic p") or ""
|
|
104
93
|
|
|
105
|
-
tags =
|
|
94
|
+
tags = secici.select_all_text("a[rel='category tag']")
|
|
106
95
|
|
|
107
96
|
# Rating: normalize-space yerine doğrudan class ile ve son kelimeyi al
|
|
108
|
-
|
|
97
|
+
rating_text = secici.select_text("div.puanx-puan") or None
|
|
109
98
|
rating = None
|
|
110
|
-
if
|
|
111
|
-
|
|
112
|
-
if
|
|
113
|
-
parts = rating_text.split()
|
|
114
|
-
rating = parts[-1] if parts else None
|
|
99
|
+
if rating_text:
|
|
100
|
+
parts = rating_text.split()
|
|
101
|
+
rating = parts[-1] if parts else None
|
|
115
102
|
|
|
116
103
|
# Year: ilk yıl formatında değer
|
|
117
|
-
|
|
104
|
+
year_text = secici.select_text("div.dd a.category") or None
|
|
118
105
|
year = None
|
|
119
|
-
if
|
|
120
|
-
|
|
121
|
-
if
|
|
122
|
-
parts = year_text.split()
|
|
123
|
-
year = parts[0] if parts else None
|
|
106
|
+
if year_text:
|
|
107
|
+
parts = year_text.split()
|
|
108
|
+
year = parts[0] if parts else None
|
|
124
109
|
|
|
125
110
|
# Actors: nth-child yerine tüm li'leri alıp 2. index
|
|
126
|
-
lis = secici.
|
|
111
|
+
lis = secici.select("div.film-info ul li")
|
|
127
112
|
actors = []
|
|
128
113
|
if len(lis) >= 2:
|
|
129
|
-
actors =
|
|
114
|
+
actors = secici.select_all_text("a > span", lis[1])
|
|
130
115
|
|
|
131
|
-
duration_el = secici.css_first("span.sure")
|
|
132
116
|
duration = "0"
|
|
133
|
-
|
|
134
|
-
|
|
117
|
+
duration_text = secici.select_text("span.sure") or None
|
|
118
|
+
if duration_text:
|
|
135
119
|
duration_parts = duration_text.split()
|
|
136
120
|
duration = duration_parts[0] if duration_parts else "0"
|
|
137
121
|
|
|
@@ -149,18 +133,18 @@ class FullHDFilmizlesene(PluginBase):
|
|
|
149
133
|
|
|
150
134
|
async def load_links(self, url: str) -> list[ExtractResult]:
|
|
151
135
|
istek = await self.httpx.get(url)
|
|
152
|
-
secici =
|
|
136
|
+
secici = HTMLHelper(istek.text)
|
|
153
137
|
html_text = istek.text
|
|
154
138
|
|
|
155
139
|
# İlk script'i al (xpath (//script)[1] yerine)
|
|
156
|
-
scripts = secici.
|
|
140
|
+
scripts = secici.select("script")
|
|
157
141
|
script_content = scripts[0].text() if scripts else ""
|
|
158
142
|
|
|
159
|
-
|
|
160
|
-
if not
|
|
143
|
+
scx_json = HTMLHelper(script_content).regex_first(r"scx = (.*?);")
|
|
144
|
+
if not scx_json:
|
|
161
145
|
return []
|
|
162
146
|
|
|
163
|
-
scx_data = json.loads(
|
|
147
|
+
scx_data = json.loads(scx_json)
|
|
164
148
|
scx_keys = list(scx_data.keys())
|
|
165
149
|
|
|
166
150
|
link_list = []
|