KekikStream 2.4.7__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.
- KekikStream/Plugins/BelgeselX.py +3 -4
- KekikStream/Plugins/DiziBox.py +3 -3
- KekikStream/Plugins/DiziMom.py +48 -42
- KekikStream/Plugins/DiziPal.py +1 -1
- KekikStream/Plugins/Dizilla.py +2 -2
- KekikStream/Plugins/FilmBip.py +4 -11
- KekikStream/Plugins/FilmEkseni.py +59 -55
- KekikStream/Plugins/FilmMakinesi.py +42 -5
- KekikStream/Plugins/FilmModu.py +0 -1
- KekikStream/Plugins/Filmatek.py +4 -11
- KekikStream/Plugins/{Full4kizle.py → FilmciBaba.py} +55 -74
- KekikStream/Plugins/FullHDFilmizlesene.py +6 -7
- KekikStream/Plugins/HDFilm.py +243 -0
- KekikStream/Plugins/HDFilmCehennemi.py +193 -124
- {kekikstream-2.4.7.dist-info → kekikstream-2.4.8.dist-info}/METADATA +1 -1
- {kekikstream-2.4.7.dist-info → kekikstream-2.4.8.dist-info}/RECORD +20 -20
- KekikStream/Plugins/FullHDFilm.py +0 -179
- {kekikstream-2.4.7.dist-info → kekikstream-2.4.8.dist-info}/WHEEL +0 -0
- {kekikstream-2.4.7.dist-info → kekikstream-2.4.8.dist-info}/entry_points.txt +0 -0
- {kekikstream-2.4.7.dist-info → kekikstream-2.4.8.dist-info}/licenses/LICENSE +0 -0
- {kekikstream-2.4.7.dist-info → kekikstream-2.4.8.dist-info}/top_level.txt +0 -0
KekikStream/Plugins/BelgeselX.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
2
|
|
|
3
3
|
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, SeriesInfo, Episode, ExtractResult, HTMLHelper
|
|
4
|
+
from contextlib import suppress
|
|
4
5
|
|
|
5
6
|
class BelgeselX(PluginBase):
|
|
6
7
|
name = "BelgeselX"
|
|
@@ -209,12 +210,10 @@ class BelgeselX(PluginBase):
|
|
|
209
210
|
|
|
210
211
|
# belgeselx.php redirect'ini çöz
|
|
211
212
|
if "belgeselx.php" in video_url or "belgeselx2.php" in video_url:
|
|
212
|
-
|
|
213
|
+
with suppress(Exception):
|
|
213
214
|
# HEAD isteği ile lokasyonu alalım
|
|
214
|
-
resp
|
|
215
|
+
resp = await self.httpx.head(video_url, headers={"Referer": main_url}, follow_redirects=True)
|
|
215
216
|
video_url = str(resp.url)
|
|
216
|
-
except:
|
|
217
|
-
pass
|
|
218
217
|
|
|
219
218
|
links.append(ExtractResult(
|
|
220
219
|
url = video_url,
|
KekikStream/Plugins/DiziBox.py
CHANGED
|
@@ -52,8 +52,8 @@ class DiziBox(PluginBase):
|
|
|
52
52
|
|
|
53
53
|
results = []
|
|
54
54
|
for veri in secici.select("article.detailed-article"):
|
|
55
|
-
title
|
|
56
|
-
href
|
|
55
|
+
title = secici.select_text("h3 a", veri)
|
|
56
|
+
href = secici.select_attr("h3 a", "href", veri)
|
|
57
57
|
poster = secici.select_attr("img", "src", veri)
|
|
58
58
|
|
|
59
59
|
if title and href:
|
|
@@ -185,7 +185,7 @@ class DiziBox(PluginBase):
|
|
|
185
185
|
# Aktif kaynağın adını bul (DBX Pro vs.)
|
|
186
186
|
current_source_name = secici.select_text("div.video-toolbar option[selected]") or self.name
|
|
187
187
|
|
|
188
|
-
results
|
|
188
|
+
results = []
|
|
189
189
|
main_iframe = secici.select_attr("div#video-area iframe", "src")
|
|
190
190
|
|
|
191
191
|
if main_iframe:
|
KekikStream/Plugins/DiziMom.py
CHANGED
|
@@ -10,24 +10,32 @@ class DiziMom(PluginBase):
|
|
|
10
10
|
description = "Binlerce yerli yabancı dizi arşivi, tüm sezonlar, kesintisiz bölümler. Sadece dizi izle, Dizimom heryerde seninle!"
|
|
11
11
|
|
|
12
12
|
main_page = {
|
|
13
|
-
f"{main_url}/tum-bolumler/page"
|
|
14
|
-
f"{main_url}/yerli-dizi-izle/page"
|
|
15
|
-
f"{main_url}/yabanci-dizi-izle/page"
|
|
16
|
-
f"{main_url}/tv-programlari-izle/page"
|
|
13
|
+
f"{main_url}/tum-bolumler/page" : "Son Bölümler",
|
|
14
|
+
f"{main_url}/yerli-dizi-izle/page" : "Yerli Diziler",
|
|
15
|
+
f"{main_url}/yabanci-dizi-izle/page" : "Yabancı Diziler",
|
|
16
|
+
f"{main_url}/tv-programlari-izle/page" : "TV Programları",
|
|
17
|
+
f"{main_url}/netflix-dizileri-izle/page" : "Netflix Dizileri",
|
|
18
|
+
f"{main_url}/turkce-dublaj-diziler-hd/page" : "Dublajlı Diziler",
|
|
19
|
+
f"{main_url}/yerli-dizi-izle/page" : "Yerli Diziler",
|
|
20
|
+
f"{main_url}/anime-izle/page" : "Animeler",
|
|
21
|
+
f"{main_url}/yabanci-dizi-izle/page" : "Yabancı Diziler",
|
|
22
|
+
f"{main_url}/kore-dizileri-izle-hd/page" : "Kore Dizileri",
|
|
23
|
+
f"{main_url}/full-hd-hint-dizileri-izle/page" : "Hint Dizileri",
|
|
24
|
+
f"{main_url}/pakistan-dizileri-izle/page" : "Pakistan Dizileri",
|
|
25
|
+
f"{main_url}/tv-programlari-izle/page" : "Tv Programları",
|
|
17
26
|
}
|
|
18
27
|
|
|
19
28
|
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
helper = HTMLHelper(istek.text)
|
|
29
|
+
istek = await self.httpx.get(f"{url}/{page}/")
|
|
30
|
+
secici = HTMLHelper(istek.text)
|
|
23
31
|
|
|
24
32
|
results = []
|
|
25
33
|
# Eğer "tum-bolumler" ise Episode kutularını, değilse Dizi kutularını tara
|
|
26
34
|
if "/tum-bolumler/" in url:
|
|
27
|
-
for item in
|
|
28
|
-
title =
|
|
29
|
-
href =
|
|
30
|
-
img =
|
|
35
|
+
for item in secici.select("div.episode-box"):
|
|
36
|
+
title = secici.select_text("div.episode-name a", item)
|
|
37
|
+
href = secici.select_attr("div.episode-name a", "href", item)
|
|
38
|
+
img = secici.select_poster("div.cat-img img", item)
|
|
31
39
|
if title and href:
|
|
32
40
|
results.append(MainPageResult(
|
|
33
41
|
category = category,
|
|
@@ -36,10 +44,10 @@ class DiziMom(PluginBase):
|
|
|
36
44
|
poster = self.fix_url(img)
|
|
37
45
|
))
|
|
38
46
|
else:
|
|
39
|
-
for item in
|
|
40
|
-
title =
|
|
41
|
-
href =
|
|
42
|
-
img =
|
|
47
|
+
for item in secici.select("div.single-item"):
|
|
48
|
+
title = secici.select_text("div.categorytitle a", item)
|
|
49
|
+
href = secici.select_attr("div.categorytitle a", "href", item)
|
|
50
|
+
img = secici.select_poster("div.cat-img img", item)
|
|
43
51
|
if title and href:
|
|
44
52
|
results.append(MainPageResult(
|
|
45
53
|
category = category,
|
|
@@ -51,38 +59,37 @@ class DiziMom(PluginBase):
|
|
|
51
59
|
return results
|
|
52
60
|
|
|
53
61
|
async def search(self, query: str) -> list[SearchResult]:
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
items = helper.select("div.single-item")
|
|
62
|
+
istek = await self.httpx.get(f"{self.main_url}/?s={query}")
|
|
63
|
+
secici = HTMLHelper(istek.text)
|
|
64
|
+
items = secici.select("div.single-item")
|
|
58
65
|
|
|
59
66
|
return [
|
|
60
67
|
SearchResult(
|
|
61
|
-
title =
|
|
62
|
-
url = self.fix_url(
|
|
63
|
-
poster = self.fix_url(
|
|
68
|
+
title = secici.select_text("div.categorytitle a", item).split(" izle")[0],
|
|
69
|
+
url = self.fix_url(secici.select_attr("div.categorytitle a", "href", item)),
|
|
70
|
+
poster = self.fix_url(secici.select_attr("div.cat-img img", "src", item))
|
|
64
71
|
)
|
|
65
72
|
for item in items
|
|
66
73
|
]
|
|
67
74
|
|
|
68
75
|
async def load_item(self, url: str) -> SeriesInfo:
|
|
69
76
|
istek = await self.httpx.get(url)
|
|
70
|
-
|
|
77
|
+
secici = HTMLHelper(istek.text)
|
|
71
78
|
|
|
72
|
-
title = self.clean_title(
|
|
73
|
-
poster =
|
|
74
|
-
description =
|
|
75
|
-
tags =
|
|
76
|
-
rating =
|
|
77
|
-
year =
|
|
78
|
-
actors =
|
|
79
|
+
title = self.clean_title(secici.select_text("div.title h1"))
|
|
80
|
+
poster = secici.select_poster("div.category_image img")
|
|
81
|
+
description = secici.select_direct_text("div.category_desc")
|
|
82
|
+
tags = secici.select_texts("div.genres a")
|
|
83
|
+
rating = secici.regex_first(r"(?s)IMDB\s*:\s*(?:</span>)?\s*([\d\.]+)", secici.html)
|
|
84
|
+
year = secici.extract_year("div.category_text")
|
|
85
|
+
actors = secici.meta_list("Oyuncular", container_selector="div#icerikcat2")
|
|
79
86
|
|
|
80
87
|
episodes = []
|
|
81
|
-
for item in
|
|
82
|
-
name =
|
|
83
|
-
href =
|
|
88
|
+
for item in secici.select("div.bolumust"):
|
|
89
|
+
name = secici.select_text("div.baslik", item)
|
|
90
|
+
href = secici.select_attr("a", "href", item)
|
|
84
91
|
if name and href:
|
|
85
|
-
s, e =
|
|
92
|
+
s, e = secici.extract_season_episode(name)
|
|
86
93
|
episodes.append(Episode(
|
|
87
94
|
season = s or 1,
|
|
88
95
|
episode = e or 1,
|
|
@@ -120,27 +127,26 @@ class DiziMom(PluginBase):
|
|
|
120
127
|
)
|
|
121
128
|
|
|
122
129
|
istek = await self.httpx.get(url)
|
|
123
|
-
|
|
130
|
+
secici = HTMLHelper(istek.text)
|
|
124
131
|
|
|
125
132
|
iframe_data = []
|
|
126
133
|
|
|
127
134
|
# Aktif kaynağın (main iframe) adını bul
|
|
128
|
-
current_name =
|
|
129
|
-
main_iframe
|
|
135
|
+
current_name = secici.select_text("div.sources span.current_dil") or ""
|
|
136
|
+
main_iframe = secici.select_attr("iframe[src]", "src")
|
|
130
137
|
|
|
131
138
|
# Bazen iframe doğrudan video p içinde olabilir
|
|
132
139
|
if not main_iframe:
|
|
133
|
-
main_iframe =
|
|
140
|
+
main_iframe = secici.select_attr("div.video p iframe", "src")
|
|
134
141
|
|
|
135
142
|
if main_iframe:
|
|
136
143
|
iframe_data.append((main_iframe, current_name))
|
|
137
144
|
|
|
138
145
|
# Diğer kaynakları (Partlar) gez
|
|
139
|
-
sources =
|
|
146
|
+
sources = secici.select("div.sources a.post-page-numbers")
|
|
140
147
|
for source in sources:
|
|
141
|
-
href =
|
|
142
|
-
name =
|
|
143
|
-
|
|
148
|
+
href = secici.select_attr(None, "href", source)
|
|
149
|
+
name = secici.select_text("span.dil", source)
|
|
144
150
|
if href:
|
|
145
151
|
# Part sayfasına git
|
|
146
152
|
sub_istek = await self.httpx.get(href)
|
KekikStream/Plugins/DiziPal.py
CHANGED
KekikStream/Plugins/Dizilla.py
CHANGED
|
@@ -54,7 +54,7 @@ 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
|
|
@@ -118,7 +118,7 @@ class Dizilla(PluginBase):
|
|
|
118
118
|
SearchResult(
|
|
119
119
|
title = veri.get("object_name"),
|
|
120
120
|
url = self.fix_url(f"{self.main_url}/{veri.get('used_slug')}"),
|
|
121
|
-
poster = self.fix_poster_url(self.fix_url(veri.get("
|
|
121
|
+
poster = self.fix_poster_url(self.fix_url(veri.get("object_poster_url"))),
|
|
122
122
|
)
|
|
123
123
|
for veri in arama_veri
|
|
124
124
|
]
|
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
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"
|
|
@@ -123,12 +124,8 @@ class FilmBip(PluginBase):
|
|
|
123
124
|
secici = HTMLHelper(istek.text)
|
|
124
125
|
|
|
125
126
|
results = []
|
|
126
|
-
|
|
127
|
-
tabs = secici.select("ul.tab.alternative-group li[data-number]")
|
|
128
|
-
|
|
129
|
-
for tab in tabs:
|
|
127
|
+
for tab in secici.select("ul.tab.alternative-group li[data-number]"):
|
|
130
128
|
tab_id = tab.attrs.get("data-number")
|
|
131
|
-
# Tab ismini al
|
|
132
129
|
tab_name = secici.select_text(None, tab)
|
|
133
130
|
tab_hash = tab.attrs.get("data-group-hash")
|
|
134
131
|
|
|
@@ -148,7 +145,7 @@ class FilmBip(PluginBase):
|
|
|
148
145
|
|
|
149
146
|
elif tab_hash:
|
|
150
147
|
# Div yok veya boş, AJAX ile çek
|
|
151
|
-
|
|
148
|
+
with suppress(Exception):
|
|
152
149
|
hash_resp = await self.httpx.post(
|
|
153
150
|
url = f"{self.main_url}/get/video/group",
|
|
154
151
|
headers = {
|
|
@@ -175,11 +172,9 @@ class FilmBip(PluginBase):
|
|
|
175
172
|
sub_btns = sub_helper.select("ul li button")
|
|
176
173
|
for btn in sub_btns:
|
|
177
174
|
button_data.append((btn.text(strip=True), btn.attrs.get("data-hhs")))
|
|
178
|
-
except Exception:
|
|
179
|
-
pass
|
|
180
175
|
|
|
181
176
|
for player_name, iframe_url in button_data:
|
|
182
|
-
|
|
177
|
+
with suppress(Exception):
|
|
183
178
|
if iframe_url:
|
|
184
179
|
data = await self.extract(
|
|
185
180
|
url = self.fix_url(iframe_url),
|
|
@@ -190,8 +185,6 @@ class FilmBip(PluginBase):
|
|
|
190
185
|
results.extend(data)
|
|
191
186
|
else:
|
|
192
187
|
results.append(data)
|
|
193
|
-
except Exception:
|
|
194
|
-
pass
|
|
195
188
|
|
|
196
189
|
# Eğer hiç sonuç bulunamazsa fallback
|
|
197
190
|
if not results:
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
2
|
|
|
3
3
|
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, ExtractResult, HTMLHelper
|
|
4
|
+
import asyncio
|
|
4
5
|
|
|
5
6
|
class FilmEkseni(PluginBase):
|
|
6
7
|
name = "FilmEkseni"
|
|
@@ -30,17 +31,17 @@ class FilmEkseni(PluginBase):
|
|
|
30
31
|
|
|
31
32
|
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
32
33
|
istek = await self.httpx.get(f"{url}/{page}/")
|
|
33
|
-
|
|
34
|
-
posters =
|
|
34
|
+
secici = HTMLHelper(istek.text)
|
|
35
|
+
posters = secici.select("div.poster")
|
|
35
36
|
|
|
36
37
|
return [
|
|
37
38
|
MainPageResult(
|
|
38
39
|
category = category,
|
|
39
|
-
title = self.clean_title(
|
|
40
|
-
url =
|
|
41
|
-
poster =
|
|
40
|
+
title = self.clean_title(secici.select_text("h2", veri)),
|
|
41
|
+
url = secici.select_attr("a", "href", veri),
|
|
42
|
+
poster = secici.select_attr("img", "data-src", veri)
|
|
42
43
|
)
|
|
43
|
-
|
|
44
|
+
for veri in posters
|
|
44
45
|
]
|
|
45
46
|
|
|
46
47
|
async def search(self, query: str) -> list[SearchResult]:
|
|
@@ -62,21 +63,21 @@ class FilmEkseni(PluginBase):
|
|
|
62
63
|
url = f"{self.main_url}/{veri.get('slug')}",
|
|
63
64
|
poster = f"{self.main_url}/uploads/poster/{veri.get('cover')}" if veri.get('cover') else None,
|
|
64
65
|
)
|
|
65
|
-
|
|
66
|
+
for veri in veriler
|
|
66
67
|
]
|
|
67
68
|
|
|
68
69
|
async def load_item(self, url: str) -> MovieInfo:
|
|
69
70
|
istek = await self.httpx.get(url)
|
|
70
|
-
|
|
71
|
+
secici = HTMLHelper(istek.text)
|
|
71
72
|
|
|
72
|
-
title = self.clean_title(
|
|
73
|
-
poster =
|
|
74
|
-
description =
|
|
75
|
-
year =
|
|
76
|
-
tags =
|
|
77
|
-
rating =
|
|
78
|
-
duration =
|
|
79
|
-
actors =
|
|
73
|
+
title = self.clean_title(secici.select_text("div.page-title h1"))
|
|
74
|
+
poster = secici.select_poster("picture.poster-auto img")
|
|
75
|
+
description = secici.select_direct_text("article.text-white p")
|
|
76
|
+
year = secici.extract_year("div.page-title", "strong a")
|
|
77
|
+
tags = secici.select_texts("div.pb-2 a[href*='/tur/']")
|
|
78
|
+
rating = secici.select_text("div.rate")
|
|
79
|
+
duration = secici.regex_first(r"(\d+)", secici.select_text("div.d-flex.flex-column.text-nowrap"))
|
|
80
|
+
actors = secici.select_texts("div.card-body.p-0.pt-2 .story-item .story-item-title")
|
|
80
81
|
|
|
81
82
|
return MovieInfo(
|
|
82
83
|
url = url,
|
|
@@ -90,51 +91,24 @@ class FilmEkseni(PluginBase):
|
|
|
90
91
|
duration = duration
|
|
91
92
|
)
|
|
92
93
|
|
|
93
|
-
async def
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
nav_links = helper.select("nav.card-nav a.nav-link")
|
|
101
|
-
if nav_links:
|
|
102
|
-
seen_urls = set()
|
|
103
|
-
for link in nav_links:
|
|
104
|
-
if link.attrs.get("href") == "#":
|
|
105
|
-
continue # Sinema Modu vb.
|
|
106
|
-
|
|
107
|
-
name = link.text(strip=True)
|
|
108
|
-
href = link.attrs.get("href")
|
|
109
|
-
is_active = "active" in link.attrs.get("class", "")
|
|
110
|
-
|
|
111
|
-
if href and href not in seen_urls:
|
|
112
|
-
seen_urls.add(href)
|
|
113
|
-
sources.append((name, href, is_active))
|
|
114
|
-
else:
|
|
115
|
-
# Nav yoksa mevcut sayfayı (Varsayılan/VIP) al
|
|
116
|
-
sources.append(("VIP", url, True))
|
|
117
|
-
|
|
118
|
-
for name, link_url, is_active in sources:
|
|
119
|
-
current_helper = helper
|
|
120
|
-
|
|
121
|
-
# Eğer aktif değilse sayfaya git
|
|
122
|
-
if not is_active:
|
|
123
|
-
try:
|
|
124
|
-
resp = await self.httpx.get(link_url)
|
|
125
|
-
current_helper = HTMLHelper(resp.text)
|
|
126
|
-
except:
|
|
127
|
-
continue
|
|
94
|
+
async def _get_source_links(self, name: str, url: str, is_active: bool, initial_helper: HTMLHelper | None = None) -> list[ExtractResult]:
|
|
95
|
+
try:
|
|
96
|
+
if is_active and initial_helper:
|
|
97
|
+
secici = initial_helper
|
|
98
|
+
else:
|
|
99
|
+
resp = await self.httpx.get(url)
|
|
100
|
+
secici = HTMLHelper(resp.text)
|
|
128
101
|
|
|
129
|
-
iframe =
|
|
102
|
+
iframe = secici.select_first("div.card-video iframe")
|
|
130
103
|
if not iframe:
|
|
131
|
-
|
|
104
|
+
return []
|
|
132
105
|
|
|
133
106
|
iframe_url = iframe.attrs.get("data-src") or iframe.attrs.get("src")
|
|
134
107
|
if not iframe_url:
|
|
135
|
-
|
|
108
|
+
return []
|
|
136
109
|
|
|
137
110
|
iframe_url = self.fix_url(iframe_url)
|
|
111
|
+
results = []
|
|
138
112
|
|
|
139
113
|
# VIP / EksenLoad mantığı
|
|
140
114
|
if "eksenload" in iframe_url or name == "VIP":
|
|
@@ -155,4 +129,34 @@ class FilmEkseni(PluginBase):
|
|
|
155
129
|
else:
|
|
156
130
|
results.append(extracted)
|
|
157
131
|
|
|
158
|
-
|
|
132
|
+
return results
|
|
133
|
+
except Exception:
|
|
134
|
+
return []
|
|
135
|
+
|
|
136
|
+
async def load_links(self, url: str) -> list[ExtractResult]:
|
|
137
|
+
istek = await self.httpx.get(url)
|
|
138
|
+
secici = HTMLHelper(istek.text)
|
|
139
|
+
|
|
140
|
+
sources = [] # (name, url, is_active)
|
|
141
|
+
if nav_links := secici.select("nav.card-nav a.nav-link"):
|
|
142
|
+
seen_urls = set()
|
|
143
|
+
for link in nav_links:
|
|
144
|
+
if link.attrs.get("href") == "#":
|
|
145
|
+
continue # Sinema Modu vb.
|
|
146
|
+
|
|
147
|
+
name = link.text(strip=True)
|
|
148
|
+
href = link.attrs.get("href")
|
|
149
|
+
is_active = "active" in link.attrs.get("class", "")
|
|
150
|
+
|
|
151
|
+
if href and href not in seen_urls:
|
|
152
|
+
seen_urls.add(href)
|
|
153
|
+
sources.append((name, href, is_active))
|
|
154
|
+
else:
|
|
155
|
+
# Nav yoksa mevcut sayfayı (Varsayılan/VIP) al
|
|
156
|
+
sources.append(("VIP", url, True))
|
|
157
|
+
|
|
158
|
+
tasks = []
|
|
159
|
+
for name, link_url, is_active in sources:
|
|
160
|
+
tasks.append(self._get_source_links(name, link_url, is_active, secici if is_active else None))
|
|
161
|
+
|
|
162
|
+
return [item for sublist in await asyncio.gather(*tasks) for item in sublist]
|
|
@@ -79,7 +79,7 @@ class FilmMakinesi(PluginBase):
|
|
|
79
79
|
title = self.clean_title(secici.select_text("h1.title"))
|
|
80
80
|
poster = secici.select_poster("img.cover-img")
|
|
81
81
|
description = secici.select_text("div.info-description p")
|
|
82
|
-
rating = secici.
|
|
82
|
+
rating = secici.select_text("div.info div.imdb b")
|
|
83
83
|
year = secici.select_text("span.date a")
|
|
84
84
|
actors = secici.select_texts("div.cast-name")
|
|
85
85
|
tags = secici.select_texts("div.type a[href*='/tur/']")
|
|
@@ -91,7 +91,12 @@ class FilmMakinesi(PluginBase):
|
|
|
91
91
|
s, e = secici.extract_season_episode(href)
|
|
92
92
|
if s and e:
|
|
93
93
|
name = link.text(strip=True).split("Bölüm")[-1].strip() if "Bölüm" in link.text() else ""
|
|
94
|
-
episodes.append(Episode(
|
|
94
|
+
episodes.append(Episode(
|
|
95
|
+
season = s,
|
|
96
|
+
episode = e,
|
|
97
|
+
title = name,
|
|
98
|
+
url = self.fix_url(href)
|
|
99
|
+
))
|
|
95
100
|
|
|
96
101
|
# Tekrar edenleri temizle ve sırala
|
|
97
102
|
if episodes:
|
|
@@ -132,7 +137,8 @@ class FilmMakinesi(PluginBase):
|
|
|
132
137
|
istek = await self.httpx.get(url)
|
|
133
138
|
secici = HTMLHelper(istek.text)
|
|
134
139
|
|
|
135
|
-
response
|
|
140
|
+
response = []
|
|
141
|
+
shared_subs = []
|
|
136
142
|
|
|
137
143
|
# Video parts linklerini ve etiketlerini al
|
|
138
144
|
for link in secici.select("div.video-parts a[data-video_url]"):
|
|
@@ -142,7 +148,15 @@ class FilmMakinesi(PluginBase):
|
|
|
142
148
|
if video_url:
|
|
143
149
|
data = await self.extract(video_url, prefix=label.split()[0] if label else None)
|
|
144
150
|
if data:
|
|
145
|
-
|
|
151
|
+
if isinstance(data, list):
|
|
152
|
+
for d in data:
|
|
153
|
+
response.append(d)
|
|
154
|
+
if d.subtitles:
|
|
155
|
+
shared_subs.extend(d.subtitles)
|
|
156
|
+
else:
|
|
157
|
+
response.append(data)
|
|
158
|
+
if data.subtitles:
|
|
159
|
+
shared_subs.extend(data.subtitles)
|
|
146
160
|
|
|
147
161
|
# Eğer video-parts yoksa iframe kullan
|
|
148
162
|
if not response:
|
|
@@ -150,6 +164,29 @@ class FilmMakinesi(PluginBase):
|
|
|
150
164
|
if iframe_src:
|
|
151
165
|
data = await self.extract(iframe_src)
|
|
152
166
|
if data:
|
|
153
|
-
|
|
167
|
+
if isinstance(data, list):
|
|
168
|
+
for d in data:
|
|
169
|
+
response.append(d)
|
|
170
|
+
if d.subtitles:
|
|
171
|
+
shared_subs.extend(d.subtitles)
|
|
172
|
+
else:
|
|
173
|
+
response.append(data)
|
|
174
|
+
if data.subtitles:
|
|
175
|
+
shared_subs.extend(data.subtitles)
|
|
176
|
+
|
|
177
|
+
# Altyazıları Dağıt
|
|
178
|
+
if shared_subs:
|
|
179
|
+
unique_subs = []
|
|
180
|
+
seen_urls = set()
|
|
181
|
+
for sub in shared_subs:
|
|
182
|
+
if sub.url not in seen_urls:
|
|
183
|
+
seen_urls.add(sub.url)
|
|
184
|
+
unique_subs.append(sub)
|
|
185
|
+
|
|
186
|
+
for res in response:
|
|
187
|
+
current_urls = {s.url for s in res.subtitles}
|
|
188
|
+
for sub in unique_subs:
|
|
189
|
+
if sub.url not in current_urls:
|
|
190
|
+
res.subtitles.append(sub)
|
|
154
191
|
|
|
155
192
|
return response
|
KekikStream/Plugins/FilmModu.py
CHANGED
KekikStream/Plugins/Filmatek.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, ExtractResult, HTMLHelper
|
|
4
4
|
from urllib.parse import unquote
|
|
5
|
-
|
|
5
|
+
from contextlib import suppress
|
|
6
6
|
|
|
7
7
|
class Filmatek(PluginBase):
|
|
8
8
|
name = "Filmatek"
|
|
@@ -29,10 +29,8 @@ class Filmatek(PluginBase):
|
|
|
29
29
|
istek = await self.httpx.get(f"{url}/{page}/")
|
|
30
30
|
secici = HTMLHelper(istek.text)
|
|
31
31
|
|
|
32
|
-
items = secici.select("div.items article, #archive-content article")
|
|
33
32
|
results = []
|
|
34
|
-
|
|
35
|
-
for item in items:
|
|
33
|
+
for item in secici.select("div.items article, #archive-content article"):
|
|
36
34
|
title_el = secici.select_first("div.data h3 a, h3 a", item)
|
|
37
35
|
if not title_el:
|
|
38
36
|
continue
|
|
@@ -54,10 +52,8 @@ class Filmatek(PluginBase):
|
|
|
54
52
|
istek = await self.httpx.get(f"{self.main_url}/?s={query}")
|
|
55
53
|
secici = HTMLHelper(istek.text)
|
|
56
54
|
|
|
57
|
-
items = secici.select("div.result-item")
|
|
58
55
|
results = []
|
|
59
|
-
|
|
60
|
-
for item in items:
|
|
56
|
+
for item in secici.select("div.result-item"):
|
|
61
57
|
title_el = secici.select_first("div.title a", item)
|
|
62
58
|
if not title_el:
|
|
63
59
|
continue
|
|
@@ -114,7 +110,6 @@ class Filmatek(PluginBase):
|
|
|
114
110
|
options = []
|
|
115
111
|
|
|
116
112
|
results = []
|
|
117
|
-
|
|
118
113
|
for opt in options:
|
|
119
114
|
if isinstance(opt, dict):
|
|
120
115
|
post_id = opt.get("data-post")
|
|
@@ -158,11 +153,9 @@ class Filmatek(PluginBase):
|
|
|
158
153
|
|
|
159
154
|
# Unwrap internal JWPlayer
|
|
160
155
|
if "jwplayer/?source=" in iframe_url:
|
|
161
|
-
|
|
156
|
+
with suppress(Exception):
|
|
162
157
|
raw_source = iframe_url.split("source=")[1].split("&")[0]
|
|
163
158
|
iframe_url = unquote(raw_source)
|
|
164
|
-
except:
|
|
165
|
-
pass
|
|
166
159
|
|
|
167
160
|
# Direct media files
|
|
168
161
|
if ".m3u8" in iframe_url or ".mp4" in iframe_url:
|