KekikStream 1.7.2__py3-none-any.whl → 1.7.5__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 +39 -0
- KekikStream/Extractors/ExPlay.py +54 -0
- KekikStream/Extractors/FirePlayer.py +61 -0
- KekikStream/Extractors/HDPlayerSystem.py +42 -0
- KekikStream/Extractors/JetTv.py +46 -0
- KekikStream/Extractors/MailRu.py +2 -2
- KekikStream/Extractors/MixPlayHD.py +2 -2
- KekikStream/Extractors/MixTiger.py +61 -0
- KekikStream/Extractors/Odnoklassniki.py +2 -2
- KekikStream/Extractors/PeaceMakerst.py +4 -4
- KekikStream/Extractors/PixelDrain.py +1 -1
- KekikStream/Extractors/PlayerFilmIzle.py +62 -0
- KekikStream/Extractors/RapidVid.py +2 -2
- KekikStream/Extractors/SetPlay.py +58 -0
- KekikStream/Extractors/SetPrime.py +46 -0
- 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 +34 -0
- KekikStream/Extractors/VidHide.py +72 -0
- KekikStream/Extractors/VidMoly.py +4 -4
- KekikStream/Extractors/VidMoxy.py +2 -2
- KekikStream/Extractors/VidPapi.py +90 -0
- KekikStream/Extractors/VideoSeyred.py +3 -3
- KekikStream/Extractors/YildizKisaFilm.py +42 -0
- KekikStream/Plugins/DiziBox.py +15 -15
- KekikStream/Plugins/DiziPal.py +11 -11
- KekikStream/Plugins/DiziYou.py +4 -4
- KekikStream/Plugins/Dizilla.py +10 -6
- KekikStream/Plugins/FilmBip.py +145 -0
- KekikStream/Plugins/FilmMakinesi.py +3 -3
- KekikStream/Plugins/FilmModu.py +6 -6
- KekikStream/Plugins/FullHDFilm.py +164 -0
- KekikStream/Plugins/FullHDFilmizlesene.py +3 -3
- KekikStream/Plugins/HDFilmCehennemi.py +3 -0
- KekikStream/Plugins/JetFilmizle.py +16 -9
- KekikStream/Plugins/KultFilmler.py +219 -0
- KekikStream/Plugins/RecTV.py +6 -6
- KekikStream/Plugins/RoketDizi.py +207 -0
- KekikStream/Plugins/SelcukFlix.py +216 -0
- KekikStream/Plugins/SezonlukDizi.py +11 -8
- KekikStream/Plugins/SineWix.py +4 -4
- KekikStream/Plugins/Sinefy.py +214 -0
- KekikStream/Plugins/SinemaCX.py +9 -9
- KekikStream/Plugins/Sinezy.py +99 -0
- KekikStream/Plugins/SuperFilmGeldi.py +121 -0
- KekikStream/Plugins/UgurFilm.py +6 -6
- KekikStream/requirements.txt +2 -2
- {kekikstream-1.7.2.dist-info → kekikstream-1.7.5.dist-info}/METADATA +2 -1
- kekikstream-1.7.5.dist-info/RECORD +85 -0
- kekikstream-1.7.2.dist-info/RECORD +0 -64
- {kekikstream-1.7.2.dist-info → kekikstream-1.7.5.dist-info}/WHEEL +0 -0
- {kekikstream-1.7.2.dist-info → kekikstream-1.7.5.dist-info}/entry_points.txt +0 -0
- {kekikstream-1.7.2.dist-info → kekikstream-1.7.5.dist-info}/licenses/LICENSE +0 -0
- {kekikstream-1.7.2.dist-info → kekikstream-1.7.5.dist-info}/top_level.txt +0 -0
|
@@ -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")},
|
|
@@ -134,6 +134,9 @@ class SezonlukDizi(PluginBase):
|
|
|
134
134
|
secici = Selector(veri_response.text)
|
|
135
135
|
|
|
136
136
|
if iframe := secici.css("iframe::attr(src)").get():
|
|
137
|
+
if "link.asp" in iframe:
|
|
138
|
+
continue
|
|
139
|
+
|
|
137
140
|
extractor = self.ex_manager.find_extractor(self.fix_url(iframe))
|
|
138
141
|
results.append({
|
|
139
142
|
"url" : self.fix_url(iframe),
|
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")
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
|
+
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, SeriesInfo, Episode, MovieInfo
|
|
4
|
+
from parsel import Selector
|
|
5
|
+
import re, json, urllib.parse
|
|
6
|
+
|
|
7
|
+
class Sinefy(PluginBase):
|
|
8
|
+
name = "Sinefy"
|
|
9
|
+
main_url = "https://sinefy3.com"
|
|
10
|
+
lang = "tr"
|
|
11
|
+
|
|
12
|
+
main_page = {
|
|
13
|
+
"page/" : "Son Eklenenler",
|
|
14
|
+
"en-yenifilmler" : "Yeni Filmler",
|
|
15
|
+
"netflix-filmleri-izle" : "Netflix Filmleri",
|
|
16
|
+
"dizi-izle/netflix" : "Netflix Dizileri"
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
20
|
+
if "page/" in url:
|
|
21
|
+
full_url = f"{self.main_url}/{url}{page}"
|
|
22
|
+
elif "en-yenifilmler" in url or "netflix" in url:
|
|
23
|
+
full_url = f"{self.main_url}/{url}/{page}"
|
|
24
|
+
else:
|
|
25
|
+
full_url = f"{self.main_url}/{url}&page={page}"
|
|
26
|
+
|
|
27
|
+
resp = await self.httpx.get(full_url)
|
|
28
|
+
sel = Selector(resp.text)
|
|
29
|
+
|
|
30
|
+
results = []
|
|
31
|
+
# Kotlin: div.poster-with-subject, div.dark-segment div.poster-md.poster
|
|
32
|
+
for item in sel.css("div.poster-with-subject, div.dark-segment div.poster-md.poster"):
|
|
33
|
+
title = item.css("h2::text").get()
|
|
34
|
+
href = item.css("a::attr(href)").get()
|
|
35
|
+
poster= item.css("img::attr(data-srcset)").get()
|
|
36
|
+
if poster:
|
|
37
|
+
poster = poster.split(",")[0].split(" ")[0]
|
|
38
|
+
|
|
39
|
+
if title and href:
|
|
40
|
+
results.append(MainPageResult(
|
|
41
|
+
category=category,
|
|
42
|
+
title=title,
|
|
43
|
+
url=self.fix_url(href),
|
|
44
|
+
poster=self.fix_url(poster)
|
|
45
|
+
))
|
|
46
|
+
return results
|
|
47
|
+
|
|
48
|
+
async def search(self, query: str) -> list[SearchResult]:
|
|
49
|
+
# Try to get dynamic keys from main page first
|
|
50
|
+
c_key = "ca1d4a53d0f4761a949b85e51e18f096"
|
|
51
|
+
c_value = "MTc0NzI2OTAwMDU3ZTEwYmZjMDViNWFmOWIwZDViODg0MjU4MjA1ZmYxOThmZTYwMDdjMWQzMzliNzY5NzFlZmViMzRhMGVmNjgwODU3MGIyZA=="
|
|
52
|
+
|
|
53
|
+
try:
|
|
54
|
+
resp = await self.httpx.get(self.main_url)
|
|
55
|
+
sel = Selector(resp.text)
|
|
56
|
+
cke = sel.css("input[name='cKey']::attr(value)").get()
|
|
57
|
+
cval = sel.css("input[name='cValue']::attr(value)").get()
|
|
58
|
+
if cke and cval:
|
|
59
|
+
c_key = cke
|
|
60
|
+
c_value = cval
|
|
61
|
+
except Exception:
|
|
62
|
+
pass
|
|
63
|
+
|
|
64
|
+
post_url = f"{self.main_url}/bg/searchcontent"
|
|
65
|
+
data = {
|
|
66
|
+
"cKey": c_key,
|
|
67
|
+
"cValue": c_value,
|
|
68
|
+
"searchTerm": query
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
headers = {
|
|
72
|
+
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:134.0) Gecko/20100101 Firefox/134.0",
|
|
73
|
+
"Accept": "application/json, text/javascript, */*; q=0.01",
|
|
74
|
+
"X-Requested-With": "XMLHttpRequest",
|
|
75
|
+
"Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
response = await self.httpx.post(post_url, data=data, headers=headers)
|
|
79
|
+
|
|
80
|
+
try:
|
|
81
|
+
# Extract JSON data from response (might contain garbage chars at start)
|
|
82
|
+
raw = response.text
|
|
83
|
+
json_start = raw.find('{')
|
|
84
|
+
if json_start != -1:
|
|
85
|
+
clean_json = raw[json_start:]
|
|
86
|
+
data = json.loads(clean_json)
|
|
87
|
+
|
|
88
|
+
results = []
|
|
89
|
+
# Result array is in data['data']['result']
|
|
90
|
+
res_array = data.get("data", {}).get("result", [])
|
|
91
|
+
|
|
92
|
+
if not res_array:
|
|
93
|
+
# Fallback manual parsing ?
|
|
94
|
+
pass
|
|
95
|
+
|
|
96
|
+
for item in res_array:
|
|
97
|
+
name = item.get("object_name")
|
|
98
|
+
slug = item.get("used_slug")
|
|
99
|
+
poster = item.get("object_poster_url")
|
|
100
|
+
|
|
101
|
+
if name and slug:
|
|
102
|
+
if "cdn.ampproject.org" in poster:
|
|
103
|
+
poster = "https://images.macellan.online/images/movie/poster/180/275/80/" + poster.split("/")[-1]
|
|
104
|
+
|
|
105
|
+
results.append(SearchResult(
|
|
106
|
+
title=name,
|
|
107
|
+
url=self.fix_url(slug),
|
|
108
|
+
poster=self.fix_url(poster)
|
|
109
|
+
))
|
|
110
|
+
return results
|
|
111
|
+
|
|
112
|
+
except Exception:
|
|
113
|
+
pass
|
|
114
|
+
return []
|
|
115
|
+
|
|
116
|
+
async def load_item(self, url: str) -> SeriesInfo:
|
|
117
|
+
resp = await self.httpx.get(url)
|
|
118
|
+
sel = Selector(resp.text)
|
|
119
|
+
|
|
120
|
+
title = sel.css("h1::text").get()
|
|
121
|
+
poster_info = sel.css("div.ui.items img::attr(data-srcset)").get()
|
|
122
|
+
poster = None
|
|
123
|
+
if poster_info:
|
|
124
|
+
# take 1x
|
|
125
|
+
parts = str(poster_info).split(",")
|
|
126
|
+
for p in parts:
|
|
127
|
+
if "1x" in p:
|
|
128
|
+
poster = p.strip().split(" ")[0]
|
|
129
|
+
break
|
|
130
|
+
|
|
131
|
+
description = sel.css("p#tv-series-desc::text").get()
|
|
132
|
+
tags = sel.css("div.item.categories a::text").getall()
|
|
133
|
+
rating = sel.css("span.color-imdb::text").get()
|
|
134
|
+
actors = sel.css("div.content h5::text").getall()
|
|
135
|
+
|
|
136
|
+
episodes = []
|
|
137
|
+
season_elements = sel.css("section.episodes-box")
|
|
138
|
+
|
|
139
|
+
if season_elements:
|
|
140
|
+
# Get season links
|
|
141
|
+
season_links = []
|
|
142
|
+
menu = sel.css("div.ui.vertical.fluid.tabular.menu a")
|
|
143
|
+
for link in menu:
|
|
144
|
+
href = link.css("::attr(href)").get()
|
|
145
|
+
if href:
|
|
146
|
+
season_links.append(self.fix_url(href))
|
|
147
|
+
|
|
148
|
+
for s_url in season_links:
|
|
149
|
+
target_url = s_url if "/bolum-" in s_url else f"{s_url}/bolum-1"
|
|
150
|
+
|
|
151
|
+
try:
|
|
152
|
+
s_resp = await self.httpx.get(target_url)
|
|
153
|
+
s_sel = Selector(s_resp.text)
|
|
154
|
+
ep_links = s_sel.css("div.ui.list.celled a.item")
|
|
155
|
+
|
|
156
|
+
current_season_no = 1
|
|
157
|
+
match = re.search(r"sezon-(\d+)", target_url)
|
|
158
|
+
if match:
|
|
159
|
+
current_season_no = int(match.group(1))
|
|
160
|
+
|
|
161
|
+
for ep_link in ep_links:
|
|
162
|
+
href = ep_link.css("::attr(href)").get()
|
|
163
|
+
name = ep_link.css("div.content div.header::text").get()
|
|
164
|
+
|
|
165
|
+
if href:
|
|
166
|
+
ep_no = 0
|
|
167
|
+
match_ep = re.search(r"bolum-(\d+)", href)
|
|
168
|
+
if match_ep:
|
|
169
|
+
ep_no = int(match_ep.group(1))
|
|
170
|
+
|
|
171
|
+
episodes.append(Episode(
|
|
172
|
+
season = current_season_no,
|
|
173
|
+
episode = ep_no,
|
|
174
|
+
title = name.strip() if name else "",
|
|
175
|
+
url = self.fix_url(href)
|
|
176
|
+
))
|
|
177
|
+
except Exception:
|
|
178
|
+
pass
|
|
179
|
+
|
|
180
|
+
if episodes:
|
|
181
|
+
return SeriesInfo(
|
|
182
|
+
title=title,
|
|
183
|
+
url=url,
|
|
184
|
+
poster=self.fix_url(poster),
|
|
185
|
+
description=description,
|
|
186
|
+
rating=rating,
|
|
187
|
+
tags=tags,
|
|
188
|
+
actors=actors,
|
|
189
|
+
episodes=episodes
|
|
190
|
+
)
|
|
191
|
+
else:
|
|
192
|
+
return MovieInfo(
|
|
193
|
+
title=title,
|
|
194
|
+
url=url,
|
|
195
|
+
poster=self.fix_url(poster),
|
|
196
|
+
description=description,
|
|
197
|
+
rating=rating,
|
|
198
|
+
tags=tags,
|
|
199
|
+
actors=actors
|
|
200
|
+
)
|
|
201
|
+
|
|
202
|
+
async def load_links(self, url: str) -> list[dict]:
|
|
203
|
+
resp = await self.httpx.get(url)
|
|
204
|
+
sel = Selector(resp.text)
|
|
205
|
+
|
|
206
|
+
iframe = sel.css("iframe::attr(src)").get()
|
|
207
|
+
if iframe:
|
|
208
|
+
iframe = self.fix_url(iframe)
|
|
209
|
+
extractor = self.ex_manager.find_extractor(iframe)
|
|
210
|
+
return [{
|
|
211
|
+
"url": iframe,
|
|
212
|
+
"name": extractor.name if extractor else "Iframe"
|
|
213
|
+
}]
|
|
214
|
+
return []
|
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()
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
|
+
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo
|
|
4
|
+
from parsel import Selector
|
|
5
|
+
import re, base64
|
|
6
|
+
|
|
7
|
+
class Sinezy(PluginBase):
|
|
8
|
+
name = "Sinezy"
|
|
9
|
+
main_url = "https://sinezy.site"
|
|
10
|
+
lang = "tr"
|
|
11
|
+
|
|
12
|
+
main_page = {
|
|
13
|
+
"izle/en-yeni-filmler/" : "Yeni Filmler",
|
|
14
|
+
"izle/en-yi-filmler/" : "En İyi Filmler"
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
18
|
+
full_url = f"{self.main_url}/{url}page/{page}/"
|
|
19
|
+
resp = await self.httpx.get(full_url)
|
|
20
|
+
sel = Selector(resp.text)
|
|
21
|
+
|
|
22
|
+
results = []
|
|
23
|
+
for item in sel.css("div.container div.content div.movie_box.move_k"):
|
|
24
|
+
title = item.css("a::attr(title)").get()
|
|
25
|
+
href = item.css("a::attr(href)").get()
|
|
26
|
+
poster= item.css("img::attr(data-src)").get()
|
|
27
|
+
|
|
28
|
+
if title and href:
|
|
29
|
+
results.append(MainPageResult(
|
|
30
|
+
category=category,
|
|
31
|
+
title=title,
|
|
32
|
+
url=self.fix_url(href),
|
|
33
|
+
poster=self.fix_url(poster)
|
|
34
|
+
))
|
|
35
|
+
return results
|
|
36
|
+
|
|
37
|
+
async def search(self, query: str) -> list[SearchResult]:
|
|
38
|
+
url = f"{self.main_url}/arama/?s={query}"
|
|
39
|
+
resp = await self.httpx.get(url)
|
|
40
|
+
sel = Selector(resp.text)
|
|
41
|
+
|
|
42
|
+
results = []
|
|
43
|
+
for item in sel.css("div.movie_box.move_k"):
|
|
44
|
+
title = item.css("a::attr(title)").get()
|
|
45
|
+
href = item.css("a::attr(href)").get()
|
|
46
|
+
poster= item.css("img::attr(data-src)").get()
|
|
47
|
+
|
|
48
|
+
if title and href:
|
|
49
|
+
results.append(SearchResult(
|
|
50
|
+
title=title,
|
|
51
|
+
url=self.fix_url(href),
|
|
52
|
+
poster=self.fix_url(poster)
|
|
53
|
+
))
|
|
54
|
+
return results
|
|
55
|
+
|
|
56
|
+
async def load_item(self, url: str) -> MovieInfo:
|
|
57
|
+
resp = await self.httpx.get(url)
|
|
58
|
+
sel = Selector(resp.text)
|
|
59
|
+
|
|
60
|
+
title = sel.css("div.detail::attr(title)").get()
|
|
61
|
+
poster = sel.css("div.move_k img::attr(data-src)").get()
|
|
62
|
+
description = sel.css("div.desc.yeniscroll p::text").get()
|
|
63
|
+
rating = sel.css("span.info span.imdb::text").get()
|
|
64
|
+
|
|
65
|
+
tags = sel.css("div.detail span a::text").getall()
|
|
66
|
+
actors = sel.css("span.oyn p::text").getall() # Might need splitting logic
|
|
67
|
+
|
|
68
|
+
return MovieInfo(
|
|
69
|
+
title=title,
|
|
70
|
+
url=url,
|
|
71
|
+
poster=self.fix_url(poster),
|
|
72
|
+
description=description,
|
|
73
|
+
tags=tags,
|
|
74
|
+
rating=rating,
|
|
75
|
+
actors=actors
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
async def load_links(self, url: str) -> list[dict]:
|
|
79
|
+
resp = await self.httpx.get(url)
|
|
80
|
+
|
|
81
|
+
match = re.search(r"ilkpartkod\s*=\s*'([^']+)'", resp.text, re.IGNORECASE)
|
|
82
|
+
if match:
|
|
83
|
+
encoded = match.group(1)
|
|
84
|
+
try:
|
|
85
|
+
decoded = base64.b64decode(encoded).decode('utf-8')
|
|
86
|
+
iframe_match = re.search(r'src="([^"]*)"', decoded)
|
|
87
|
+
if iframe_match:
|
|
88
|
+
iframe = iframe_match.group(1)
|
|
89
|
+
iframe = self.fix_url(iframe)
|
|
90
|
+
|
|
91
|
+
extractor = self.ex_manager.find_extractor(iframe)
|
|
92
|
+
return [{
|
|
93
|
+
"url": iframe,
|
|
94
|
+
"name": extractor.name if extractor else "Iframe"
|
|
95
|
+
}]
|
|
96
|
+
except Exception:
|
|
97
|
+
pass
|
|
98
|
+
|
|
99
|
+
return []
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
|
+
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, ExtractResult, Subtitle
|
|
4
|
+
from parsel import Selector
|
|
5
|
+
import re
|
|
6
|
+
|
|
7
|
+
class SuperFilmGeldi(PluginBase):
|
|
8
|
+
name = "SuperFilmGeldi"
|
|
9
|
+
language = "tr"
|
|
10
|
+
main_url = "https://www.superfilmgeldi13.art"
|
|
11
|
+
favicon = f"https://www.google.com/s2/favicons?domain={main_url}&sz=64"
|
|
12
|
+
description = "Ücretsiz film izleme sitesi."
|
|
13
|
+
|
|
14
|
+
main_page = {
|
|
15
|
+
f"{main_url}/page/SAYFA" : "Son Eklenenler",
|
|
16
|
+
f"{main_url}/hdizle/category/aksiyon/page/SAYFA" : "Aksiyon",
|
|
17
|
+
f"{main_url}/hdizle/category/animasyon/page/SAYFA" : "Animasyon",
|
|
18
|
+
f"{main_url}/hdizle/category/belgesel/page/SAYFA" : "Belgesel",
|
|
19
|
+
f"{main_url}/hdizle/category/bilim-kurgu/page/SAYFA" : "Bilim Kurgu",
|
|
20
|
+
f"{main_url}/hdizle/category/fantastik/page/SAYFA" : "Fantastik",
|
|
21
|
+
f"{main_url}/hdizle/category/komedi-filmleri/page/SAYFA" : "Komedi Filmleri",
|
|
22
|
+
f"{main_url}/hdizle/category/macera/page/SAYFA" : "Macera",
|
|
23
|
+
f"{main_url}/hdizle/category/gerilim/page/SAYFA" : "Gerilim",
|
|
24
|
+
f"{main_url}/hdizle/category/suc/page/SAYFA" : "Suç",
|
|
25
|
+
f"{main_url}/hdizle/category/karete-filmleri/page/SAYFA" : "Karate Filmleri",
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
29
|
+
istek = await self.httpx.get(url.replace("SAYFA", str(page)))
|
|
30
|
+
secici = Selector(istek.text)
|
|
31
|
+
|
|
32
|
+
return [
|
|
33
|
+
MainPageResult(
|
|
34
|
+
category = category,
|
|
35
|
+
title = self.clean_title(veri.css("span.movie-title a::text").get().split(" izle")[0]),
|
|
36
|
+
url = self.fix_url(veri.css("span.movie-title a::attr(href)").get()),
|
|
37
|
+
poster = self.fix_url(veri.css("img::attr(src)").get()),
|
|
38
|
+
)
|
|
39
|
+
for veri in secici.css("div.movie-preview-content")
|
|
40
|
+
if veri.css("span.movie-title a::text").get()
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
async def search(self, query: str) -> list[SearchResult]:
|
|
44
|
+
istek = await self.httpx.get(f"{self.main_url}?s={query}")
|
|
45
|
+
secici = Selector(istek.text)
|
|
46
|
+
|
|
47
|
+
return [
|
|
48
|
+
SearchResult(
|
|
49
|
+
title = self.clean_title(veri.css("span.movie-title a::text").get().split(" izle")[0]),
|
|
50
|
+
url = self.fix_url(veri.css("span.movie-title a::attr(href)").get()),
|
|
51
|
+
poster = self.fix_url(veri.css("img::attr(src)").get()),
|
|
52
|
+
)
|
|
53
|
+
for veri in secici.css("div.movie-preview-content")
|
|
54
|
+
if veri.css("span.movie-title a::text").get()
|
|
55
|
+
]
|
|
56
|
+
|
|
57
|
+
async def load_item(self, url: str) -> MovieInfo:
|
|
58
|
+
istek = await self.httpx.get(url)
|
|
59
|
+
secici = Selector(istek.text)
|
|
60
|
+
|
|
61
|
+
title = secici.css("div.title h1::text").get()
|
|
62
|
+
title = self.clean_title(title.split(" izle")[0]) if title else ""
|
|
63
|
+
poster = self.fix_url(secici.css("div.poster img::attr(src)").get())
|
|
64
|
+
year = secici.css("div.release a::text").re_first(r"(\d{4})")
|
|
65
|
+
description = secici.css("div.excerpt p::text").get()
|
|
66
|
+
tags = secici.css("div.categories a::text").getall()
|
|
67
|
+
actors = secici.css("div.actor a::text").getall()
|
|
68
|
+
|
|
69
|
+
return MovieInfo(
|
|
70
|
+
url = url,
|
|
71
|
+
poster = poster,
|
|
72
|
+
title = title,
|
|
73
|
+
description = description,
|
|
74
|
+
tags = tags,
|
|
75
|
+
year = year,
|
|
76
|
+
actors = actors,
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
async def load_links(self, url: str) -> list[dict]:
|
|
80
|
+
istek = await self.httpx.get(url)
|
|
81
|
+
secici = Selector(istek.text)
|
|
82
|
+
|
|
83
|
+
iframe = self.fix_url(secici.css("div#vast iframe::attr(src)").get())
|
|
84
|
+
if not iframe:
|
|
85
|
+
return []
|
|
86
|
+
|
|
87
|
+
results = []
|
|
88
|
+
|
|
89
|
+
# Mix player özel işleme
|
|
90
|
+
if "mix" in iframe and "index.php?data=" in iframe:
|
|
91
|
+
iframe_istek = await self.httpx.get(iframe, headers={"Referer": f"{self.main_url}/"})
|
|
92
|
+
mix_point = re.search(r'videoUrl":"(.*)","videoServer', iframe_istek.text)
|
|
93
|
+
|
|
94
|
+
if mix_point:
|
|
95
|
+
mix_point = mix_point[1].replace("\\", "")
|
|
96
|
+
|
|
97
|
+
# Endpoint belirleme
|
|
98
|
+
if "mixlion" in iframe:
|
|
99
|
+
end_point = "?s=3&d="
|
|
100
|
+
elif "mixeagle" in iframe:
|
|
101
|
+
end_point = "?s=1&d="
|
|
102
|
+
else:
|
|
103
|
+
end_point = "?s=0&d="
|
|
104
|
+
|
|
105
|
+
m3u_link = iframe.split("/player")[0] + mix_point + end_point
|
|
106
|
+
|
|
107
|
+
results.append({
|
|
108
|
+
"name" : f"{self.name} | Mix Player",
|
|
109
|
+
"url" : m3u_link,
|
|
110
|
+
"referer" : iframe,
|
|
111
|
+
"subtitles" : []
|
|
112
|
+
})
|
|
113
|
+
else:
|
|
114
|
+
extractor = self.ex_manager.find_extractor(iframe)
|
|
115
|
+
results.append({
|
|
116
|
+
"name" : extractor.name if extractor else "Player",
|
|
117
|
+
"url" : iframe,
|
|
118
|
+
"referer" : f"{self.main_url}/"
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
return results
|
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
|
)
|