KekikStream 2.2.9__py3-none-any.whl → 2.5.3__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/Extractor/ExtractorBase.py +3 -2
- KekikStream/Core/Extractor/ExtractorLoader.py +8 -14
- KekikStream/Core/HTMLHelper.py +205 -0
- KekikStream/Core/Plugin/PluginBase.py +48 -12
- KekikStream/Core/Plugin/PluginLoader.py +13 -14
- KekikStream/Core/Plugin/PluginManager.py +2 -2
- KekikStream/Core/Plugin/PluginModels.py +0 -3
- KekikStream/Core/__init__.py +2 -0
- KekikStream/Extractors/Abstream.py +27 -0
- KekikStream/Extractors/CloseLoad.py +31 -56
- KekikStream/Extractors/ContentX.py +28 -71
- KekikStream/Extractors/DonilasPlay.py +34 -78
- KekikStream/Extractors/DzenRu.py +11 -25
- KekikStream/Extractors/ExPlay.py +20 -38
- KekikStream/Extractors/Filemoon.py +23 -53
- KekikStream/Extractors/HDMomPlayer.py +30 -0
- KekikStream/Extractors/HDPlayerSystem.py +13 -31
- KekikStream/Extractors/HotStream.py +27 -0
- KekikStream/Extractors/JFVid.py +3 -24
- KekikStream/Extractors/JetTv.py +21 -34
- KekikStream/Extractors/JetV.py +55 -0
- KekikStream/Extractors/MailRu.py +11 -29
- KekikStream/Extractors/MixPlayHD.py +17 -31
- KekikStream/Extractors/MixTiger.py +17 -40
- KekikStream/Extractors/MolyStream.py +25 -22
- KekikStream/Extractors/Odnoklassniki.py +41 -105
- KekikStream/Extractors/PeaceMakerst.py +20 -47
- KekikStream/Extractors/PixelDrain.py +9 -16
- KekikStream/Extractors/PlayerFilmIzle.py +23 -46
- KekikStream/Extractors/RapidVid.py +23 -36
- KekikStream/Extractors/SetPlay.py +19 -44
- KekikStream/Extractors/SetPrime.py +3 -6
- KekikStream/Extractors/SibNet.py +8 -19
- KekikStream/Extractors/Sobreatsesuyp.py +25 -47
- KekikStream/Extractors/TRsTX.py +25 -55
- KekikStream/Extractors/TurboImgz.py +8 -16
- KekikStream/Extractors/TurkeyPlayer.py +5 -5
- KekikStream/Extractors/VCTPlay.py +10 -28
- KekikStream/Extractors/Veev.py +145 -0
- KekikStream/Extractors/VidBiz.py +62 -0
- KekikStream/Extractors/VidHide.py +59 -34
- KekikStream/Extractors/VidMoly.py +67 -89
- KekikStream/Extractors/VidMoxy.py +17 -29
- KekikStream/Extractors/VidPapi.py +26 -58
- KekikStream/Extractors/VideoSeyred.py +21 -42
- KekikStream/Extractors/Videostr.py +58 -0
- KekikStream/Extractors/Vidoza.py +18 -0
- KekikStream/Extractors/Vtbe.py +38 -0
- KekikStream/Extractors/YTDLP.py +2 -2
- KekikStream/Extractors/YildizKisaFilm.py +13 -31
- KekikStream/Extractors/Zeus.py +61 -0
- KekikStream/Plugins/BelgeselX.py +108 -99
- KekikStream/Plugins/DiziBox.py +61 -106
- KekikStream/Plugins/DiziMom.py +179 -0
- KekikStream/Plugins/DiziPal.py +104 -192
- KekikStream/Plugins/DiziYou.py +66 -149
- KekikStream/Plugins/Dizilla.py +93 -126
- KekikStream/Plugins/FilmBip.py +102 -72
- KekikStream/Plugins/FilmEkseni.py +199 -0
- KekikStream/Plugins/FilmMakinesi.py +101 -64
- KekikStream/Plugins/FilmModu.py +35 -59
- KekikStream/Plugins/Filmatek.py +184 -0
- KekikStream/Plugins/FilmciBaba.py +155 -0
- KekikStream/Plugins/FullHDFilmizlesene.py +32 -78
- KekikStream/Plugins/HDFilm.py +243 -0
- KekikStream/Plugins/HDFilmCehennemi.py +261 -222
- KekikStream/Plugins/JetFilmizle.py +117 -98
- KekikStream/Plugins/KultFilmler.py +153 -143
- KekikStream/Plugins/RecTV.py +53 -49
- KekikStream/Plugins/RoketDizi.py +92 -123
- KekikStream/Plugins/SelcukFlix.py +86 -95
- KekikStream/Plugins/SetFilmIzle.py +105 -143
- KekikStream/Plugins/SezonlukDizi.py +106 -128
- KekikStream/Plugins/Sinefy.py +194 -166
- KekikStream/Plugins/SinemaCX.py +159 -113
- KekikStream/Plugins/Sinezy.py +44 -73
- KekikStream/Plugins/SuperFilmGeldi.py +28 -52
- KekikStream/Plugins/UgurFilm.py +94 -72
- KekikStream/Plugins/Watch32.py +160 -0
- KekikStream/Plugins/YabanciDizi.py +250 -0
- {kekikstream-2.2.9.dist-info → kekikstream-2.5.3.dist-info}/METADATA +1 -1
- kekikstream-2.5.3.dist-info/RECORD +99 -0
- {kekikstream-2.2.9.dist-info → kekikstream-2.5.3.dist-info}/WHEEL +1 -1
- KekikStream/Plugins/FullHDFilm.py +0 -254
- kekikstream-2.2.9.dist-info/RECORD +0 -82
- {kekikstream-2.2.9.dist-info → kekikstream-2.5.3.dist-info}/entry_points.txt +0 -0
- {kekikstream-2.2.9.dist-info → kekikstream-2.5.3.dist-info}/licenses/LICENSE +0 -0
- {kekikstream-2.2.9.dist-info → kekikstream-2.5.3.dist-info}/top_level.txt +0 -0
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
|
|
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,97 +40,77 @@ 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(
|
|
58
53
|
category = category,
|
|
59
54
|
title = title,
|
|
60
55
|
url = self.fix_url(href),
|
|
61
|
-
poster = self.fix_url(poster)
|
|
56
|
+
poster = self.fix_url(poster),
|
|
62
57
|
))
|
|
63
58
|
|
|
64
59
|
return results
|
|
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(
|
|
81
73
|
title = title,
|
|
82
74
|
url = self.fix_url(href),
|
|
83
|
-
poster = self.fix_url(poster)
|
|
75
|
+
poster = self.fix_url(poster),
|
|
84
76
|
))
|
|
85
77
|
|
|
86
78
|
return results
|
|
87
79
|
|
|
88
80
|
async def load_item(self, url: str) -> MovieInfo:
|
|
89
81
|
istek = await self.httpx.get(url)
|
|
90
|
-
secici =
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
desc_el = secici.css_first("p[itemprop='description']")
|
|
103
|
-
description = desc_el.text(strip=True) if desc_el else None
|
|
104
|
-
|
|
105
|
-
tags = [a.text(strip=True) for a in secici.css("a[href*='film-tur/']") if a.text(strip=True)]
|
|
106
|
-
|
|
107
|
-
year_el = secici.css_first("span[itemprop='dateCreated']")
|
|
108
|
-
year = year_el.text(strip=True) if year_el else None
|
|
109
|
-
|
|
110
|
-
actors = []
|
|
111
|
-
for a in secici.css("a[itemprop='actor']"):
|
|
112
|
-
span_el = a.css_first("span")
|
|
113
|
-
if span_el and span_el.text(strip=True):
|
|
114
|
-
actors.append(span_el.text(strip=True))
|
|
82
|
+
secici = HTMLHelper(istek.text)
|
|
83
|
+
|
|
84
|
+
org_title = secici.select_text("div.titles h1")
|
|
85
|
+
alt_title = secici.select_text("div.titles h2")
|
|
86
|
+
title = f"{org_title} - {alt_title}" if alt_title else (org_title)
|
|
87
|
+
poster = secici.select_poster("img.img-responsive")
|
|
88
|
+
description = secici.select_text("p[itemprop='description']")
|
|
89
|
+
tags = secici.select_texts("a[href*='film-tur/']")
|
|
90
|
+
rating = secici.meta_value("IMDB")
|
|
91
|
+
year = secici.extract_year("span[itemprop='dateCreated']")
|
|
92
|
+
actors = secici.select_texts("a[itemprop='actor'] span")
|
|
115
93
|
|
|
116
94
|
return MovieInfo(
|
|
117
95
|
url = url,
|
|
118
|
-
poster = self.fix_url(poster)
|
|
96
|
+
poster = self.fix_url(poster),
|
|
119
97
|
title = title,
|
|
120
98
|
description = description,
|
|
121
99
|
tags = tags,
|
|
100
|
+
rating = rating,
|
|
122
101
|
year = year,
|
|
123
|
-
actors = actors
|
|
102
|
+
actors = actors
|
|
124
103
|
)
|
|
125
104
|
|
|
126
105
|
async def load_links(self, url: str) -> list[ExtractResult]:
|
|
127
106
|
istek = await self.httpx.get(url)
|
|
128
|
-
secici =
|
|
107
|
+
secici = HTMLHelper(istek.text)
|
|
129
108
|
|
|
130
|
-
alternates = secici.
|
|
109
|
+
alternates = secici.select("div.alternates a")
|
|
131
110
|
if not alternates:
|
|
132
111
|
return []
|
|
133
112
|
|
|
134
113
|
results = []
|
|
135
|
-
|
|
136
114
|
for alternatif in alternates:
|
|
137
115
|
alt_link = alternatif.attrs.get("href")
|
|
138
116
|
alt_name = alternatif.text(strip=True)
|
|
@@ -140,20 +118,18 @@ class FilmModu(PluginBase):
|
|
|
140
118
|
if alt_name == "Fragman" or not alt_link:
|
|
141
119
|
continue
|
|
142
120
|
|
|
143
|
-
alt_link
|
|
121
|
+
alt_link = self.fix_url(alt_link)
|
|
144
122
|
alt_istek = await self.httpx.get(alt_link)
|
|
145
|
-
|
|
123
|
+
secici = HTMLHelper(alt_istek.text)
|
|
146
124
|
|
|
147
|
-
vid_id =
|
|
148
|
-
vid_type =
|
|
125
|
+
vid_id = secici.regex_first(r"var videoId = '([^']*)'")
|
|
126
|
+
vid_type = secici.regex_first(r"var videoType = '([^']*)'")
|
|
149
127
|
|
|
150
128
|
if not vid_id or not vid_type:
|
|
151
129
|
continue
|
|
152
130
|
|
|
153
|
-
source_istek = await self.httpx.get(
|
|
154
|
-
|
|
155
|
-
)
|
|
156
|
-
source_data = source_istek.json()
|
|
131
|
+
source_istek = await self.httpx.get(f"{self.main_url}/get-source?movie_id={vid_id}&type={vid_type}")
|
|
132
|
+
source_data = source_istek.json()
|
|
157
133
|
|
|
158
134
|
if source_data.get("subtitle"):
|
|
159
135
|
subtitle_url = self.fix_url(source_data["subtitle"])
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
|
+
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, ExtractResult, HTMLHelper
|
|
4
|
+
from urllib.parse import unquote
|
|
5
|
+
from contextlib import suppress
|
|
6
|
+
|
|
7
|
+
class Filmatek(PluginBase):
|
|
8
|
+
name = "Filmatek"
|
|
9
|
+
language = "tr"
|
|
10
|
+
main_url = "https://filmatek.net"
|
|
11
|
+
favicon = f"https://www.google.com/s2/favicons?domain={main_url}&sz=64"
|
|
12
|
+
description = "Sosyalizmin Sineması Veritabanı"
|
|
13
|
+
|
|
14
|
+
main_page = {
|
|
15
|
+
f"{main_url}/tur/aile/page" : "Aile",
|
|
16
|
+
f"{main_url}/tur/aksiyon/page" : "Aksiyon",
|
|
17
|
+
f"{main_url}/tur/animasyon/page" : "Animasyon",
|
|
18
|
+
f"{main_url}/tur/bilim-kurgu/page" : "Bilim Kurgu",
|
|
19
|
+
f"{main_url}/tur/komedi/page" : "Komedi",
|
|
20
|
+
f"{main_url}/tur/korku/page" : "Korku",
|
|
21
|
+
f"{main_url}/tur/macera/page" : "Macera",
|
|
22
|
+
f"{main_url}/tur/romantik/page" : "Romantik",
|
|
23
|
+
f"{main_url}/tur/suc/page" : "Suç",
|
|
24
|
+
f"{main_url}/tur/yerli-filmler/page" : "Yerli Filmler",
|
|
25
|
+
f"{main_url}/film-arsivi/page" : "Tüm Filmler",
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
29
|
+
istek = await self.httpx.get(f"{url}/{page}/")
|
|
30
|
+
secici = HTMLHelper(istek.text)
|
|
31
|
+
|
|
32
|
+
results = []
|
|
33
|
+
for item in secici.select("div.items article, #archive-content article"):
|
|
34
|
+
title_el = secici.select_first("div.data h3 a, h3 a", item)
|
|
35
|
+
if not title_el:
|
|
36
|
+
continue
|
|
37
|
+
|
|
38
|
+
title = title_el.text(strip=True)
|
|
39
|
+
href = self.fix_url(title_el.attrs.get("href"))
|
|
40
|
+
poster = self.fix_url(secici.select_poster("img", item))
|
|
41
|
+
|
|
42
|
+
results.append(MainPageResult(
|
|
43
|
+
category = category,
|
|
44
|
+
title = title,
|
|
45
|
+
url = href,
|
|
46
|
+
poster = poster
|
|
47
|
+
))
|
|
48
|
+
|
|
49
|
+
return results
|
|
50
|
+
|
|
51
|
+
async def search(self, query: str) -> list[SearchResult]:
|
|
52
|
+
istek = await self.httpx.get(f"{self.main_url}/?s={query}")
|
|
53
|
+
secici = HTMLHelper(istek.text)
|
|
54
|
+
|
|
55
|
+
results = []
|
|
56
|
+
for item in secici.select("div.result-item"):
|
|
57
|
+
title_el = secici.select_first("div.title a", item)
|
|
58
|
+
if not title_el:
|
|
59
|
+
continue
|
|
60
|
+
|
|
61
|
+
title = title_el.text(strip=True)
|
|
62
|
+
href = self.fix_url(title_el.attrs.get("href"))
|
|
63
|
+
poster = self.fix_url(secici.select_poster("div.image img", item))
|
|
64
|
+
|
|
65
|
+
results.append(SearchResult(
|
|
66
|
+
title = title,
|
|
67
|
+
url = href,
|
|
68
|
+
poster = poster
|
|
69
|
+
))
|
|
70
|
+
|
|
71
|
+
return results
|
|
72
|
+
|
|
73
|
+
async def load_item(self, url: str) -> MovieInfo:
|
|
74
|
+
istek = await self.httpx.get(url)
|
|
75
|
+
secici = HTMLHelper(istek.text)
|
|
76
|
+
|
|
77
|
+
title = self.clean_title(secici.select_text("div.data h1, h1"))
|
|
78
|
+
poster = secici.select_poster("div.poster img") or secici.select_attr("meta[property='og:image']", "content")
|
|
79
|
+
description = secici.select_text("div.wp-content p") or secici.select_attr("meta[property='og:description']", "content")
|
|
80
|
+
year = secici.extract_year("span.date")
|
|
81
|
+
rating = secici.select_text("span.dt_rating_vgs") or secici.select_text("span.dt_rating_vmanual")
|
|
82
|
+
duration = secici.regex_first(r"(\d+)", secici.select_text("span.runtime"))
|
|
83
|
+
tags = secici.select_texts("div.sgeneros a")
|
|
84
|
+
actors = secici.select_texts("div.person div.name a")
|
|
85
|
+
|
|
86
|
+
return MovieInfo(
|
|
87
|
+
url = url,
|
|
88
|
+
title = title,
|
|
89
|
+
description = description,
|
|
90
|
+
poster = self.fix_url(poster),
|
|
91
|
+
year = year,
|
|
92
|
+
rating = rating,
|
|
93
|
+
duration = duration,
|
|
94
|
+
tags = tags,
|
|
95
|
+
actors = actors
|
|
96
|
+
)
|
|
97
|
+
|
|
98
|
+
async def load_links(self, url: str) -> list[ExtractResult]:
|
|
99
|
+
istek = await self.httpx.get(url)
|
|
100
|
+
secici = HTMLHelper(istek.text)
|
|
101
|
+
|
|
102
|
+
# Player seçeneklerini bul
|
|
103
|
+
options = secici.select("div#playeroptions ul.ajax_mode li.dooplay_player_option")
|
|
104
|
+
if not options:
|
|
105
|
+
# Fallback: Body class'tan post_id
|
|
106
|
+
body_class = secici.select_attr("body", "class") or ""
|
|
107
|
+
if pid := secici.regex_first(r"postid-(\d+)", body_class):
|
|
108
|
+
options = [{"data-post": pid, "data-nume": "1", "data-type": "movie", "title": "Varsayılan"}]
|
|
109
|
+
else:
|
|
110
|
+
options = []
|
|
111
|
+
|
|
112
|
+
results = []
|
|
113
|
+
for opt in options:
|
|
114
|
+
if isinstance(opt, dict):
|
|
115
|
+
post_id = opt.get("data-post")
|
|
116
|
+
nume = opt.get("data-nume")
|
|
117
|
+
type_ = opt.get("data-type")
|
|
118
|
+
title = opt.get("title")
|
|
119
|
+
else:
|
|
120
|
+
post_id = opt.attrs.get("data-post")
|
|
121
|
+
nume = opt.attrs.get("data-nume")
|
|
122
|
+
type_ = opt.attrs.get("data-type")
|
|
123
|
+
title = secici.select_text("span.title", opt)
|
|
124
|
+
|
|
125
|
+
if not post_id or not nume:
|
|
126
|
+
continue
|
|
127
|
+
|
|
128
|
+
try:
|
|
129
|
+
# Need to use post with data
|
|
130
|
+
player_resp = await self.httpx.post(
|
|
131
|
+
url = f"{self.main_url}/wp-admin/admin-ajax.php",
|
|
132
|
+
headers = {
|
|
133
|
+
"X-Requested-With" : "XMLHttpRequest",
|
|
134
|
+
"Referer" : url,
|
|
135
|
+
"Content-Type" : "application/x-www-form-urlencoded"
|
|
136
|
+
},
|
|
137
|
+
data = {
|
|
138
|
+
"action" : "doo_player_ajax",
|
|
139
|
+
"post" : post_id,
|
|
140
|
+
"nume" : nume,
|
|
141
|
+
"type" : type_
|
|
142
|
+
}
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
content = player_resp.text.replace(r"\/", "/")
|
|
146
|
+
iframe_url = secici.regex_first(r'(?:src|url)["\']?\s*[:=]\s*["\']([^"\']+)["\']', content)
|
|
147
|
+
|
|
148
|
+
if iframe_url:
|
|
149
|
+
if iframe_url.startswith("/"):
|
|
150
|
+
iframe_url = self.main_url + iframe_url
|
|
151
|
+
|
|
152
|
+
iframe_url = self.fix_url(iframe_url)
|
|
153
|
+
|
|
154
|
+
# Unwrap internal JWPlayer
|
|
155
|
+
if "jwplayer/?source=" in iframe_url:
|
|
156
|
+
with suppress(Exception):
|
|
157
|
+
raw_source = iframe_url.split("source=")[1].split("&")[0]
|
|
158
|
+
iframe_url = unquote(raw_source)
|
|
159
|
+
|
|
160
|
+
# Direct media files
|
|
161
|
+
if ".m3u8" in iframe_url or ".mp4" in iframe_url:
|
|
162
|
+
results.append(ExtractResult(
|
|
163
|
+
name = f"{title} | Direct",
|
|
164
|
+
url = iframe_url,
|
|
165
|
+
referer = url
|
|
166
|
+
))
|
|
167
|
+
else:
|
|
168
|
+
extracted = await self.extract(iframe_url, prefix=title)
|
|
169
|
+
if extracted:
|
|
170
|
+
if isinstance(extracted, list):
|
|
171
|
+
results.extend(extracted)
|
|
172
|
+
else:
|
|
173
|
+
results.append(extracted)
|
|
174
|
+
else:
|
|
175
|
+
results.append(ExtractResult(
|
|
176
|
+
name = f"{title} | External",
|
|
177
|
+
url = iframe_url,
|
|
178
|
+
referer = url
|
|
179
|
+
))
|
|
180
|
+
except Exception as e:
|
|
181
|
+
# print(f"Filmatek Error: {e}")
|
|
182
|
+
pass
|
|
183
|
+
|
|
184
|
+
return results
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
|
+
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, SeriesInfo, Episode, ExtractResult, HTMLHelper
|
|
4
|
+
|
|
5
|
+
class FilmciBaba(PluginBase):
|
|
6
|
+
name = "FilmciBaba"
|
|
7
|
+
language = "tr"
|
|
8
|
+
main_url = "https://4kizle.live"
|
|
9
|
+
favicon = f"https://www.google.com/s2/favicons?domain={main_url}&sz=64"
|
|
10
|
+
description = "Filmci Baba, film izleme sitesi 4k Full film izle, 1080p ve 4k kalite de sinema filmleri ve dizileri, tek parça hd kalitede türkçe dublajlı filmler seyret."
|
|
11
|
+
|
|
12
|
+
main_page = {
|
|
13
|
+
f"{main_url}/Kategori/en-populer-filmler/page" : "En Popüler Filmler",
|
|
14
|
+
f"{main_url}/Kategori/tur/aksiyon-filmleri/page" : "Aksiyon",
|
|
15
|
+
f"{main_url}/Kategori/tur/macera-filmleri/page" : "Macera",
|
|
16
|
+
f"{main_url}/Kategori/tur/bilim-kurgu-filmleri/page" : "Bilim Kurgu",
|
|
17
|
+
f"{main_url}/Kategori/tur/fantastik-filmler/page" : "Fantastik",
|
|
18
|
+
f"{main_url}/Kategori/tur/korku-filmleri/page" : "Korku",
|
|
19
|
+
f"{main_url}/Kategori/tur/gerilim-filmleri-hd/page" : "Gerilim",
|
|
20
|
+
f"{main_url}/Kategori/tur/gizem-filmleri/page" : "Gizem",
|
|
21
|
+
f"{main_url}/Kategori/tur/dram-filmleri-hd/page" : "Dram",
|
|
22
|
+
f"{main_url}/Kategori/tur/komedi-filmleri-hd/page" : "Komedi",
|
|
23
|
+
f"{main_url}/Kategori/tur/romantik-filmler/page" : "Romantik",
|
|
24
|
+
f"{main_url}/Kategori/tur/aile-filmleri/page" : "Aile",
|
|
25
|
+
f"{main_url}/Kategori/tur/animasyon-filmleri/page" : "Animasyon",
|
|
26
|
+
f"{main_url}/Kategori/tur/biyografi-filmleri/page" : "Biyografi",
|
|
27
|
+
f"{main_url}/Kategori/tur/polisiye-suc-filmleri/page" : "Polisiye / Suç",
|
|
28
|
+
f"{main_url}/Kategori/tur/savas-filmleri/page" : "Savaş",
|
|
29
|
+
f"{main_url}/Kategori/tur/western-filmler/page" : "Western",
|
|
30
|
+
f"{main_url}/Kategori/tur/hint-filmleri/page" : "Hint Filmleri",
|
|
31
|
+
f"{main_url}/Kategori/tur/kore-filmleri/page" : "Kore Filmleri",
|
|
32
|
+
f"{main_url}/Kategori/tur/yerli-filmler-izle/page" : "Yerli Filmler",
|
|
33
|
+
f"{main_url}/Kategori/tur/yerli-diziler/page" : "Yerli Diziler",
|
|
34
|
+
f"{main_url}/Kategori/tur/18-erotik-filmler/page" : "+18 Erotik Filmler",
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
38
|
+
istek = await self.httpx.get(f"{url}/{page}/")
|
|
39
|
+
secici = HTMLHelper(istek.text)
|
|
40
|
+
|
|
41
|
+
results = []
|
|
42
|
+
for item in secici.select("div.movie-preview"):
|
|
43
|
+
title_el = secici.select_first(".movie-title a", item)
|
|
44
|
+
if not title_el:
|
|
45
|
+
continue
|
|
46
|
+
|
|
47
|
+
title = self.clean_title(title_el.text(strip=True))
|
|
48
|
+
href = self.fix_url(title_el.attrs.get("href"))
|
|
49
|
+
poster = self.fix_url(secici.select_poster(".movie-poster img", item))
|
|
50
|
+
|
|
51
|
+
results.append(MainPageResult(
|
|
52
|
+
category = category,
|
|
53
|
+
title = title,
|
|
54
|
+
url = href,
|
|
55
|
+
poster = poster
|
|
56
|
+
))
|
|
57
|
+
|
|
58
|
+
return results
|
|
59
|
+
|
|
60
|
+
async def search(self, query: str) -> list[SearchResult]:
|
|
61
|
+
istek = await self.httpx.get(f"{self.main_url}/?s={query}")
|
|
62
|
+
secici = HTMLHelper(istek.text)
|
|
63
|
+
|
|
64
|
+
results = []
|
|
65
|
+
for item in secici.select("div.movie-preview"):
|
|
66
|
+
title_el = secici.select_first(".movie-title a", item)
|
|
67
|
+
if not title_el:
|
|
68
|
+
continue
|
|
69
|
+
|
|
70
|
+
title = self.clean_title(title_el.text(strip=True))
|
|
71
|
+
href = self.fix_url(title_el.attrs.get("href"))
|
|
72
|
+
poster = self.fix_url(secici.select_poster(".movie-poster img", item))
|
|
73
|
+
|
|
74
|
+
results.append(SearchResult(
|
|
75
|
+
title = title,
|
|
76
|
+
url = href,
|
|
77
|
+
poster = poster
|
|
78
|
+
))
|
|
79
|
+
|
|
80
|
+
return results
|
|
81
|
+
|
|
82
|
+
async def load_item(self, url: str) -> MovieInfo | SeriesInfo:
|
|
83
|
+
istek = await self.httpx.get(url)
|
|
84
|
+
secici = HTMLHelper(istek.text)
|
|
85
|
+
|
|
86
|
+
title = self.clean_title(secici.select_text("h1"))
|
|
87
|
+
poster = secici.select_poster(".poster img")
|
|
88
|
+
description = secici.select_text(".excerpt p")
|
|
89
|
+
year = secici.extract_year(".release", ".movie-info")
|
|
90
|
+
rating = secici.regex_first(r"([\d\.]+)", secici.select_text(".imdb-rating"))
|
|
91
|
+
tags = secici.select_texts("div.categories a[href*='/Kategori/tur/']")
|
|
92
|
+
actors = secici.select_texts("a[href*='/oyuncular/']") or secici.select_texts(".cast-list .actor-name, .cast-list a")
|
|
93
|
+
|
|
94
|
+
# Bölüm linklerini kontrol et
|
|
95
|
+
ep_elements = secici.select(".parts-middle a, .parts-middle .part.active")
|
|
96
|
+
|
|
97
|
+
if not ep_elements:
|
|
98
|
+
return MovieInfo(
|
|
99
|
+
url = url,
|
|
100
|
+
title = title,
|
|
101
|
+
description = description,
|
|
102
|
+
poster = self.fix_url(poster),
|
|
103
|
+
year = year,
|
|
104
|
+
rating = rating if rating != "." else None,
|
|
105
|
+
tags = tags,
|
|
106
|
+
actors = actors
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
episodes = []
|
|
110
|
+
for i, el in enumerate(ep_elements):
|
|
111
|
+
name = secici.select_text(".part-name", el) or f"Bölüm {i+1}"
|
|
112
|
+
href = el.attrs.get("href") or url
|
|
113
|
+
s, e = secici.extract_season_episode(name)
|
|
114
|
+
episodes.append(Episode(season=s or 1, episode=e or (i + 1), title=name, url=self.fix_url(href)))
|
|
115
|
+
|
|
116
|
+
return SeriesInfo(
|
|
117
|
+
url = url,
|
|
118
|
+
title = title,
|
|
119
|
+
description = description,
|
|
120
|
+
poster = self.fix_url(poster),
|
|
121
|
+
year = year,
|
|
122
|
+
rating = rating,
|
|
123
|
+
tags = tags,
|
|
124
|
+
actors = actors,
|
|
125
|
+
episodes = episodes
|
|
126
|
+
)
|
|
127
|
+
|
|
128
|
+
async def load_links(self, url: str) -> list[ExtractResult]:
|
|
129
|
+
istek = await self.httpx.get(url)
|
|
130
|
+
secici = HTMLHelper(istek.text)
|
|
131
|
+
|
|
132
|
+
iframe = secici.select_attr(".center-container iframe", "src")
|
|
133
|
+
if not iframe:
|
|
134
|
+
iframe = secici.select_attr("iframe[src*='hotstream.club']", "src")
|
|
135
|
+
|
|
136
|
+
results = []
|
|
137
|
+
|
|
138
|
+
if iframe:
|
|
139
|
+
iframe = self.fix_url(iframe)
|
|
140
|
+
|
|
141
|
+
# Use general extract method
|
|
142
|
+
extracted = await self.extract(iframe)
|
|
143
|
+
if extracted:
|
|
144
|
+
if isinstance(extracted, list):
|
|
145
|
+
results.extend(extracted)
|
|
146
|
+
else:
|
|
147
|
+
results.append(extracted)
|
|
148
|
+
else:
|
|
149
|
+
results.append(ExtractResult(
|
|
150
|
+
name = "FilmciBaba | External",
|
|
151
|
+
url = iframe,
|
|
152
|
+
referer = url
|
|
153
|
+
))
|
|
154
|
+
|
|
155
|
+
return results
|