KekikStream 1.7.3__py3-none-any.whl → 1.7.6__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/Extractor/ExtractorBase.py +23 -6
- KekikStream/Core/Plugin/PluginBase.py +29 -8
- KekikStream/Extractors/CloseLoad.py +2 -2
- KekikStream/Extractors/ContentX.py +4 -4
- KekikStream/Extractors/DzenRu.py +2 -2
- KekikStream/Extractors/ExPlay.py +2 -2
- KekikStream/Extractors/FirePlayer.py +1 -1
- KekikStream/Extractors/HDPlayerSystem.py +1 -1
- KekikStream/Extractors/JetTv.py +4 -5
- KekikStream/Extractors/MailRu.py +2 -2
- KekikStream/Extractors/MixPlayHD.py +2 -2
- KekikStream/Extractors/MixTiger.py +1 -1
- KekikStream/Extractors/Odnoklassniki.py +2 -2
- KekikStream/Extractors/PeaceMakerst.py +4 -4
- KekikStream/Extractors/PixelDrain.py +1 -1
- KekikStream/Extractors/PlayerFilmIzle.py +6 -7
- KekikStream/Extractors/RapidVid.py +2 -2
- KekikStream/Extractors/SetPlay.py +2 -2
- KekikStream/Extractors/SetPrime.py +1 -1
- KekikStream/Extractors/SibNet.py +2 -2
- KekikStream/Extractors/Sobreatsesuyp.py +4 -4
- KekikStream/Extractors/TRsTX.py +4 -4
- KekikStream/Extractors/TauVideo.py +2 -2
- KekikStream/Extractors/TurboImgz.py +2 -2
- KekikStream/Extractors/TurkeyPlayer.py +5 -6
- KekikStream/Extractors/VidHide.py +6 -7
- KekikStream/Extractors/VidMoly.py +4 -4
- KekikStream/Extractors/VidMoxy.py +2 -2
- KekikStream/Extractors/VidPapi.py +2 -2
- KekikStream/Extractors/VideoSeyred.py +3 -3
- KekikStream/Extractors/YildizKisaFilm.py +1 -1
- KekikStream/Plugins/DiziBox.py +15 -15
- KekikStream/Plugins/DiziPal.py +11 -11
- KekikStream/Plugins/DiziYou.py +4 -4
- KekikStream/Plugins/Dizilla.py +5 -5
- KekikStream/Plugins/FilmBip.py +4 -4
- KekikStream/Plugins/FilmMakinesi.py +3 -3
- KekikStream/Plugins/FilmModu.py +6 -6
- KekikStream/Plugins/FullHDFilm.py +7 -7
- KekikStream/Plugins/FullHDFilmizlesene.py +3 -3
- KekikStream/Plugins/HDFilmCehennemi.py +3 -0
- KekikStream/Plugins/JetFilmizle.py +6 -6
- KekikStream/Plugins/KultFilmler.py +6 -6
- KekikStream/Plugins/RecTV.py +6 -6
- KekikStream/Plugins/RoketDizi.py +6 -3
- KekikStream/Plugins/SelcukFlix.py +4 -4
- KekikStream/Plugins/SezonlukDizi.py +8 -8
- KekikStream/Plugins/SineWix.py +4 -4
- KekikStream/Plugins/Sinefy.py +6 -6
- KekikStream/Plugins/SinemaCX.py +9 -9
- KekikStream/Plugins/Sinezy.py +4 -4
- KekikStream/Plugins/SuperFilmGeldi.py +5 -5
- KekikStream/Plugins/UgurFilm.py +6 -6
- KekikStream/__init__.py +29 -16
- KekikStream/requirements.txt +2 -2
- {kekikstream-1.7.3.dist-info → kekikstream-1.7.6.dist-info}/METADATA +3 -2
- kekikstream-1.7.6.dist-info/RECORD +85 -0
- KekikStream/Extractors/VidStack.py +0 -75
- kekikstream-1.7.3.dist-info/RECORD +0 -86
- {kekikstream-1.7.3.dist-info → kekikstream-1.7.6.dist-info}/WHEEL +0 -0
- {kekikstream-1.7.3.dist-info → kekikstream-1.7.6.dist-info}/entry_points.txt +0 -0
- {kekikstream-1.7.3.dist-info → kekikstream-1.7.6.dist-info}/licenses/LICENSE +0 -0
- {kekikstream-1.7.3.dist-info → kekikstream-1.7.6.dist-info}/top_level.txt +0 -0
|
@@ -15,7 +15,7 @@ class SelcukFlix(PluginBase):
|
|
|
15
15
|
|
|
16
16
|
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
17
17
|
full_url = f"{self.main_url}/{url}"
|
|
18
|
-
resp = await self.
|
|
18
|
+
resp = await self.httpx.get(full_url)
|
|
19
19
|
sel = Selector(resp.text)
|
|
20
20
|
|
|
21
21
|
results = []
|
|
@@ -50,7 +50,7 @@ class SelcukFlix(PluginBase):
|
|
|
50
50
|
"Referer": f"{self.main_url}/"
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
post_resp = await self.
|
|
53
|
+
post_resp = await self.httpx.post(search_url, headers=headers)
|
|
54
54
|
|
|
55
55
|
try:
|
|
56
56
|
resp_json = post_resp.json()
|
|
@@ -84,7 +84,7 @@ class SelcukFlix(PluginBase):
|
|
|
84
84
|
return []
|
|
85
85
|
|
|
86
86
|
async def load_item(self, url: str) -> SeriesInfo:
|
|
87
|
-
resp = await self.
|
|
87
|
+
resp = await self.httpx.get(url)
|
|
88
88
|
sel = Selector(resp.text)
|
|
89
89
|
|
|
90
90
|
next_data = sel.css("script#__NEXT_DATA__::text").get()
|
|
@@ -143,7 +143,7 @@ class SelcukFlix(PluginBase):
|
|
|
143
143
|
)
|
|
144
144
|
|
|
145
145
|
async def load_links(self, url: str) -> list[dict]:
|
|
146
|
-
resp = await self.
|
|
146
|
+
resp = await self.httpx.get(url)
|
|
147
147
|
sel = Selector(resp.text)
|
|
148
148
|
|
|
149
149
|
next_data = sel.css("script#__NEXT_DATA__::text").get()
|
|
@@ -23,7 +23,7 @@ class SezonlukDizi(PluginBase):
|
|
|
23
23
|
|
|
24
24
|
#@kekik_cache(ttl=60*60)
|
|
25
25
|
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
26
|
-
istek = await self.
|
|
26
|
+
istek = await self.httpx.get(f"{url}{page}")
|
|
27
27
|
secici = Selector(istek.text)
|
|
28
28
|
|
|
29
29
|
return [
|
|
@@ -38,7 +38,7 @@ class SezonlukDizi(PluginBase):
|
|
|
38
38
|
|
|
39
39
|
#@kekik_cache(ttl=60*60)
|
|
40
40
|
async def search(self, query: str) -> list[SearchResult]:
|
|
41
|
-
istek = await self.
|
|
41
|
+
istek = await self.httpx.get(f"{self.main_url}/diziler.asp?adi={query}")
|
|
42
42
|
secici = Selector(istek.text)
|
|
43
43
|
|
|
44
44
|
return [
|
|
@@ -52,7 +52,7 @@ class SezonlukDizi(PluginBase):
|
|
|
52
52
|
|
|
53
53
|
#@kekik_cache(ttl=60*60)
|
|
54
54
|
async def load_item(self, url: str) -> SeriesInfo:
|
|
55
|
-
istek = await self.
|
|
55
|
+
istek = await self.httpx.get(url)
|
|
56
56
|
secici = Selector(istek.text)
|
|
57
57
|
|
|
58
58
|
title = secici.css("div.header::text").get().strip()
|
|
@@ -63,14 +63,14 @@ class SezonlukDizi(PluginBase):
|
|
|
63
63
|
rating = secici.css("div.dizipuani a div::text").re_first(r"[\d.,]+")
|
|
64
64
|
actors = []
|
|
65
65
|
|
|
66
|
-
actors_istek = await self.
|
|
66
|
+
actors_istek = await self.httpx.get(f"{self.main_url}/oyuncular/{url.split('/')[-1]}")
|
|
67
67
|
actors_secici = Selector(actors_istek.text)
|
|
68
68
|
actors = [
|
|
69
69
|
actor.css("div.header::text").get().strip()
|
|
70
70
|
for actor in actors_secici.css("div.doubling div.ui")
|
|
71
71
|
]
|
|
72
72
|
|
|
73
|
-
episodes_istek = await self.
|
|
73
|
+
episodes_istek = await self.httpx.get(f"{self.main_url}/bolumler/{url.split('/')[-1]}")
|
|
74
74
|
episodes_secici = Selector(episodes_istek.text)
|
|
75
75
|
episodes = []
|
|
76
76
|
|
|
@@ -104,7 +104,7 @@ class SezonlukDizi(PluginBase):
|
|
|
104
104
|
|
|
105
105
|
#@kekik_cache(ttl=15*60)
|
|
106
106
|
async def load_links(self, url: str) -> list[dict]:
|
|
107
|
-
istek = await self.
|
|
107
|
+
istek = await self.httpx.get(url)
|
|
108
108
|
secici = Selector(istek.text)
|
|
109
109
|
|
|
110
110
|
bid = secici.css("div#dilsec::attr(data-id)").get()
|
|
@@ -113,7 +113,7 @@ class SezonlukDizi(PluginBase):
|
|
|
113
113
|
|
|
114
114
|
results = []
|
|
115
115
|
for dil, label in [("1", "Altyazı"), ("0", "Dublaj")]:
|
|
116
|
-
dil_istek = await self.
|
|
116
|
+
dil_istek = await self.httpx.post(
|
|
117
117
|
url = f"{self.main_url}/ajax/dataAlternatif22.asp",
|
|
118
118
|
headers = {"X-Requested-With": "XMLHttpRequest"},
|
|
119
119
|
data = {"bid": bid, "dil": dil},
|
|
@@ -126,7 +126,7 @@ class SezonlukDizi(PluginBase):
|
|
|
126
126
|
|
|
127
127
|
if dil_json.get("status") == "success":
|
|
128
128
|
for idx, veri in enumerate(dil_json.get("data", [])):
|
|
129
|
-
veri_response = await self.
|
|
129
|
+
veri_response = await self.httpx.post(
|
|
130
130
|
url = f"{self.main_url}/ajax/dataEmbed22.asp",
|
|
131
131
|
headers = {"X-Requested-With": "XMLHttpRequest"},
|
|
132
132
|
data = {"id": veri.get("id")},
|
KekikStream/Plugins/SineWix.py
CHANGED
|
@@ -37,7 +37,7 @@ class SineWix(PluginBase):
|
|
|
37
37
|
|
|
38
38
|
#@kekik_cache(ttl=60*60)
|
|
39
39
|
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
40
|
-
istek = await self.
|
|
40
|
+
istek = await self.httpx.get(f"{url}/{page}")
|
|
41
41
|
veriler = istek.json()
|
|
42
42
|
|
|
43
43
|
return [
|
|
@@ -52,7 +52,7 @@ class SineWix(PluginBase):
|
|
|
52
52
|
|
|
53
53
|
#@kekik_cache(ttl=60*60)
|
|
54
54
|
async def search(self, query: str) -> list[SearchResult]:
|
|
55
|
-
istek = await self.
|
|
55
|
+
istek = await self.httpx.get(f"{self.main_url}/sinewix/search/{query}")
|
|
56
56
|
|
|
57
57
|
return [
|
|
58
58
|
SearchResult(
|
|
@@ -68,7 +68,7 @@ class SineWix(PluginBase):
|
|
|
68
68
|
item_type = url.split("?type=")[-1].split("&id=")[0]
|
|
69
69
|
item_id = url.split("&id=")[-1]
|
|
70
70
|
|
|
71
|
-
istek = await self.
|
|
71
|
+
istek = await self.httpx.get(f"{self.main_url}/sinewix/{item_type}/{item_id}")
|
|
72
72
|
veri = istek.json()
|
|
73
73
|
|
|
74
74
|
match item_type:
|
|
@@ -143,7 +143,7 @@ class SineWix(PluginBase):
|
|
|
143
143
|
if not url.startswith(self.main_url) and not url.startswith("{"):
|
|
144
144
|
return [{"url": url, "name": "Video"}]
|
|
145
145
|
|
|
146
|
-
istek = await self.
|
|
146
|
+
istek = await self.httpx.get(url)
|
|
147
147
|
veri = istek.json()
|
|
148
148
|
|
|
149
149
|
org_title = veri.get("title")
|
KekikStream/Plugins/Sinefy.py
CHANGED
|
@@ -24,7 +24,7 @@ class Sinefy(PluginBase):
|
|
|
24
24
|
else:
|
|
25
25
|
full_url = f"{self.main_url}/{url}&page={page}"
|
|
26
26
|
|
|
27
|
-
resp = await self.
|
|
27
|
+
resp = await self.httpx.get(full_url)
|
|
28
28
|
sel = Selector(resp.text)
|
|
29
29
|
|
|
30
30
|
results = []
|
|
@@ -51,7 +51,7 @@ class Sinefy(PluginBase):
|
|
|
51
51
|
c_value = "MTc0NzI2OTAwMDU3ZTEwYmZjMDViNWFmOWIwZDViODg0MjU4MjA1ZmYxOThmZTYwMDdjMWQzMzliNzY5NzFlZmViMzRhMGVmNjgwODU3MGIyZA=="
|
|
52
52
|
|
|
53
53
|
try:
|
|
54
|
-
resp = await self.
|
|
54
|
+
resp = await self.httpx.get(self.main_url)
|
|
55
55
|
sel = Selector(resp.text)
|
|
56
56
|
cke = sel.css("input[name='cKey']::attr(value)").get()
|
|
57
57
|
cval = sel.css("input[name='cValue']::attr(value)").get()
|
|
@@ -75,7 +75,7 @@ class Sinefy(PluginBase):
|
|
|
75
75
|
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
|
|
76
76
|
}
|
|
77
77
|
|
|
78
|
-
response = await self.
|
|
78
|
+
response = await self.httpx.post(post_url, data=data, headers=headers)
|
|
79
79
|
|
|
80
80
|
try:
|
|
81
81
|
# Extract JSON data from response (might contain garbage chars at start)
|
|
@@ -114,7 +114,7 @@ class Sinefy(PluginBase):
|
|
|
114
114
|
return []
|
|
115
115
|
|
|
116
116
|
async def load_item(self, url: str) -> SeriesInfo:
|
|
117
|
-
resp = await self.
|
|
117
|
+
resp = await self.httpx.get(url)
|
|
118
118
|
sel = Selector(resp.text)
|
|
119
119
|
|
|
120
120
|
title = sel.css("h1::text").get()
|
|
@@ -149,7 +149,7 @@ class Sinefy(PluginBase):
|
|
|
149
149
|
target_url = s_url if "/bolum-" in s_url else f"{s_url}/bolum-1"
|
|
150
150
|
|
|
151
151
|
try:
|
|
152
|
-
s_resp = await self.
|
|
152
|
+
s_resp = await self.httpx.get(target_url)
|
|
153
153
|
s_sel = Selector(s_resp.text)
|
|
154
154
|
ep_links = s_sel.css("div.ui.list.celled a.item")
|
|
155
155
|
|
|
@@ -200,7 +200,7 @@ class Sinefy(PluginBase):
|
|
|
200
200
|
)
|
|
201
201
|
|
|
202
202
|
async def load_links(self, url: str) -> list[dict]:
|
|
203
|
-
resp = await self.
|
|
203
|
+
resp = await self.httpx.get(url)
|
|
204
204
|
sel = Selector(resp.text)
|
|
205
205
|
|
|
206
206
|
iframe = sel.css("iframe::attr(src)").get()
|
KekikStream/Plugins/SinemaCX.py
CHANGED
|
@@ -29,7 +29,7 @@ class SinemaCX(PluginBase):
|
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
32
|
-
istek = await self.
|
|
32
|
+
istek = await self.httpx.get(url.replace("SAYFA", str(page)))
|
|
33
33
|
secici = Selector(istek.text)
|
|
34
34
|
|
|
35
35
|
return [
|
|
@@ -44,7 +44,7 @@ class SinemaCX(PluginBase):
|
|
|
44
44
|
]
|
|
45
45
|
|
|
46
46
|
async def search(self, query: str) -> list[SearchResult]:
|
|
47
|
-
istek = await self.
|
|
47
|
+
istek = await self.httpx.get(f"{self.main_url}/?s={query}")
|
|
48
48
|
secici = Selector(istek.text)
|
|
49
49
|
|
|
50
50
|
return [
|
|
@@ -58,7 +58,7 @@ class SinemaCX(PluginBase):
|
|
|
58
58
|
]
|
|
59
59
|
|
|
60
60
|
async def load_item(self, url: str) -> MovieInfo:
|
|
61
|
-
istek = await self.
|
|
61
|
+
istek = await self.httpx.get(url)
|
|
62
62
|
secici = Selector(istek.text)
|
|
63
63
|
|
|
64
64
|
duration_match = re.search(r"Süre:.*?(\d+)\s*Dakika", istek.text)
|
|
@@ -76,7 +76,7 @@ class SinemaCX(PluginBase):
|
|
|
76
76
|
)
|
|
77
77
|
|
|
78
78
|
async def load_links(self, url: str) -> list[dict]:
|
|
79
|
-
istek = await self.
|
|
79
|
+
istek = await self.httpx.get(url)
|
|
80
80
|
secici = Selector(istek.text)
|
|
81
81
|
|
|
82
82
|
iframe_list = [iframe.css("::attr(data-vsrc)").get() for iframe in secici.css("iframe")]
|
|
@@ -90,7 +90,7 @@ class SinemaCX(PluginBase):
|
|
|
90
90
|
|
|
91
91
|
if has_only_trailer:
|
|
92
92
|
alt_url = url.rstrip("/") + "/2/"
|
|
93
|
-
alt_istek = await self.
|
|
93
|
+
alt_istek = await self.httpx.get(alt_url)
|
|
94
94
|
alt_sec = Selector(alt_istek.text)
|
|
95
95
|
iframe_list = [iframe.css("::attr(data-vsrc)").get() for iframe in alt_sec.css("iframe")]
|
|
96
96
|
iframe_list = [i for i in iframe_list if i]
|
|
@@ -105,8 +105,8 @@ class SinemaCX(PluginBase):
|
|
|
105
105
|
results = []
|
|
106
106
|
|
|
107
107
|
# Altyazı kontrolü
|
|
108
|
-
self.
|
|
109
|
-
iframe_istek = await self.
|
|
108
|
+
self.httpx.headers.update({"Referer": f"{self.main_url}/"})
|
|
109
|
+
iframe_istek = await self.httpx.get(iframe)
|
|
110
110
|
iframe_text = iframe_istek.text
|
|
111
111
|
|
|
112
112
|
subtitles = []
|
|
@@ -123,8 +123,8 @@ class SinemaCX(PluginBase):
|
|
|
123
123
|
base_url = base_match[1]
|
|
124
124
|
vid_id = iframe.split("/")[-1]
|
|
125
125
|
|
|
126
|
-
self.
|
|
127
|
-
vid_istek = await self.
|
|
126
|
+
self.httpx.headers.update({"X-Requested-With": "XMLHttpRequest"})
|
|
127
|
+
vid_istek = await self.httpx.post(
|
|
128
128
|
f"https://{base_url}/player/index.php?data={vid_id}&do=getVideo",
|
|
129
129
|
)
|
|
130
130
|
vid_data = vid_istek.json()
|
KekikStream/Plugins/Sinezy.py
CHANGED
|
@@ -16,7 +16,7 @@ class Sinezy(PluginBase):
|
|
|
16
16
|
|
|
17
17
|
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
18
18
|
full_url = f"{self.main_url}/{url}page/{page}/"
|
|
19
|
-
resp = await self.
|
|
19
|
+
resp = await self.httpx.get(full_url)
|
|
20
20
|
sel = Selector(resp.text)
|
|
21
21
|
|
|
22
22
|
results = []
|
|
@@ -36,7 +36,7 @@ class Sinezy(PluginBase):
|
|
|
36
36
|
|
|
37
37
|
async def search(self, query: str) -> list[SearchResult]:
|
|
38
38
|
url = f"{self.main_url}/arama/?s={query}"
|
|
39
|
-
resp = await self.
|
|
39
|
+
resp = await self.httpx.get(url)
|
|
40
40
|
sel = Selector(resp.text)
|
|
41
41
|
|
|
42
42
|
results = []
|
|
@@ -54,7 +54,7 @@ class Sinezy(PluginBase):
|
|
|
54
54
|
return results
|
|
55
55
|
|
|
56
56
|
async def load_item(self, url: str) -> MovieInfo:
|
|
57
|
-
resp = await self.
|
|
57
|
+
resp = await self.httpx.get(url)
|
|
58
58
|
sel = Selector(resp.text)
|
|
59
59
|
|
|
60
60
|
title = sel.css("div.detail::attr(title)").get()
|
|
@@ -76,7 +76,7 @@ class Sinezy(PluginBase):
|
|
|
76
76
|
)
|
|
77
77
|
|
|
78
78
|
async def load_links(self, url: str) -> list[dict]:
|
|
79
|
-
resp = await self.
|
|
79
|
+
resp = await self.httpx.get(url)
|
|
80
80
|
|
|
81
81
|
match = re.search(r"ilkpartkod\s*=\s*'([^']+)'", resp.text, re.IGNORECASE)
|
|
82
82
|
if match:
|
|
@@ -26,7 +26,7 @@ class SuperFilmGeldi(PluginBase):
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
29
|
-
istek = await self.
|
|
29
|
+
istek = await self.httpx.get(url.replace("SAYFA", str(page)))
|
|
30
30
|
secici = Selector(istek.text)
|
|
31
31
|
|
|
32
32
|
return [
|
|
@@ -41,7 +41,7 @@ class SuperFilmGeldi(PluginBase):
|
|
|
41
41
|
]
|
|
42
42
|
|
|
43
43
|
async def search(self, query: str) -> list[SearchResult]:
|
|
44
|
-
istek = await self.
|
|
44
|
+
istek = await self.httpx.get(f"{self.main_url}?s={query}")
|
|
45
45
|
secici = Selector(istek.text)
|
|
46
46
|
|
|
47
47
|
return [
|
|
@@ -55,7 +55,7 @@ class SuperFilmGeldi(PluginBase):
|
|
|
55
55
|
]
|
|
56
56
|
|
|
57
57
|
async def load_item(self, url: str) -> MovieInfo:
|
|
58
|
-
istek = await self.
|
|
58
|
+
istek = await self.httpx.get(url)
|
|
59
59
|
secici = Selector(istek.text)
|
|
60
60
|
|
|
61
61
|
title = secici.css("div.title h1::text").get()
|
|
@@ -77,7 +77,7 @@ class SuperFilmGeldi(PluginBase):
|
|
|
77
77
|
)
|
|
78
78
|
|
|
79
79
|
async def load_links(self, url: str) -> list[dict]:
|
|
80
|
-
istek = await self.
|
|
80
|
+
istek = await self.httpx.get(url)
|
|
81
81
|
secici = Selector(istek.text)
|
|
82
82
|
|
|
83
83
|
iframe = self.fix_url(secici.css("div#vast iframe::attr(src)").get())
|
|
@@ -88,7 +88,7 @@ class SuperFilmGeldi(PluginBase):
|
|
|
88
88
|
|
|
89
89
|
# Mix player özel işleme
|
|
90
90
|
if "mix" in iframe and "index.php?data=" in iframe:
|
|
91
|
-
iframe_istek = await self.
|
|
91
|
+
iframe_istek = await self.httpx.get(iframe, headers={"Referer": f"{self.main_url}/"})
|
|
92
92
|
mix_point = re.search(r'videoUrl":"(.*)","videoServer', iframe_istek.text)
|
|
93
93
|
|
|
94
94
|
if mix_point:
|
KekikStream/Plugins/UgurFilm.py
CHANGED
|
@@ -25,7 +25,7 @@ class UgurFilm(PluginBase):
|
|
|
25
25
|
|
|
26
26
|
#@kekik_cache(ttl=60*60)
|
|
27
27
|
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
28
|
-
istek = await self.
|
|
28
|
+
istek = await self.httpx.get(f"{url}{page}", allow_redirects=True)
|
|
29
29
|
secici = Selector(istek.text)
|
|
30
30
|
|
|
31
31
|
return [
|
|
@@ -40,7 +40,7 @@ class UgurFilm(PluginBase):
|
|
|
40
40
|
|
|
41
41
|
#@kekik_cache(ttl=60*60)
|
|
42
42
|
async def search(self, query: str) -> list[SearchResult]:
|
|
43
|
-
istek = await self.
|
|
43
|
+
istek = await self.httpx.get(f"{self.main_url}/?s={query}")
|
|
44
44
|
secici = Selector(istek.text)
|
|
45
45
|
|
|
46
46
|
results = []
|
|
@@ -62,7 +62,7 @@ class UgurFilm(PluginBase):
|
|
|
62
62
|
|
|
63
63
|
#@kekik_cache(ttl=60*60)
|
|
64
64
|
async def load_item(self, url: str) -> MovieInfo:
|
|
65
|
-
istek = await self.
|
|
65
|
+
istek = await self.httpx.get(url)
|
|
66
66
|
secici = Selector(istek.text)
|
|
67
67
|
|
|
68
68
|
title = secici.css("div.bilgi h2::text").get().strip()
|
|
@@ -84,12 +84,12 @@ class UgurFilm(PluginBase):
|
|
|
84
84
|
|
|
85
85
|
#@kekik_cache(ttl=15*60)
|
|
86
86
|
async def load_links(self, url: str) -> list[dict]:
|
|
87
|
-
istek = await self.
|
|
87
|
+
istek = await self.httpx.get(url)
|
|
88
88
|
secici = Selector(istek.text)
|
|
89
89
|
results = []
|
|
90
90
|
|
|
91
91
|
for idx, part_link in enumerate(secici.css("li.parttab a::attr(href)").getall()):
|
|
92
|
-
sub_response = await self.
|
|
92
|
+
sub_response = await self.httpx.get(part_link)
|
|
93
93
|
sub_selector = Selector(sub_response.text)
|
|
94
94
|
|
|
95
95
|
iframe = sub_selector.css("div#vast iframe::attr(src)").get()
|
|
@@ -99,7 +99,7 @@ class UgurFilm(PluginBase):
|
|
|
99
99
|
"alternative" : "vidmoly",
|
|
100
100
|
"ord" : "0",
|
|
101
101
|
}
|
|
102
|
-
player_response = await self.
|
|
102
|
+
player_response = await self.httpx.post(
|
|
103
103
|
url = f"{self.main_url}/player/ajax_sources.php",
|
|
104
104
|
data = post_data
|
|
105
105
|
)
|
KekikStream/__init__.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from .CLI import konsol, cikis_yap, hata_yakala, pypi_kontrol_guncelle
|
|
4
4
|
from .Core import PluginManager, ExtractorManager, UIManager, MediaManager, PluginBase, ExtractorBase, SeriesInfo
|
|
5
|
-
from asyncio import run
|
|
5
|
+
from asyncio import run, TaskGroup, Semaphore
|
|
6
6
|
from contextlib import suppress
|
|
7
7
|
|
|
8
8
|
class KekikStream:
|
|
@@ -90,21 +90,34 @@ class KekikStream:
|
|
|
90
90
|
|
|
91
91
|
query = await self.ui.prompt_text("Arama sorgusu:")
|
|
92
92
|
all_results = []
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
93
|
+
|
|
94
|
+
# Maksimum 5 eşzamanlı arama için semaphore
|
|
95
|
+
semaphore = Semaphore(5)
|
|
96
|
+
|
|
97
|
+
async def search_plugin(name: str, plugin: PluginBase):
|
|
98
|
+
"""Tek bir plugin'de ara (semaphore ile sınırlandırılmış)"""
|
|
99
|
+
async with semaphore:
|
|
100
|
+
konsol.log(f"[yellow][~] {name:<19} aranıyor...[/]")
|
|
101
|
+
try:
|
|
102
|
+
results = await plugin.search(query)
|
|
103
|
+
if results:
|
|
104
|
+
return [
|
|
105
|
+
{"plugin": name, "title": r.title, "url": r.url, "poster": r.poster}
|
|
106
|
+
for r in results
|
|
107
|
+
]
|
|
108
|
+
except Exception as e:
|
|
109
|
+
konsol.print(f"[bold red]{name} hatası: {e}[/bold red]")
|
|
110
|
+
return []
|
|
111
|
+
|
|
112
|
+
# Tüm plugin'leri paralel olarak ara
|
|
113
|
+
async with TaskGroup() as tg:
|
|
114
|
+
tasks = []
|
|
115
|
+
for name, plugin in self.plugin.plugins.items():
|
|
116
|
+
tasks.append(tg.create_task(search_plugin(name, plugin)))
|
|
117
|
+
|
|
118
|
+
# Sonuçları topla
|
|
119
|
+
for task in tasks:
|
|
120
|
+
all_results.extend(task.result())
|
|
108
121
|
|
|
109
122
|
if not all_results:
|
|
110
123
|
return await self.handle_no_results()
|
KekikStream/requirements.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: KekikStream
|
|
3
|
-
Version: 1.7.
|
|
3
|
+
Version: 1.7.6
|
|
4
4
|
Summary: terminal üzerinden medya içeriği aramanızı ve VLC/MPV gibi popüler medya oynatıcılar aracılığıyla doğrudan izlemenizi sağlayan modüler ve genişletilebilir bir bıdı bıdı
|
|
5
5
|
Home-page: https://github.com/keyiflerolsun/KekikStream
|
|
6
6
|
Author: keyiflerolsun
|
|
@@ -10,12 +10,13 @@ Keywords: KekikStream,KekikAkademi,keyiflerolsun
|
|
|
10
10
|
Classifier: Development Status :: 5 - Production/Stable
|
|
11
11
|
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
|
|
12
12
|
Classifier: Programming Language :: Python :: 3
|
|
13
|
-
Requires-Python: >=3.
|
|
13
|
+
Requires-Python: >=3.11
|
|
14
14
|
Description-Content-Type: text/markdown
|
|
15
15
|
License-File: LICENSE
|
|
16
16
|
Requires-Dist: setuptools
|
|
17
17
|
Requires-Dist: wheel
|
|
18
18
|
Requires-Dist: Kekik
|
|
19
|
+
Requires-Dist: httpx
|
|
19
20
|
Requires-Dist: curl-cffi
|
|
20
21
|
Requires-Dist: cloudscraper
|
|
21
22
|
Requires-Dist: parsel
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
KekikStream/__init__.py,sha256=Qgb2Dq_10q_z1lSNcrU_M6e-iKwEwjvA_A6AGVgYDS4,13600
|
|
2
|
+
KekikStream/__main__.py,sha256=B81dQoeGEb-T5Sycs3eNAmW7unvx0Mef0syCjs4nPds,137
|
|
3
|
+
KekikStream/requirements.txt,sha256=ENISGfW7D7abbqEh-1Yp2BaQdFJyYIJ0p8zNTUscuwU,80
|
|
4
|
+
KekikStream/CLI/__init__.py,sha256=U6oLq_O7u5y2eHhBnmfhZNns_EqHHJXJmzl8jvZFUNY,230
|
|
5
|
+
KekikStream/CLI/pypi_kontrol.py,sha256=q6fNs6EKJDc5VuUFig9DBzLzNPp_kMD1vOVgLElcii8,1487
|
|
6
|
+
KekikStream/Core/__init__.py,sha256=ar2MZQF83ryfLfydEXcfjdwNe4Too_HT6bP-D_4TopA,710
|
|
7
|
+
KekikStream/Core/Extractor/ExtractorBase.py,sha256=0GO8u5YzsboYMLk6kmSJmzqLZAbX_HQq6so8-2lBuqQ,2177
|
|
8
|
+
KekikStream/Core/Extractor/ExtractorLoader.py,sha256=7uxUXTAuF65KKkmbI6iRiCiUhx-IqrronB7ixhchcTU,4289
|
|
9
|
+
KekikStream/Core/Extractor/ExtractorManager.py,sha256=4L1H3jiTnf0kTq4W6uS7n95bBYHlKJ8_hh0og8z4erQ,1244
|
|
10
|
+
KekikStream/Core/Extractor/ExtractorModels.py,sha256=vLxG99_cbWwTc-dbk8XzjCasvR0QkoKSX2R0FAY9gks,456
|
|
11
|
+
KekikStream/Core/Media/MediaHandler.py,sha256=OWYNhQfT9bcCs1qo4qGz0VXxMWCoi7CA4ZqfAUHUgFw,7084
|
|
12
|
+
KekikStream/Core/Media/MediaManager.py,sha256=9ItiUguOkk3wg3YY5uf3mrjfwLPCvggnP8QviX0uiuE,526
|
|
13
|
+
KekikStream/Core/Plugin/PluginBase.py,sha256=hlvErfJd_11wuhpIzI0Bfa0y3R4g5xM4VakSQJ-54mY,4425
|
|
14
|
+
KekikStream/Core/Plugin/PluginLoader.py,sha256=yZxMug-OcJ5RBm4fQkoquKrZxcBU7Pvt4IcY-d0WU8g,3393
|
|
15
|
+
KekikStream/Core/Plugin/PluginManager.py,sha256=CZVg1eegi8vfMfccx0DRV0Box8kXz-aoULTQLgbPbvM,893
|
|
16
|
+
KekikStream/Core/Plugin/PluginModels.py,sha256=Aty3V4B3nPStVVSjYO9EIBmbUhavChQwQjC3l5TsrQI,2583
|
|
17
|
+
KekikStream/Core/UI/UIManager.py,sha256=T4V_kdTTWa-UDamgLSKa__dWJuzcvRK9NuwBlzU9Bzc,1693
|
|
18
|
+
KekikStream/Extractors/CloseLoad.py,sha256=cas2l0vk3S8yt15xAoin_iz1dQhBvFPg4k6U_b8SF9w,911
|
|
19
|
+
KekikStream/Extractors/ContentX.py,sha256=HfQ3g5KlL7LxB-7lxE70kIwg17NvfEk6wEUtzo-7-nM,3044
|
|
20
|
+
KekikStream/Extractors/DzenRu.py,sha256=6QOXBdU5GoWvzDlfdrMk0vLXjzxYBOqYAKrgs70rPa8,1213
|
|
21
|
+
KekikStream/Extractors/ExPlay.py,sha256=yHXdE0lr6i_Dhv8TmuC5gBItU01T19mbTqglkWoG8Y0,1855
|
|
22
|
+
KekikStream/Extractors/FirePlayer.py,sha256=axp8TIrkvI224yhLphwf1AdtOH4eVcD8ZcRzMmds-hI,2163
|
|
23
|
+
KekikStream/Extractors/FourCX.py,sha256=4FrMj1IZBBpN_g1P6S3A-8eUu7QFwlt4fJXzJ7vfe0Q,221
|
|
24
|
+
KekikStream/Extractors/FourPichive.py,sha256=iq3BCUbih1UVF4y4BIWO--0hX5jP2nxqesNx3MGP3kQ,234
|
|
25
|
+
KekikStream/Extractors/FourPlayRu.py,sha256=wq1ylxKpsO_IBoYr_ALzB2dVrQpJ-jY9lf2zPhcAZX8,228
|
|
26
|
+
KekikStream/Extractors/HDPlayerSystem.py,sha256=Q7IYAfy1UMamy3aLWZA31-IjI4mQsKYpb3fiOiAM_GA,1340
|
|
27
|
+
KekikStream/Extractors/HDStreamAble.py,sha256=66n5EvIdX_or5cdnlJ_Uqmzi50n4rl9c5VCw8kBqhQk,245
|
|
28
|
+
KekikStream/Extractors/Hotlinger.py,sha256=NFMRgUmb6BCrJfa7Hi0VarDNYvCeVknBWEk24FKBBa0,224
|
|
29
|
+
KekikStream/Extractors/JetTv.py,sha256=kFw-_rgVxSuDGtOeYYvg0fa0P0kMcGLhexiD8y4BW5U,1625
|
|
30
|
+
KekikStream/Extractors/MailRu.py,sha256=9TfjtgqkbcRAvoWfSwDJK3zvtq1z5-_JCdPDdZj5UDI,1279
|
|
31
|
+
KekikStream/Extractors/MixPlayHD.py,sha256=810efcVXQ1OniIz7gGtrsjNpqFy5Z6HScxDsJNsubHA,1584
|
|
32
|
+
KekikStream/Extractors/MixTiger.py,sha256=nf5wq3Y_h2trE8bLbUWEza3BTgFK-Pfsb0OdQyar1VM,2238
|
|
33
|
+
KekikStream/Extractors/MolyStream.py,sha256=y1kB2Fuf0kEchl6mxcyFdaRWOKwt6zSwYy3ojPC135M,1171
|
|
34
|
+
KekikStream/Extractors/Odnoklassniki.py,sha256=YG_e3SbIUCwEkWXJHD1zihvbQiRByJEUPxBhI5e8hTs,3779
|
|
35
|
+
KekikStream/Extractors/OkRuHTTP.py,sha256=L-B0i_i_Vnm61GvUfd6cGIW-o_H4M-C7DO_cdw2rQPU,228
|
|
36
|
+
KekikStream/Extractors/OkRuSSL.py,sha256=FHJ5XZ1dO5ED3mIku3e3vnq8K0slrcr0jqhaUnHmfVk,227
|
|
37
|
+
KekikStream/Extractors/PeaceMakerst.py,sha256=NYrVJrh32iu1T5Lnv1cjpUdzFcPgxfgSt7JM4ZoejnE,2124
|
|
38
|
+
KekikStream/Extractors/Pichive.py,sha256=BSVYFwL3Ax6yGoS1WkpOWtngxNyuZLoKzpPwjibpu2s,221
|
|
39
|
+
KekikStream/Extractors/PixelDrain.py,sha256=ZpeNFnMTEgMggqdSeInJN7wkJ-7rEXZ6TfhVylQfkDM,992
|
|
40
|
+
KekikStream/Extractors/PlayRu.py,sha256=DQMZyCSJwLkrh-gfDD8T1DvUFNBAKUXpByeCAWuK6YY,215
|
|
41
|
+
KekikStream/Extractors/PlayerFilmIzle.py,sha256=eg3Yv7GDTHZxHyCNY8lpeZIqMHAbD-bLpzRifrvfGHI,2405
|
|
42
|
+
KekikStream/Extractors/RapidVid.py,sha256=reS-05xizyDP0HGYWlyVumvxtnBgpSDH95t5-Ii5R7M,2945
|
|
43
|
+
KekikStream/Extractors/SetPlay.py,sha256=lOk9v8YJAcFs6mL46RCxY2wJg1tXqgwlfpM6X_bEJEA,1934
|
|
44
|
+
KekikStream/Extractors/SetPrime.py,sha256=nLlPRUthnD6H4tLo4uONBXsGDZHEKpg8KTWAXDsTiq8,1564
|
|
45
|
+
KekikStream/Extractors/SibNet.py,sha256=j6hFTzUA0lJyruAq7rQuV9L7GJZMHfazzCmaLUU2uRE,877
|
|
46
|
+
KekikStream/Extractors/Sobreatsesuyp.py,sha256=JY3TjuKi95fNenKXustqmYa_9jFoW8Vo6OOMQfFhXEw,2036
|
|
47
|
+
KekikStream/Extractors/TRsTX.py,sha256=ui7EPM9S9z2nhNsy1S7KORSOsgaCpqP0tuGl1xN5f9E,2188
|
|
48
|
+
KekikStream/Extractors/TauVideo.py,sha256=9qF9N1a7bYkCAjMbUpso1JPw0m28Gq_gNSchpwgyUcU,1148
|
|
49
|
+
KekikStream/Extractors/TurboImgz.py,sha256=KYAtCQ33egsR1x6t08UFyF9ps6loCrRV5WZBFR5U-YA,856
|
|
50
|
+
KekikStream/Extractors/TurkeyPlayer.py,sha256=6gQ6Ht7gLd9_vBY81NqqsYbDIsEh5XQpGF19KWrqKH4,1226
|
|
51
|
+
KekikStream/Extractors/VidHide.py,sha256=3LHmRRurplnmlxKf5bnK2fgYQCQR2W9rB6-IcVubyvk,2517
|
|
52
|
+
KekikStream/Extractors/VidMoly.py,sha256=Rd_DIa1KUyBYpDFUfsCvtjwYCZ6ANjFkqxVOqH1Tq1E,3682
|
|
53
|
+
KekikStream/Extractors/VidMolyMe.py,sha256=ogLiFUJVqFbhtzQrZ1gSB9me85DiHvntjWtSvidYVS8,218
|
|
54
|
+
KekikStream/Extractors/VidMoxy.py,sha256=vwyw2MgC9EIdF4PYB_5O7gkUxF5JTkfbmlVudZewvNs,1799
|
|
55
|
+
KekikStream/Extractors/VidPapi.py,sha256=Y9wBhZi-uH5VlYJaREByjheAGuVKQ7gXqNkQ_dlwlVM,3287
|
|
56
|
+
KekikStream/Extractors/VideoSeyred.py,sha256=HHzS8Ew1yJgWmyzi64dJkPD5bGP6Ku00EoSdZ7ncgaA,2009
|
|
57
|
+
KekikStream/Extractors/YildizKisaFilm.py,sha256=TZp9y3TQBKs_6MLxrrnXV1RbqLuCxHXbEId63tiBPcg,1344
|
|
58
|
+
KekikStream/Plugins/DiziBox.py,sha256=P9DwqsI3XqNJtTymZWL2TPOZmprxP1BRAIc0lJFeLmw,10091
|
|
59
|
+
KekikStream/Plugins/DiziPal.py,sha256=u9hAB7y3mo7MtP_wOth-wUA_xov4d8ktYu6DpR4NLHI,10194
|
|
60
|
+
KekikStream/Plugins/DiziYou.py,sha256=f1rxPM_9Mut2Cws3-sKesq5Gn9p0gZL7zvbrGrawqhk,8004
|
|
61
|
+
KekikStream/Plugins/Dizilla.py,sha256=aaORb3ZfNZm5gXB940d3Q9FgRjuNiVtQoY64W0hYbOA,7450
|
|
62
|
+
KekikStream/Plugins/FilmBip.py,sha256=wBp8jmjYuxv5nnI76skD2R_oSuS7CWhGTyQpM1YujHg,6054
|
|
63
|
+
KekikStream/Plugins/FilmMakinesi.py,sha256=CdV4k44dw0Q4rO3x4GobSDT1KGrkgit0OfTPxZfmfJ8,5314
|
|
64
|
+
KekikStream/Plugins/FilmModu.py,sha256=11c6dSMMfu6SQsIbRLD9n84KxN2MnbZ00nH0Tnc2aGk,6792
|
|
65
|
+
KekikStream/Plugins/FullHDFilm.py,sha256=kkb-JtWf23uiEzP9f_uds0tROYiKOyxcX0D-jNtQFi0,7005
|
|
66
|
+
KekikStream/Plugins/FullHDFilmizlesene.py,sha256=UYOMLJqbH72gkXWizNV3gWLZHATWeC6h8YaqThgGduI,6281
|
|
67
|
+
KekikStream/Plugins/HDFilmCehennemi.py,sha256=w49XXVNyU9hyA5vU0pIkJbB4OzHaa15p8STtnkVa1Uc,9913
|
|
68
|
+
KekikStream/Plugins/JetFilmizle.py,sha256=7EpWvl2mUCRq8x72ZMluUSurAq9pJjWtVQNCtKXyG_Y,6091
|
|
69
|
+
KekikStream/Plugins/KultFilmler.py,sha256=VZET3RUoOVYKE-C2YbkMW8oNcxz6zE2pR7a3z-B4nD4,8987
|
|
70
|
+
KekikStream/Plugins/RecTV.py,sha256=000u2dwMVd9HgqFn1m74y97Yod6gOwVR2zEiIkJvno8,7713
|
|
71
|
+
KekikStream/Plugins/RoketDizi.py,sha256=lmdGNkv8QdmOsYcC3BQbviXHL94qVzz5onGNOXF8c9w,7813
|
|
72
|
+
KekikStream/Plugins/SelcukFlix.py,sha256=F3Rv2TRpfM-SZUAqjTPsQChS_Ejoh5q1Mo5fBFlsLy0,9013
|
|
73
|
+
KekikStream/Plugins/SezonlukDizi.py,sha256=IomeNsVlji1TCimv8JwdMquKLcxZwwJQOZYzJ5v0OdE,6455
|
|
74
|
+
KekikStream/Plugins/SineWix.py,sha256=NbILBaYMj-Mxei4xOg3Si0l7L44qb5aAA-M6L_KIZ_w,7579
|
|
75
|
+
KekikStream/Plugins/Sinefy.py,sha256=mRwtQYiH7I_1k4EZS0g4MhnRDEx0NXwY8sa5tI33dog,8368
|
|
76
|
+
KekikStream/Plugins/SinemaCX.py,sha256=-vCHGhycKOoynnfkhTQwmMrBl_c7IsTO43UuIQwf3Mk,7263
|
|
77
|
+
KekikStream/Plugins/Sinezy.py,sha256=t7InHEtKdIVyBQj8HJWwWcHhRP9AXKKXYE0O3YD8MYg,3647
|
|
78
|
+
KekikStream/Plugins/SuperFilmGeldi.py,sha256=Ohm21BPsJH_S1tx5i2APEgAOD25k2NiwRP7rSgAKvRs,5289
|
|
79
|
+
KekikStream/Plugins/UgurFilm.py,sha256=DSzQD9wQMFiUKn82VNJ2KTpRhwx3X8K9Aj-zBCbpZVc,4960
|
|
80
|
+
kekikstream-1.7.6.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
81
|
+
kekikstream-1.7.6.dist-info/METADATA,sha256=1ydcxLOOiPby9eMkv5BH0wARJjCiLkeXxcyYsN4F-1E,4983
|
|
82
|
+
kekikstream-1.7.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
83
|
+
kekikstream-1.7.6.dist-info/entry_points.txt,sha256=dFwdiTx8djyehI0Gsz-rZwjAfZzUzoBSrmzRu9ubjJc,50
|
|
84
|
+
kekikstream-1.7.6.dist-info/top_level.txt,sha256=DNmGJDXl27Drdfobrak8KYLmocW_uznVYFJOzcjUgmY,12
|
|
85
|
+
kekikstream-1.7.6.dist-info/RECORD,,
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
|
-
|
|
3
|
-
from KekikStream.Core import ExtractorBase, ExtractResult, Subtitle
|
|
4
|
-
from Crypto.Cipher import AES
|
|
5
|
-
from urllib.parse import urlparse
|
|
6
|
-
import re, binascii
|
|
7
|
-
|
|
8
|
-
class VidStack(ExtractorBase):
|
|
9
|
-
name = "VidStack"
|
|
10
|
-
main_url = "https://vidstack.io"
|
|
11
|
-
requires_referer = True
|
|
12
|
-
|
|
13
|
-
def get_base_url(self, url: str) -> str:
|
|
14
|
-
try:
|
|
15
|
-
parsed = urlparse(url)
|
|
16
|
-
return f"{parsed.scheme}://{parsed.netloc}"
|
|
17
|
-
except Exception:
|
|
18
|
-
return self.main_url
|
|
19
|
-
|
|
20
|
-
def decrypt_aes(self, encrypted_hex: str, key: str, iv: str) -> str:
|
|
21
|
-
try:
|
|
22
|
-
key_bytes = key.encode('utf-8')
|
|
23
|
-
iv_bytes = iv.encode('utf-8')
|
|
24
|
-
cipher = AES.new(key_bytes, AES.MODE_CBC, iv_bytes)
|
|
25
|
-
|
|
26
|
-
encrypted_bytes = binascii.unhexlify(encrypted_hex)
|
|
27
|
-
decrypted_bytes = cipher.decrypt(encrypted_bytes)
|
|
28
|
-
|
|
29
|
-
# Remove PKCS5 padding
|
|
30
|
-
padding_len = decrypted_bytes[-1]
|
|
31
|
-
return decrypted_bytes[:-padding_len].decode('utf-8')
|
|
32
|
-
except Exception:
|
|
33
|
-
return None
|
|
34
|
-
|
|
35
|
-
async def extract(self, url: str, referer: str = None) -> ExtractResult:
|
|
36
|
-
self.cffi.headers.update({
|
|
37
|
-
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:134.0) Gecko/20100101 Firefox/134.0"
|
|
38
|
-
})
|
|
39
|
-
|
|
40
|
-
if referer:
|
|
41
|
-
self.cffi.headers.update({"Referer": referer})
|
|
42
|
-
|
|
43
|
-
video_hash = url.split("#")[-1].split("/")[-1]
|
|
44
|
-
base_url = self.get_base_url(url)
|
|
45
|
-
|
|
46
|
-
api_url = f"{base_url}/api/v1/video?id={video_hash}"
|
|
47
|
-
istek = await self.cffi.get(api_url)
|
|
48
|
-
encoded = istek.text.strip()
|
|
49
|
-
|
|
50
|
-
key = "kiemtienmua911ca"
|
|
51
|
-
iv_list = ["1234567890oiuytr", "0123456789abcdef"]
|
|
52
|
-
|
|
53
|
-
decrypted_text = None
|
|
54
|
-
for iv in iv_list:
|
|
55
|
-
if result := self.decrypt_aes(encoded, key, iv):
|
|
56
|
-
decrypted_text = result
|
|
57
|
-
break
|
|
58
|
-
|
|
59
|
-
if not decrypted_text:
|
|
60
|
-
raise ValueError(f"VidStack: Şifre çözülemedi. {url}")
|
|
61
|
-
|
|
62
|
-
m3u8_url = ""
|
|
63
|
-
if match := re.search(r'"source":"(.*?)"', decrypted_text):
|
|
64
|
-
m3u8_url = match.group(1).replace("\\/", "/")
|
|
65
|
-
|
|
66
|
-
if not m3u8_url:
|
|
67
|
-
raise ValueError(f"VidStack: Source bulunamadı. {url}")
|
|
68
|
-
|
|
69
|
-
return ExtractResult(
|
|
70
|
-
name = self.name,
|
|
71
|
-
url = m3u8_url,
|
|
72
|
-
referer = url,
|
|
73
|
-
headers = {},
|
|
74
|
-
subtitles = []
|
|
75
|
-
)
|