KekikStream 1.8.3__py3-none-any.whl → 1.8.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 +2 -14
- KekikStream/Core/Plugin/PluginBase.py +2 -15
- KekikStream/Plugins/DiziBox.py +0 -1
- KekikStream/Plugins/DiziYou.py +1 -2
- KekikStream/Plugins/Dizilla.py +0 -2
- KekikStream/Plugins/FilmMakinesi.py +1 -2
- KekikStream/Plugins/FullHDFilmizlesene.py +1 -2
- KekikStream/Plugins/HDFilmCehennemi.py +11 -15
- KekikStream/Plugins/JetFilmizle.py +1 -2
- KekikStream/Plugins/RecTV.py +1 -2
- KekikStream/Plugins/RoketDizi.py +5 -6
- KekikStream/Plugins/SelcukFlix.py +160 -67
- KekikStream/Plugins/SezonlukDizi.py +1 -2
- KekikStream/Plugins/SineWix.py +1 -2
- KekikStream/Plugins/Sinefy.py +72 -51
- KekikStream/Plugins/Sinezy.py +74 -42
- KekikStream/Plugins/UgurFilm.py +1 -2
- KekikStream/requirements.txt +2 -3
- {kekikstream-1.8.3.dist-info → kekikstream-1.8.5.dist-info}/METADATA +1 -2
- {kekikstream-1.8.3.dist-info → kekikstream-1.8.5.dist-info}/RECORD +24 -24
- {kekikstream-1.8.3.dist-info → kekikstream-1.8.5.dist-info}/WHEEL +0 -0
- {kekikstream-1.8.3.dist-info → kekikstream-1.8.5.dist-info}/entry_points.txt +0 -0
- {kekikstream-1.8.3.dist-info → kekikstream-1.8.5.dist-info}/licenses/LICENSE +0 -0
- {kekikstream-1.8.3.dist-info → kekikstream-1.8.5.dist-info}/top_level.txt +0 -0
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
2
|
|
|
3
3
|
from abc import ABC, abstractmethod
|
|
4
|
-
from curl_cffi import AsyncSession
|
|
5
4
|
from cloudscraper import CloudScraper
|
|
6
5
|
from httpx import AsyncClient
|
|
7
6
|
from typing import Optional
|
|
@@ -12,7 +11,6 @@ class ExtractorBase(ABC):
|
|
|
12
11
|
# Çıkarıcının temel özellikleri
|
|
13
12
|
name = "Extractor"
|
|
14
13
|
main_url = ""
|
|
15
|
-
requires_cffi = False
|
|
16
14
|
|
|
17
15
|
def __init__(self):
|
|
18
16
|
# cloudscraper - for bypassing Cloudflare
|
|
@@ -21,19 +19,11 @@ class ExtractorBase(ABC):
|
|
|
21
19
|
# httpx - lightweight and safe for most HTTP requests
|
|
22
20
|
self.httpx = AsyncClient(
|
|
23
21
|
timeout = 3,
|
|
24
|
-
follow_redirects = True
|
|
22
|
+
follow_redirects = True
|
|
25
23
|
)
|
|
26
24
|
self.httpx.headers.update(self.cloudscraper.headers)
|
|
27
25
|
self.httpx.cookies.update(self.cloudscraper.cookies)
|
|
28
26
|
|
|
29
|
-
# curl_cffi - only initialize if needed for anti-bot bypass
|
|
30
|
-
self.cffi = None
|
|
31
|
-
|
|
32
|
-
if self.requires_cffi:
|
|
33
|
-
self.cffi = AsyncSession(impersonate="firefox135")
|
|
34
|
-
self.cffi.cookies.update(self.cloudscraper.cookies)
|
|
35
|
-
self.cffi.headers.update({"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 15.7; rv:135.0) Gecko/20100101 Firefox/135.0"})
|
|
36
|
-
|
|
37
27
|
def can_handle_url(self, url: str) -> bool:
|
|
38
28
|
# URL'nin bu çıkarıcı tarafından işlenip işlenemeyeceğini kontrol et
|
|
39
29
|
return self.main_url in url
|
|
@@ -44,10 +34,8 @@ class ExtractorBase(ABC):
|
|
|
44
34
|
pass
|
|
45
35
|
|
|
46
36
|
async def close(self):
|
|
47
|
-
"""Close
|
|
37
|
+
"""Close HTTP client."""
|
|
48
38
|
await self.httpx.aclose()
|
|
49
|
-
if self.cffi:
|
|
50
|
-
await self.cffi.close()
|
|
51
39
|
|
|
52
40
|
def fix_url(self, url: str) -> str:
|
|
53
41
|
# Eksik URL'leri düzelt ve tam URL formatına çevir
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
2
|
|
|
3
3
|
from abc import ABC, abstractmethod
|
|
4
|
-
from curl_cffi import AsyncSession
|
|
5
4
|
from cloudscraper import CloudScraper
|
|
6
5
|
from httpx import AsyncClient
|
|
7
6
|
from .PluginModels import MainPageResult, SearchResult, MovieInfo
|
|
@@ -17,8 +16,6 @@ class PluginBase(ABC):
|
|
|
17
16
|
favicon = f"https://www.google.com/s2/favicons?domain={main_url}&sz=64"
|
|
18
17
|
description = "No description provided."
|
|
19
18
|
|
|
20
|
-
requires_cffi = False
|
|
21
|
-
|
|
22
19
|
main_page = {}
|
|
23
20
|
|
|
24
21
|
async def url_update(self, new_url: str):
|
|
@@ -33,19 +30,11 @@ class PluginBase(ABC):
|
|
|
33
30
|
# httpx - lightweight and safe for most HTTP requests
|
|
34
31
|
self.httpx = AsyncClient(
|
|
35
32
|
timeout = 3,
|
|
36
|
-
follow_redirects = True
|
|
33
|
+
follow_redirects = True
|
|
37
34
|
)
|
|
38
35
|
self.httpx.headers.update(self.cloudscraper.headers)
|
|
39
36
|
self.httpx.cookies.update(self.cloudscraper.cookies)
|
|
40
37
|
|
|
41
|
-
# curl_cffi - only initialize if needed for anti-bot bypass
|
|
42
|
-
self.cffi = None
|
|
43
|
-
|
|
44
|
-
if self.requires_cffi:
|
|
45
|
-
self.cffi = AsyncSession(impersonate="firefox135")
|
|
46
|
-
self.cffi.cookies.update(self.cloudscraper.cookies)
|
|
47
|
-
self.cffi.headers.update({"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 15.7; rv:135.0) Gecko/20100101 Firefox/135.0"})
|
|
48
|
-
|
|
49
38
|
self.media_handler = MediaHandler()
|
|
50
39
|
self.ex_manager = ExtractorManager()
|
|
51
40
|
|
|
@@ -90,10 +79,8 @@ class PluginBase(ABC):
|
|
|
90
79
|
pass
|
|
91
80
|
|
|
92
81
|
async def close(self):
|
|
93
|
-
"""Close
|
|
82
|
+
"""Close HTTP client."""
|
|
94
83
|
await self.httpx.aclose()
|
|
95
|
-
if self.cffi:
|
|
96
|
-
await self.cffi.close()
|
|
97
84
|
|
|
98
85
|
def fix_url(self, url: str) -> str:
|
|
99
86
|
if not url:
|
KekikStream/Plugins/DiziBox.py
CHANGED
KekikStream/Plugins/DiziYou.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
2
|
|
|
3
|
-
from KekikStream.Core import
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, SeriesInfo, Episode, Subtitle, ExtractResult
|
|
4
4
|
from parsel import Selector
|
|
5
5
|
import re
|
|
6
6
|
|
|
@@ -123,7 +123,6 @@ class DiziYou(PluginBase):
|
|
|
123
123
|
actors = actors
|
|
124
124
|
)
|
|
125
125
|
|
|
126
|
-
#@kekik_cache(ttl=15*60)
|
|
127
126
|
async def load_links(self, url: str) -> list[dict]:
|
|
128
127
|
istek = await self.httpx.get(url)
|
|
129
128
|
secici = Selector(istek.text)
|
KekikStream/Plugins/Dizilla.py
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
2
|
|
|
3
|
-
from Kekik.cli import konsol
|
|
4
3
|
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, SeriesInfo, Episode
|
|
5
4
|
from parsel import Selector
|
|
6
5
|
from json import loads
|
|
@@ -171,7 +170,6 @@ class Dizilla(PluginBase):
|
|
|
171
170
|
actors = actors
|
|
172
171
|
)
|
|
173
172
|
|
|
174
|
-
#@kekik_cache(ttl=15*60)
|
|
175
173
|
async def load_links(self, url: str) -> list[dict]:
|
|
176
174
|
istek = await self.httpx.get(url)
|
|
177
175
|
secici = Selector(istek.text)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
2
|
|
|
3
|
-
from KekikStream.Core import
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo
|
|
4
4
|
from parsel import Selector
|
|
5
5
|
|
|
6
6
|
class FilmMakinesi(PluginBase):
|
|
@@ -98,7 +98,6 @@ class FilmMakinesi(PluginBase):
|
|
|
98
98
|
duration = duration
|
|
99
99
|
)
|
|
100
100
|
|
|
101
|
-
#@kekik_cache(ttl=15*60)
|
|
102
101
|
async def load_links(self, url: str) -> list[dict]:
|
|
103
102
|
istek = await self.httpx.get(url)
|
|
104
103
|
secici = Selector(istek.text)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
2
|
|
|
3
|
-
from KekikStream.Core import
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo
|
|
4
4
|
from parsel import Selector
|
|
5
5
|
from Kekik.Sifreleme import StringCodec
|
|
6
6
|
import json, re
|
|
@@ -100,7 +100,6 @@ class FullHDFilmizlesene(PluginBase):
|
|
|
100
100
|
duration = duration
|
|
101
101
|
)
|
|
102
102
|
|
|
103
|
-
#@kekik_cache(ttl=15*60)
|
|
104
103
|
async def load_links(self, url: str) -> list[dict]:
|
|
105
104
|
istek = await self.httpx.get(url)
|
|
106
105
|
secici = Selector(istek.text)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
2
|
|
|
3
|
-
from KekikStream.Core import
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, ExtractResult, Subtitle
|
|
4
4
|
from parsel import Selector
|
|
5
5
|
from Kekik.Sifreleme import Packer, StreamDecoder
|
|
6
6
|
import random, string, re
|
|
@@ -12,8 +12,7 @@ class HDFilmCehennemi(PluginBase):
|
|
|
12
12
|
favicon = f"https://www.google.com/s2/favicons?domain={main_url}&sz=64"
|
|
13
13
|
description = "Türkiye'nin en hızlı hd film izleme sitesi"
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
requires_cffi = True
|
|
15
|
+
|
|
17
16
|
|
|
18
17
|
main_page = {
|
|
19
18
|
f"{main_url}" : "Yeni Eklenen Filmler",
|
|
@@ -33,7 +32,7 @@ class HDFilmCehennemi(PluginBase):
|
|
|
33
32
|
}
|
|
34
33
|
|
|
35
34
|
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
36
|
-
istek = await self.
|
|
35
|
+
istek = await self.httpx.get(f"{url}", follow_redirects=True)
|
|
37
36
|
secici = Selector(istek.text)
|
|
38
37
|
|
|
39
38
|
return [
|
|
@@ -47,7 +46,7 @@ class HDFilmCehennemi(PluginBase):
|
|
|
47
46
|
]
|
|
48
47
|
|
|
49
48
|
async def search(self, query: str) -> list[SearchResult]:
|
|
50
|
-
istek = await self.
|
|
49
|
+
istek = await self.httpx.get(
|
|
51
50
|
url = f"{self.main_url}/search/?q={query}",
|
|
52
51
|
headers = {
|
|
53
52
|
"Referer" : f"{self.main_url}/",
|
|
@@ -75,7 +74,7 @@ class HDFilmCehennemi(PluginBase):
|
|
|
75
74
|
return results
|
|
76
75
|
|
|
77
76
|
async def load_item(self, url: str) -> MovieInfo:
|
|
78
|
-
istek = await self.
|
|
77
|
+
istek = await self.httpx.get(url, headers = {"Referer": f"{self.main_url}/"})
|
|
79
78
|
secici = Selector(istek.text)
|
|
80
79
|
|
|
81
80
|
title = secici.css("h1.section-title::text").get().strip()
|
|
@@ -108,11 +107,10 @@ class HDFilmCehennemi(PluginBase):
|
|
|
108
107
|
def generate_random_cookie(self):
|
|
109
108
|
return "".join(random.choices(string.ascii_letters + string.digits, k=16))
|
|
110
109
|
|
|
111
|
-
#@kekik_cache(ttl=15*60)
|
|
112
110
|
async def cehennempass(self, video_id: str) -> list[dict]:
|
|
113
111
|
results = []
|
|
114
112
|
|
|
115
|
-
istek = await self.
|
|
113
|
+
istek = await self.httpx.post(
|
|
116
114
|
url = "https://cehennempass.pw/process_quality_selection.php",
|
|
117
115
|
headers = {
|
|
118
116
|
"Referer" : f"https://cehennempass.pw/download/{video_id}",
|
|
@@ -129,7 +127,7 @@ class HDFilmCehennemi(PluginBase):
|
|
|
129
127
|
"referer" : f"https://cehennempass.pw/download/{video_id}"
|
|
130
128
|
})
|
|
131
129
|
|
|
132
|
-
istek = await self.
|
|
130
|
+
istek = await self.httpx.post(
|
|
133
131
|
url = "https://cehennempass.pw/process_quality_selection.php",
|
|
134
132
|
headers = {
|
|
135
133
|
"Referer" : f"https://cehennempass.pw/download/{video_id}",
|
|
@@ -148,10 +146,9 @@ class HDFilmCehennemi(PluginBase):
|
|
|
148
146
|
|
|
149
147
|
return results
|
|
150
148
|
|
|
151
|
-
#@kekik_cache(ttl=15*60)
|
|
152
149
|
async def invoke_local_source(self, iframe: str, source: str, url: str):
|
|
153
|
-
self.
|
|
154
|
-
istek = await self.
|
|
150
|
+
self.httpx.headers.update({"Referer": f"{self.main_url}/"})
|
|
151
|
+
istek = await self.httpx.get(iframe)
|
|
155
152
|
|
|
156
153
|
try:
|
|
157
154
|
eval_func = re.compile(r'\s*(eval\(function[\s\S].*)\s*').findall(istek.text)[0]
|
|
@@ -179,9 +176,8 @@ class HDFilmCehennemi(PluginBase):
|
|
|
179
176
|
"subtitles" : subtitles
|
|
180
177
|
}]
|
|
181
178
|
|
|
182
|
-
#@kekik_cache(ttl=15*60)
|
|
183
179
|
async def load_links(self, url: str) -> list[dict]:
|
|
184
|
-
istek = await self.
|
|
180
|
+
istek = await self.httpx.get(url)
|
|
185
181
|
secici = Selector(istek.text)
|
|
186
182
|
|
|
187
183
|
results = []
|
|
@@ -192,7 +188,7 @@ class HDFilmCehennemi(PluginBase):
|
|
|
192
188
|
source = f"{link.css('::text').get().replace('(HDrip Xbet)', '').strip()} {lang_code}"
|
|
193
189
|
video_id = link.css("::attr(data-video)").get()
|
|
194
190
|
|
|
195
|
-
api_get = await self.
|
|
191
|
+
api_get = await self.httpx.get(
|
|
196
192
|
url = f"{self.main_url}/video/{video_id}/",
|
|
197
193
|
headers = {
|
|
198
194
|
"Content-Type" : "application/json",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
2
|
|
|
3
|
-
from KekikStream.Core import
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo
|
|
4
4
|
from parsel import Selector
|
|
5
5
|
|
|
6
6
|
class JetFilmizle(PluginBase):
|
|
@@ -89,7 +89,6 @@ class JetFilmizle(PluginBase):
|
|
|
89
89
|
actors = actors
|
|
90
90
|
)
|
|
91
91
|
|
|
92
|
-
#@kekik_cache(ttl=15*60)
|
|
93
92
|
async def load_links(self, url: str) -> list[dict]:
|
|
94
93
|
istek = await self.httpx.get(url)
|
|
95
94
|
secici = Selector(istek.text)
|
KekikStream/Plugins/RecTV.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
2
|
|
|
3
|
-
from KekikStream.Core import
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, Episode, SeriesInfo, ExtractResult, Subtitle
|
|
4
4
|
from json import dumps, loads
|
|
5
5
|
import re
|
|
6
6
|
|
|
@@ -116,7 +116,6 @@ class RecTV(PluginBase):
|
|
|
116
116
|
actors = []
|
|
117
117
|
)
|
|
118
118
|
|
|
119
|
-
#@kekik_cache(ttl=15*60)
|
|
120
119
|
async def load_links(self, url: str) -> list[dict]:
|
|
121
120
|
try:
|
|
122
121
|
veri = loads(url)
|
KekikStream/Plugins/RoketDizi.py
CHANGED
|
@@ -11,8 +11,7 @@ class RoketDizi(PluginBase):
|
|
|
11
11
|
favicon = f"https://www.google.com/s2/favicons?domain={main_url}&sz=64"
|
|
12
12
|
description = "Türkiye'nin en tatlış yabancı dizi izleme sitesi. Türkçe dublaj, altyazılı, eski ve yeni yabancı dizilerin yanı sıra kore (asya) dizileri izleyebilirsiniz."
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
requires_cffi = True
|
|
14
|
+
|
|
16
15
|
|
|
17
16
|
main_page = {
|
|
18
17
|
"dizi/tur/aksiyon" : "Aksiyon",
|
|
@@ -27,7 +26,7 @@ class RoketDizi(PluginBase):
|
|
|
27
26
|
|
|
28
27
|
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
29
28
|
full_url = f"{self.main_url}/{url}?&page={page}"
|
|
30
|
-
resp = await self.
|
|
29
|
+
resp = await self.httpx.get(full_url)
|
|
31
30
|
sel = Selector(resp.text)
|
|
32
31
|
|
|
33
32
|
results = []
|
|
@@ -55,7 +54,7 @@ class RoketDizi(PluginBase):
|
|
|
55
54
|
"Referer" : f"{self.main_url}/",
|
|
56
55
|
}
|
|
57
56
|
|
|
58
|
-
search_req = await self.
|
|
57
|
+
search_req = await self.httpx.post(post_url, headers=headers)
|
|
59
58
|
|
|
60
59
|
try:
|
|
61
60
|
resp_json = search_req.json()
|
|
@@ -99,7 +98,7 @@ class RoketDizi(PluginBase):
|
|
|
99
98
|
|
|
100
99
|
async def load_item(self, url: str) -> SeriesInfo:
|
|
101
100
|
# Note: Handling both Movie and Series logic in one, returning SeriesInfo generally or MovieInfo
|
|
102
|
-
resp = await self.
|
|
101
|
+
resp = await self.httpx.get(url)
|
|
103
102
|
sel = Selector(resp.text)
|
|
104
103
|
|
|
105
104
|
title = sel.css("h1.text-white::text").get()
|
|
@@ -183,7 +182,7 @@ class RoketDizi(PluginBase):
|
|
|
183
182
|
)
|
|
184
183
|
|
|
185
184
|
async def load_links(self, url: str) -> list[dict]:
|
|
186
|
-
resp = await self.
|
|
185
|
+
resp = await self.httpx.get(url)
|
|
187
186
|
sel = Selector(resp.text)
|
|
188
187
|
|
|
189
188
|
next_data = sel.css("script#__NEXT_DATA__::text").get()
|
|
@@ -5,109 +5,202 @@ from parsel import Selector
|
|
|
5
5
|
import re, base64, json, urllib.parse
|
|
6
6
|
|
|
7
7
|
class SelcukFlix(PluginBase):
|
|
8
|
-
name
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
name = "SelcukFlix"
|
|
9
|
+
lang = "tr"
|
|
10
|
+
main_url = "https://selcukflix.net"
|
|
11
|
+
favicon = f"https://www.google.com/s2/favicons?domain={main_url}&sz=64"
|
|
12
|
+
description = "Selcukflix'te her türden en yeni ve en popüler dizi ve filmleri izlemenin keyfini çıkarın. Aksiyondan romantiğe, bilim kurgudan dramaya, geniş kütüphanemizde herkes için bir şey var."
|
|
13
|
+
|
|
12
14
|
main_page = {
|
|
13
|
-
|
|
15
|
+
f"{main_url}/tum-bolumler" : "Yeni Eklenen Bölümler",
|
|
16
|
+
"" : "Yeni Diziler",
|
|
17
|
+
"" : "Kore Dizileri",
|
|
18
|
+
"" : "Yerli Diziler",
|
|
19
|
+
"15" : "Aile",
|
|
20
|
+
"17" : "Animasyon",
|
|
21
|
+
"9" : "Aksiyon",
|
|
22
|
+
"5" : "Bilim Kurgu",
|
|
23
|
+
"2" : "Dram",
|
|
24
|
+
"12" : "Fantastik",
|
|
25
|
+
"18" : "Gerilim",
|
|
26
|
+
"3" : "Gizem",
|
|
27
|
+
"8" : "Korku",
|
|
28
|
+
"4" : "Komedi",
|
|
29
|
+
"7" : "Romantik"
|
|
14
30
|
}
|
|
15
31
|
|
|
16
32
|
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
17
|
-
full_url = f"{self.main_url}/{url}"
|
|
18
|
-
resp = await self.httpx.get(full_url)
|
|
19
|
-
sel = Selector(resp.text)
|
|
20
|
-
|
|
21
33
|
results = []
|
|
22
34
|
if "tum-bolumler" in url:
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
+
try:
|
|
36
|
+
resp = await self.httpx.get(url)
|
|
37
|
+
sel = Selector(resp.text)
|
|
38
|
+
|
|
39
|
+
for item in sel.css("div.col-span-3 a"):
|
|
40
|
+
name = item.css("h2::text").get()
|
|
41
|
+
ep_info = item.css("div.opacity-80::text").get()
|
|
42
|
+
href = item.css("::attr(href)").get()
|
|
43
|
+
poster = item.css("div.image img::attr(src)").get()
|
|
44
|
+
|
|
45
|
+
if name and href:
|
|
46
|
+
title = f"{name} - {ep_info}" if ep_info else name
|
|
47
|
+
final_url = self.fix_url(href)
|
|
48
|
+
|
|
49
|
+
if "/dizi/" in final_url and "/sezon-" in final_url:
|
|
50
|
+
final_url = final_url.split("/sezon-")[0]
|
|
51
|
+
|
|
52
|
+
results.append(MainPageResult(
|
|
53
|
+
category = category,
|
|
54
|
+
title = title,
|
|
55
|
+
url = final_url,
|
|
56
|
+
poster = self.fix_url(poster)
|
|
57
|
+
))
|
|
58
|
+
except Exception:
|
|
59
|
+
pass
|
|
60
|
+
return results
|
|
61
|
+
|
|
62
|
+
base_api = f"{self.main_url}/api/bg/findSeries"
|
|
63
|
+
|
|
64
|
+
params = {
|
|
65
|
+
"releaseYearStart" : "1900",
|
|
66
|
+
"releaseYearEnd" : "2026",
|
|
67
|
+
"imdbPointMin" : "1",
|
|
68
|
+
"imdbPointMax" : "10",
|
|
69
|
+
"categoryIdsComma" : "",
|
|
70
|
+
"countryIdsComma" : "",
|
|
71
|
+
"orderType" : "date_desc",
|
|
72
|
+
"languageId" : "-1",
|
|
73
|
+
"currentPage" : page,
|
|
74
|
+
"currentPageCount" : "24",
|
|
75
|
+
"queryStr" : "",
|
|
76
|
+
"categorySlugsComma" : "",
|
|
77
|
+
"countryCodesComma" : ""
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if "Yerli Diziler" in category:
|
|
81
|
+
params["imdbPointMin"] = "5"
|
|
82
|
+
params["countryIdsComma"] = "29"
|
|
83
|
+
elif "Kore Dizileri" in category:
|
|
84
|
+
params["countryIdsComma"] = "21"
|
|
85
|
+
params["countryCodesComma"] = "KR"
|
|
86
|
+
else:
|
|
87
|
+
params["categoryIdsComma"] = url
|
|
88
|
+
|
|
89
|
+
full_url = f"{base_api}?{urllib.parse.urlencode(params)}"
|
|
90
|
+
|
|
91
|
+
headers = {
|
|
92
|
+
"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:137.0) Gecko/20100101 Firefox/137.0",
|
|
93
|
+
"Accept" : "application/json, text/plain, */*",
|
|
94
|
+
"Accept-Language" : "en-US,en;q=0.5",
|
|
95
|
+
"X-Requested-With" : "XMLHttpRequest",
|
|
96
|
+
"Sec-Fetch-Site" : "same-origin",
|
|
97
|
+
"Sec-Fetch-Mode" : "cors",
|
|
98
|
+
"Sec-Fetch-Dest" : "empty",
|
|
99
|
+
"Referer" : f"{self.main_url}/"
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
try:
|
|
103
|
+
post_resp = await self.httpx.post(full_url, headers=headers)
|
|
104
|
+
resp_json = post_resp.json()
|
|
105
|
+
response_data = resp_json.get("response")
|
|
106
|
+
|
|
107
|
+
raw_data = base64.b64decode(response_data)
|
|
108
|
+
try:
|
|
109
|
+
decoded_str = raw_data.decode('utf-8')
|
|
110
|
+
except UnicodeDecodeError:
|
|
111
|
+
decoded_str = raw_data.decode('iso-8859-1').encode('utf-8').decode('utf-8')
|
|
112
|
+
|
|
113
|
+
data = json.loads(decoded_str)
|
|
114
|
+
|
|
115
|
+
for item in data.get("result", []):
|
|
116
|
+
title = item.get("title")
|
|
117
|
+
slug = item.get("slug")
|
|
118
|
+
poster = item.get("poster")
|
|
119
|
+
|
|
120
|
+
if poster:
|
|
121
|
+
poster = self.clean_image_url(poster)
|
|
122
|
+
|
|
123
|
+
if slug:
|
|
35
124
|
results.append(MainPageResult(
|
|
36
|
-
category=category,
|
|
37
|
-
title=title,
|
|
38
|
-
url=
|
|
39
|
-
poster=
|
|
125
|
+
category = category,
|
|
126
|
+
title = title,
|
|
127
|
+
url = self.fix_url(slug),
|
|
128
|
+
poster = poster
|
|
40
129
|
))
|
|
41
|
-
|
|
130
|
+
|
|
131
|
+
except Exception:
|
|
132
|
+
pass
|
|
133
|
+
|
|
42
134
|
return results
|
|
43
135
|
|
|
44
136
|
async def search(self, query: str) -> list[SearchResult]:
|
|
45
137
|
search_url = f"{self.main_url}/api/bg/searchcontent?searchterm={query}"
|
|
46
|
-
|
|
138
|
+
|
|
47
139
|
headers = {
|
|
48
|
-
"Accept": "application/json, text/plain, */*",
|
|
49
|
-
"X-Requested-With": "XMLHttpRequest",
|
|
50
|
-
"Referer": f"{self.main_url}/"
|
|
140
|
+
"Accept" : "application/json, text/plain, */*",
|
|
141
|
+
"X-Requested-With" : "XMLHttpRequest",
|
|
142
|
+
"Referer" : f"{self.main_url}/"
|
|
51
143
|
}
|
|
52
|
-
|
|
144
|
+
|
|
53
145
|
post_resp = await self.httpx.post(search_url, headers=headers)
|
|
54
|
-
|
|
146
|
+
|
|
55
147
|
try:
|
|
56
|
-
resp_json
|
|
148
|
+
resp_json = post_resp.json()
|
|
57
149
|
response_data = resp_json.get("response")
|
|
58
|
-
|
|
59
|
-
raw_data = base64.b64decode(response_data)
|
|
150
|
+
raw_data = base64.b64decode(response_data)
|
|
60
151
|
try:
|
|
61
152
|
decoded_str = raw_data.decode('utf-8')
|
|
62
153
|
except UnicodeDecodeError:
|
|
63
154
|
decoded_str = raw_data.decode('iso-8859-1').encode('utf-8').decode('utf-8')
|
|
64
|
-
|
|
155
|
+
|
|
65
156
|
search_data = json.loads(decoded_str)
|
|
66
|
-
|
|
157
|
+
|
|
67
158
|
results = []
|
|
68
159
|
for item in search_data.get("result", []):
|
|
69
|
-
title
|
|
70
|
-
slug
|
|
160
|
+
title = item.get("title")
|
|
161
|
+
slug = item.get("slug")
|
|
71
162
|
poster = item.get("poster")
|
|
163
|
+
|
|
72
164
|
if poster:
|
|
73
165
|
poster = self.clean_image_url(poster)
|
|
74
|
-
|
|
166
|
+
|
|
75
167
|
if slug and "/seri-filmler/" not in slug:
|
|
76
168
|
results.append(SearchResult(
|
|
77
|
-
title=title,
|
|
78
|
-
url=self.fix_url(slug),
|
|
79
|
-
poster=poster
|
|
169
|
+
title = title,
|
|
170
|
+
url = self.fix_url(slug),
|
|
171
|
+
poster = poster
|
|
80
172
|
))
|
|
173
|
+
|
|
81
174
|
return results
|
|
82
|
-
|
|
175
|
+
|
|
83
176
|
except Exception:
|
|
84
177
|
return []
|
|
85
178
|
|
|
86
179
|
async def load_item(self, url: str) -> SeriesInfo:
|
|
87
180
|
resp = await self.httpx.get(url)
|
|
88
181
|
sel = Selector(resp.text)
|
|
89
|
-
|
|
182
|
+
|
|
90
183
|
next_data = sel.css("script#__NEXT_DATA__::text").get()
|
|
91
184
|
if not next_data:
|
|
92
185
|
return None
|
|
93
|
-
|
|
94
|
-
data
|
|
95
|
-
secure_data
|
|
96
|
-
raw_data
|
|
186
|
+
|
|
187
|
+
data = json.loads(next_data)
|
|
188
|
+
secure_data = data["props"]["pageProps"]["secureData"]
|
|
189
|
+
raw_data = base64.b64decode(secure_data.replace('"', ''))
|
|
97
190
|
try:
|
|
98
191
|
decoded_str = raw_data.decode('utf-8')
|
|
99
192
|
except UnicodeDecodeError:
|
|
100
193
|
decoded_str = raw_data.decode('iso-8859-1') # .encode('utf-8').decode('utf-8') implied
|
|
101
|
-
|
|
194
|
+
|
|
102
195
|
content_details = json.loads(decoded_str)
|
|
103
|
-
item
|
|
104
|
-
|
|
105
|
-
title
|
|
106
|
-
poster
|
|
107
|
-
description
|
|
108
|
-
rating
|
|
109
|
-
|
|
110
|
-
series_data
|
|
196
|
+
item = content_details.get("contentItem", {})
|
|
197
|
+
|
|
198
|
+
title = item.get("original_title") or item.get("originalTitle")
|
|
199
|
+
poster = self.clean_image_url(item.get("poster_url") or item.get("posterUrl"))
|
|
200
|
+
description = item.get("description") or item.get("used_description")
|
|
201
|
+
rating = str(item.get("imdb_point") or item.get("imdbPoint", ""))
|
|
202
|
+
|
|
203
|
+
series_data = content_details.get("relatedData", {}).get("seriesData")
|
|
111
204
|
if not series_data and "RelatedResults" in content_details:
|
|
112
205
|
series_data = content_details["RelatedResults"].get("getSerieSeasonAndEpisodes", {}).get("result")
|
|
113
206
|
if series_data and isinstance(series_data, list):
|
|
@@ -127,19 +220,19 @@ class SelcukFlix(PluginBase):
|
|
|
127
220
|
ep_list = season.get("episodes", [])
|
|
128
221
|
for ep in ep_list:
|
|
129
222
|
episodes.append(Episode(
|
|
130
|
-
season
|
|
223
|
+
season = s_no,
|
|
131
224
|
episode = ep.get("episode_no") or ep.get("episodeNo"),
|
|
132
|
-
title
|
|
133
|
-
url
|
|
225
|
+
title = ep.get("ep_text") or ep.get("epText"),
|
|
226
|
+
url = self.fix_url(ep.get("used_slug") or ep.get("usedSlug"))
|
|
134
227
|
))
|
|
135
228
|
|
|
136
229
|
return SeriesInfo(
|
|
137
|
-
title=title,
|
|
138
|
-
url=url,
|
|
139
|
-
poster=poster,
|
|
140
|
-
description=description,
|
|
141
|
-
rating=rating,
|
|
142
|
-
episodes=episodes
|
|
230
|
+
title = title,
|
|
231
|
+
url = url,
|
|
232
|
+
poster = poster,
|
|
233
|
+
description = description,
|
|
234
|
+
rating = rating,
|
|
235
|
+
episodes = episodes
|
|
143
236
|
)
|
|
144
237
|
|
|
145
238
|
async def load_links(self, url: str) -> list[dict]:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
2
|
|
|
3
|
-
from KekikStream.Core import
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, SeriesInfo, Episode
|
|
4
4
|
from parsel import Selector
|
|
5
5
|
|
|
6
6
|
class SezonlukDizi(PluginBase):
|
|
@@ -99,7 +99,6 @@ class SezonlukDizi(PluginBase):
|
|
|
99
99
|
actors = actors
|
|
100
100
|
)
|
|
101
101
|
|
|
102
|
-
#@kekik_cache(ttl=15*60)
|
|
103
102
|
async def load_links(self, url: str) -> list[dict]:
|
|
104
103
|
istek = await self.httpx.get(url)
|
|
105
104
|
secici = Selector(istek.text)
|
KekikStream/Plugins/SineWix.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
2
|
|
|
3
|
-
from KekikStream.Core import
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, Episode, SeriesInfo, ExtractResult, Subtitle
|
|
4
4
|
import json
|
|
5
5
|
|
|
6
6
|
class SineWix(PluginBase):
|
|
@@ -123,7 +123,6 @@ class SineWix(PluginBase):
|
|
|
123
123
|
episodes = episodes,
|
|
124
124
|
)
|
|
125
125
|
|
|
126
|
-
#@kekik_cache(ttl=15*60)
|
|
127
126
|
async def load_links(self, url: str) -> list[dict]:
|
|
128
127
|
try:
|
|
129
128
|
veri = json.loads(url)
|
KekikStream/Plugins/Sinefy.py
CHANGED
|
@@ -5,74 +5,95 @@ from parsel import Selector
|
|
|
5
5
|
import re, json, urllib.parse
|
|
6
6
|
|
|
7
7
|
class Sinefy(PluginBase):
|
|
8
|
-
name
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
name = "Sinefy"
|
|
9
|
+
language = "tr"
|
|
10
|
+
main_url = "https://sinefy3.com"
|
|
11
|
+
favicon = f"https://www.google.com/s2/favicons?domain={main_url}&sz=64"
|
|
12
|
+
description = "Yabancı film izle olarak vizyondaki en yeni yabancı filmleri türkçe dublaj ve altyazılı olarak en hızlı şekilde full hd olarak sizlere sunuyoruz."
|
|
13
|
+
|
|
12
14
|
main_page = {
|
|
13
|
-
"page/"
|
|
14
|
-
"en-yenifilmler"
|
|
15
|
-
"netflix-filmleri-izle"
|
|
16
|
-
"dizi-izle/netflix"
|
|
15
|
+
f"{main_url}/page/" : "Son Eklenenler",
|
|
16
|
+
f"{main_url}/en-yenifilmler" : "Yeni Filmler",
|
|
17
|
+
f"{main_url}/netflix-filmleri-izle" : "Netflix Filmleri",
|
|
18
|
+
f"{main_url}/dizi-izle/netflix" : "Netflix Dizileri",
|
|
19
|
+
f"{main_url}/gozat/filmler/animasyon" : "Animasyon",
|
|
20
|
+
f"{main_url}/gozat/filmler/komedi" : "Komedi",
|
|
21
|
+
f"{main_url}/gozat/filmler/suc" : "Suç",
|
|
22
|
+
f"{main_url}/gozat/filmler/aile" : "Aile",
|
|
23
|
+
f"{main_url}/gozat/filmler/aksiyon" : "Aksiyon",
|
|
24
|
+
f"{main_url}/gozat/filmler/macera" : "Macera",
|
|
25
|
+
f"{main_url}/gozat/filmler/fantastik" : "Fantastik",
|
|
26
|
+
f"{main_url}/gozat/filmler/korku" : "Korku",
|
|
27
|
+
f"{main_url}/gozat/filmler/romantik" : "Romantik",
|
|
28
|
+
f"{main_url}/gozat/filmler/savas" : "Savaş",
|
|
29
|
+
f"{main_url}/gozat/filmler/gerilim" : "Gerilim",
|
|
30
|
+
f"{main_url}/gozat/filmler/bilim-kurgu" : "Bilim Kurgu",
|
|
31
|
+
f"{main_url}/gozat/filmler/dram" : "Dram",
|
|
32
|
+
f"{main_url}/gozat/filmler/gizem" : "Gizem",
|
|
33
|
+
f"{main_url}/gozat/filmler/western" : "Western",
|
|
34
|
+
f"{main_url}/gozat/filmler/ulke/turkiye" : "Türk Filmleri",
|
|
35
|
+
f"{main_url}/gozat/filmler/ulke/kore" : "Kore Filmleri"
|
|
17
36
|
}
|
|
18
37
|
|
|
19
38
|
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
20
39
|
if "page/" in url:
|
|
21
|
-
full_url = f"{
|
|
40
|
+
full_url = f"{url}{page}"
|
|
22
41
|
elif "en-yenifilmler" in url or "netflix" in url:
|
|
23
|
-
full_url = f"{
|
|
42
|
+
full_url = f"{url}/{page}"
|
|
24
43
|
else:
|
|
25
|
-
full_url = f"{
|
|
26
|
-
|
|
44
|
+
full_url = f"{url}&page={page}"
|
|
45
|
+
|
|
27
46
|
resp = await self.httpx.get(full_url)
|
|
28
|
-
sel
|
|
29
|
-
|
|
47
|
+
sel = Selector(resp.text)
|
|
48
|
+
|
|
30
49
|
results = []
|
|
31
50
|
# Kotlin: div.poster-with-subject, div.dark-segment div.poster-md.poster
|
|
32
51
|
for item in sel.css("div.poster-with-subject, div.dark-segment div.poster-md.poster"):
|
|
33
|
-
title
|
|
34
|
-
href
|
|
35
|
-
poster= item.css("img::attr(data-srcset)").get()
|
|
52
|
+
title = item.css("h2::text").get()
|
|
53
|
+
href = item.css("a::attr(href)").get()
|
|
54
|
+
poster = item.css("img::attr(data-srcset)").get()
|
|
36
55
|
if poster:
|
|
37
56
|
poster = poster.split(",")[0].split(" ")[0]
|
|
38
|
-
|
|
57
|
+
|
|
39
58
|
if title and href:
|
|
40
59
|
results.append(MainPageResult(
|
|
41
|
-
category=category,
|
|
42
|
-
title=title,
|
|
43
|
-
url=self.fix_url(href),
|
|
44
|
-
poster=self.fix_url(poster)
|
|
60
|
+
category = category,
|
|
61
|
+
title = title,
|
|
62
|
+
url = self.fix_url(href),
|
|
63
|
+
poster = self.fix_url(poster)
|
|
45
64
|
))
|
|
65
|
+
|
|
46
66
|
return results
|
|
47
67
|
|
|
48
68
|
async def search(self, query: str) -> list[SearchResult]:
|
|
49
69
|
# Try to get dynamic keys from main page first
|
|
50
|
-
c_key
|
|
70
|
+
c_key = "ca1d4a53d0f4761a949b85e51e18f096"
|
|
51
71
|
c_value = "MTc0NzI2OTAwMDU3ZTEwYmZjMDViNWFmOWIwZDViODg0MjU4MjA1ZmYxOThmZTYwMDdjMWQzMzliNzY5NzFlZmViMzRhMGVmNjgwODU3MGIyZA=="
|
|
52
|
-
|
|
72
|
+
|
|
53
73
|
try:
|
|
54
74
|
resp = await self.httpx.get(self.main_url)
|
|
55
|
-
sel
|
|
56
|
-
cke
|
|
75
|
+
sel = Selector(resp.text)
|
|
76
|
+
cke = sel.css("input[name='cKey']::attr(value)").get()
|
|
57
77
|
cval = sel.css("input[name='cValue']::attr(value)").get()
|
|
58
78
|
if cke and cval:
|
|
59
|
-
c_key
|
|
79
|
+
c_key = cke
|
|
60
80
|
c_value = cval
|
|
81
|
+
|
|
61
82
|
except Exception:
|
|
62
83
|
pass
|
|
63
84
|
|
|
64
85
|
post_url = f"{self.main_url}/bg/searchcontent"
|
|
65
86
|
data = {
|
|
66
|
-
"cKey": c_key,
|
|
67
|
-
"cValue": c_value,
|
|
68
|
-
"searchTerm": query
|
|
87
|
+
"cKey" : c_key,
|
|
88
|
+
"cValue" : c_value,
|
|
89
|
+
"searchTerm" : query
|
|
69
90
|
}
|
|
70
91
|
|
|
71
92
|
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"
|
|
93
|
+
"User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:134.0) Gecko/20100101 Firefox/134.0",
|
|
94
|
+
"Accept" : "application/json, text/javascript, */*; q=0.01",
|
|
95
|
+
"X-Requested-With" : "XMLHttpRequest",
|
|
96
|
+
"Content-Type" : "application/x-www-form-urlencoded; charset=UTF-8"
|
|
76
97
|
}
|
|
77
98
|
|
|
78
99
|
response = await self.httpx.post(post_url, data=data, headers=headers)
|
|
@@ -179,24 +200,24 @@ class Sinefy(PluginBase):
|
|
|
179
200
|
|
|
180
201
|
if episodes:
|
|
181
202
|
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
|
|
203
|
+
title = title,
|
|
204
|
+
url = url,
|
|
205
|
+
poster = self.fix_url(poster),
|
|
206
|
+
description = description,
|
|
207
|
+
rating = rating,
|
|
208
|
+
tags = tags,
|
|
209
|
+
actors = actors,
|
|
210
|
+
episodes = episodes
|
|
190
211
|
)
|
|
191
212
|
else:
|
|
192
213
|
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
|
|
214
|
+
title = title,
|
|
215
|
+
url = url,
|
|
216
|
+
poster = self.fix_url(poster),
|
|
217
|
+
description = description,
|
|
218
|
+
rating = rating,
|
|
219
|
+
tags = tags,
|
|
220
|
+
actors = actors
|
|
200
221
|
)
|
|
201
222
|
|
|
202
223
|
async def load_links(self, url: str) -> list[dict]:
|
|
@@ -208,7 +229,7 @@ class Sinefy(PluginBase):
|
|
|
208
229
|
iframe = self.fix_url(iframe)
|
|
209
230
|
extractor = self.ex_manager.find_extractor(iframe)
|
|
210
231
|
return [{
|
|
211
|
-
"url": iframe,
|
|
212
|
-
"name": extractor.name if extractor else "Iframe"
|
|
232
|
+
"url" : iframe,
|
|
233
|
+
"name" : extractor.name if extractor else "Iframe"
|
|
213
234
|
}]
|
|
214
235
|
return []
|
KekikStream/Plugins/Sinezy.py
CHANGED
|
@@ -5,95 +5,127 @@ from parsel import Selector
|
|
|
5
5
|
import re, base64
|
|
6
6
|
|
|
7
7
|
class Sinezy(PluginBase):
|
|
8
|
-
name
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
8
|
+
name = "Sinezy"
|
|
9
|
+
language = "tr"
|
|
10
|
+
main_url = "https://sinezy.fit"
|
|
11
|
+
favicon = f"https://www.google.com/s2/favicons?domain={main_url}&sz=64"
|
|
12
|
+
description = "Yerli ve yabancı film izle! Türkçe Dublaj ve Alt Yazılı Seçenekleriyle full hd film izlemek için En çok tercih edilen adres!"
|
|
13
|
+
|
|
12
14
|
main_page = {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
+
f"{main_url}/izle/en-yeni-filmler/" : "Yeni Filmler",
|
|
16
|
+
f"{main_url}/izle/en-yi-filmler/" : "En İyi Filmler",
|
|
17
|
+
f"{main_url}/izle/aksiyon-filmleri/" : "Aksiyon ",
|
|
18
|
+
f"{main_url}/izle/animasyon-filmleri/" : "Animasyon",
|
|
19
|
+
f"{main_url}/izle/belgesel-izle/" : "Belgesel",
|
|
20
|
+
f"{main_url}/izle/bilim-kurgu-filmleri/" : "Bilim Kurgu ",
|
|
21
|
+
f"{main_url}/izle/biyografi-filmleri/" : "Biyografi ",
|
|
22
|
+
f"{main_url}/izle/dram-filmleri/" : "Dram",
|
|
23
|
+
f"{main_url}/izle/erotik-film-izle/" : "Erotik ",
|
|
24
|
+
f"{main_url}/izle/fantastik-filmler/" : "Fantastik",
|
|
25
|
+
f"{main_url}/izle/gelecek-filmler/" : "Yakında",
|
|
26
|
+
f"{main_url}/izle/gerilim-filmleri/" : "Gerilim ",
|
|
27
|
+
f"{main_url}/izle/gizem-filmleri/" : "Gizem ",
|
|
28
|
+
f"{main_url}/izle/komedi-filmleri/" : "Komedi ",
|
|
29
|
+
f"{main_url}/izle/korku-filmleri/" : "Korku ",
|
|
30
|
+
f"{main_url}/izle/macera-filmleri/" : "Macera ",
|
|
31
|
+
f"{main_url}/izle/muzikal-izle/" : "Müzikal",
|
|
32
|
+
f"{main_url}/izle/romantik-film/" : "Romantik ",
|
|
33
|
+
f"{main_url}/izle/savas-filmleri/" : "Savaş ",
|
|
34
|
+
f"{main_url}/izle/spor-filmleri/" : "Spor ",
|
|
35
|
+
f"{main_url}/izle/suc-filmleri/" : "Suç ",
|
|
36
|
+
f"{main_url}/izle/tarih-filmleri/" : "Tarih ",
|
|
37
|
+
f"{main_url}/izle/turkce-altyazili-promo/" : "Altyazılı Pro",
|
|
38
|
+
f"{main_url}/izle/yabanci-dizi/" : "Yabancı Dizi",
|
|
39
|
+
f"{main_url}/izle/en-iyi-filmler/" : "En İyi Filmler",
|
|
40
|
+
f"{main_url}/izle/en-yeni-filmler/" : "Yeni Filmler",
|
|
41
|
+
f"{main_url}/izle/yerli-filmler/" : "Yerli Filmler",
|
|
42
|
+
f"{main_url}/izle/yetiskin-film/" : "Yetişkin +18",
|
|
15
43
|
}
|
|
16
44
|
|
|
17
45
|
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
18
|
-
full_url = f"{
|
|
19
|
-
resp
|
|
20
|
-
sel
|
|
46
|
+
full_url = f"{url}page/{page}/"
|
|
47
|
+
resp = await self.httpx.get(full_url)
|
|
48
|
+
sel = Selector(resp.text)
|
|
21
49
|
|
|
22
50
|
results = []
|
|
23
51
|
for item in sel.css("div.container div.content div.movie_box.move_k"):
|
|
24
|
-
title
|
|
25
|
-
href
|
|
26
|
-
poster= item.css("img::attr(data-src)").get()
|
|
52
|
+
title = item.css("a::attr(title)").get()
|
|
53
|
+
href = item.css("a::attr(href)").get()
|
|
54
|
+
poster = item.css("img::attr(data-src)").get()
|
|
27
55
|
|
|
28
56
|
if title and href:
|
|
29
57
|
results.append(MainPageResult(
|
|
30
|
-
category=category,
|
|
31
|
-
title=title,
|
|
32
|
-
url=self.fix_url(href),
|
|
33
|
-
poster=self.fix_url(poster)
|
|
58
|
+
category = category,
|
|
59
|
+
title = title,
|
|
60
|
+
url = self.fix_url(href),
|
|
61
|
+
poster = self.fix_url(poster)
|
|
34
62
|
))
|
|
63
|
+
|
|
35
64
|
return results
|
|
36
65
|
|
|
37
66
|
async def search(self, query: str) -> list[SearchResult]:
|
|
38
|
-
url
|
|
67
|
+
url = f"{self.main_url}/arama/?s={query}"
|
|
39
68
|
resp = await self.httpx.get(url)
|
|
40
|
-
sel
|
|
41
|
-
|
|
69
|
+
sel = Selector(resp.text)
|
|
70
|
+
|
|
42
71
|
results = []
|
|
43
72
|
for item in sel.css("div.movie_box.move_k"):
|
|
44
|
-
title
|
|
45
|
-
href
|
|
46
|
-
poster= item.css("img::attr(data-src)").get()
|
|
47
|
-
|
|
73
|
+
title = item.css("a::attr(title)").get()
|
|
74
|
+
href = item.css("a::attr(href)").get()
|
|
75
|
+
poster = item.css("img::attr(data-src)").get()
|
|
76
|
+
|
|
48
77
|
if title and href:
|
|
49
78
|
results.append(SearchResult(
|
|
50
|
-
title=title,
|
|
51
|
-
url=self.fix_url(href),
|
|
52
|
-
poster=self.fix_url(poster)
|
|
79
|
+
title = title,
|
|
80
|
+
url = self.fix_url(href),
|
|
81
|
+
poster = self.fix_url(poster)
|
|
53
82
|
))
|
|
83
|
+
|
|
54
84
|
return results
|
|
55
85
|
|
|
56
86
|
async def load_item(self, url: str) -> MovieInfo:
|
|
57
87
|
resp = await self.httpx.get(url)
|
|
58
88
|
sel = Selector(resp.text)
|
|
59
|
-
|
|
89
|
+
|
|
60
90
|
title = sel.css("div.detail::attr(title)").get()
|
|
61
91
|
poster = sel.css("div.move_k img::attr(data-src)").get()
|
|
62
92
|
description = sel.css("div.desc.yeniscroll p::text").get()
|
|
63
93
|
rating = sel.css("span.info span.imdb::text").get()
|
|
64
|
-
|
|
65
|
-
tags
|
|
66
|
-
actors = sel.css("span.oyn p::text").getall()
|
|
67
|
-
|
|
94
|
+
|
|
95
|
+
tags = sel.css("div.detail span a::text").getall()
|
|
96
|
+
actors = sel.css("span.oyn p::text").getall() # Might need splitting logic
|
|
97
|
+
|
|
68
98
|
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
|
|
99
|
+
title = title,
|
|
100
|
+
url = url,
|
|
101
|
+
poster = self.fix_url(poster),
|
|
102
|
+
description = description,
|
|
103
|
+
tags = tags,
|
|
104
|
+
rating = rating,
|
|
105
|
+
actors = actors
|
|
76
106
|
)
|
|
77
107
|
|
|
78
108
|
async def load_links(self, url: str) -> list[dict]:
|
|
79
109
|
resp = await self.httpx.get(url)
|
|
80
|
-
|
|
110
|
+
|
|
81
111
|
match = re.search(r"ilkpartkod\s*=\s*'([^']+)'", resp.text, re.IGNORECASE)
|
|
82
112
|
if match:
|
|
83
113
|
encoded = match.group(1)
|
|
84
114
|
try:
|
|
85
115
|
decoded = base64.b64decode(encoded).decode('utf-8')
|
|
86
116
|
iframe_match = re.search(r'src="([^"]*)"', decoded)
|
|
117
|
+
|
|
87
118
|
if iframe_match:
|
|
88
119
|
iframe = iframe_match.group(1)
|
|
89
120
|
iframe = self.fix_url(iframe)
|
|
90
121
|
|
|
91
122
|
extractor = self.ex_manager.find_extractor(iframe)
|
|
123
|
+
|
|
92
124
|
return [{
|
|
93
|
-
"url": iframe,
|
|
94
|
-
"name": extractor.name if extractor else "Iframe"
|
|
125
|
+
"url" : iframe,
|
|
126
|
+
"name" : extractor.name if extractor else "Iframe"
|
|
95
127
|
}]
|
|
96
128
|
except Exception:
|
|
97
129
|
pass
|
|
98
|
-
|
|
130
|
+
|
|
99
131
|
return []
|
KekikStream/Plugins/UgurFilm.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
2
|
|
|
3
|
-
from KekikStream.Core import
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo
|
|
4
4
|
from parsel import Selector
|
|
5
5
|
|
|
6
6
|
class UgurFilm(PluginBase):
|
|
@@ -79,7 +79,6 @@ class UgurFilm(PluginBase):
|
|
|
79
79
|
actors = actors,
|
|
80
80
|
)
|
|
81
81
|
|
|
82
|
-
#@kekik_cache(ttl=15*60)
|
|
83
82
|
async def load_links(self, url: str) -> list[dict]:
|
|
84
83
|
istek = await self.httpx.get(url)
|
|
85
84
|
secici = Selector(istek.text)
|
KekikStream/requirements.txt
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: KekikStream
|
|
3
|
-
Version: 1.8.
|
|
3
|
+
Version: 1.8.5
|
|
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
|
|
@@ -17,7 +17,6 @@ Requires-Dist: setuptools
|
|
|
17
17
|
Requires-Dist: wheel
|
|
18
18
|
Requires-Dist: Kekik
|
|
19
19
|
Requires-Dist: httpx
|
|
20
|
-
Requires-Dist: curl-cffi
|
|
21
20
|
Requires-Dist: cloudscraper
|
|
22
21
|
Requires-Dist: parsel
|
|
23
22
|
Requires-Dist: pydantic
|
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
KekikStream/__init__.py,sha256=JcSKsLRyJM5ZPNHq4DLSaj4FzOjxSp8M8JuM3YN8Ye4,13456
|
|
2
2
|
KekikStream/__main__.py,sha256=B81dQoeGEb-T5Sycs3eNAmW7unvx0Mef0syCjs4nPds,137
|
|
3
|
-
KekikStream/requirements.txt,sha256=
|
|
3
|
+
KekikStream/requirements.txt,sha256=0fO-7byqgLMr4NyJO7fQBFOnLv0zcAeqk7tLhHXqonk,76
|
|
4
4
|
KekikStream/CLI/__init__.py,sha256=U6oLq_O7u5y2eHhBnmfhZNns_EqHHJXJmzl8jvZFUNY,230
|
|
5
5
|
KekikStream/CLI/pypi_kontrol.py,sha256=q6fNs6EKJDc5VuUFig9DBzLzNPp_kMD1vOVgLElcii8,1487
|
|
6
6
|
KekikStream/Core/__init__.py,sha256=ar2MZQF83ryfLfydEXcfjdwNe4Too_HT6bP-D_4TopA,710
|
|
7
|
-
KekikStream/Core/Extractor/ExtractorBase.py,sha256=
|
|
7
|
+
KekikStream/Core/Extractor/ExtractorBase.py,sha256=Yj7CGvm2ZKxlvuUkZu0X1Pl0JMH250W7hyqv09duTmE,1637
|
|
8
8
|
KekikStream/Core/Extractor/ExtractorLoader.py,sha256=7uxUXTAuF65KKkmbI6iRiCiUhx-IqrronB7ixhchcTU,4289
|
|
9
9
|
KekikStream/Core/Extractor/ExtractorManager.py,sha256=4L1H3jiTnf0kTq4W6uS7n95bBYHlKJ8_hh0og8z4erQ,1244
|
|
10
10
|
KekikStream/Core/Extractor/ExtractorModels.py,sha256=Qj_gbIeGRewaZXNfYkTi4FFRRq6XBOc0HS0tXGDwajI,445
|
|
11
11
|
KekikStream/Core/Media/MediaHandler.py,sha256=taLA3rXsN_VfNn7nIc_OZKaaif8kuEZznhH_EaOiQQk,6874
|
|
12
12
|
KekikStream/Core/Media/MediaManager.py,sha256=AaUq2D7JSJIphjoAj2fjLOJjswm7Qf5hjYCbBdrbnDU,438
|
|
13
|
-
KekikStream/Core/Plugin/PluginBase.py,sha256=
|
|
13
|
+
KekikStream/Core/Plugin/PluginBase.py,sha256=uzJb8DqJfXOteteSBhG9QWUrFgb4JTByV_GbODz-9gs,3872
|
|
14
14
|
KekikStream/Core/Plugin/PluginLoader.py,sha256=yZxMug-OcJ5RBm4fQkoquKrZxcBU7Pvt4IcY-d0WU8g,3393
|
|
15
15
|
KekikStream/Core/Plugin/PluginManager.py,sha256=CZVg1eegi8vfMfccx0DRV0Box8kXz-aoULTQLgbPbvM,893
|
|
16
16
|
KekikStream/Core/Plugin/PluginModels.py,sha256=Yvx-6Fkn8QCIcuqAkFbCP5EJcq3XBkK_P8S0tRNhS6E,2476
|
|
@@ -55,31 +55,31 @@ KekikStream/Extractors/VidMoxy.py,sha256=LT7wTKBtuuagXwfGjWZwQF2NQGuChurZJ-I6gM0
|
|
|
55
55
|
KekikStream/Extractors/VidPapi.py,sha256=g9ohdL9VJrxy4N7xerbIRz3ZxjsXFHlJWy0NaZ31hFY,3259
|
|
56
56
|
KekikStream/Extractors/VideoSeyred.py,sha256=M6QPZ_isX9vM_7LPo-2I_8Cf1vB9awHw8vvzBODtoiQ,1977
|
|
57
57
|
KekikStream/Extractors/YildizKisaFilm.py,sha256=R_JlrOVeMiDlXYcuTdItnKvidyx8_u3B14fSrxew2aE,1316
|
|
58
|
-
KekikStream/Plugins/DiziBox.py,sha256=
|
|
58
|
+
KekikStream/Plugins/DiziBox.py,sha256=sxM7ckKeKwMrMkRNUAvh5wE9wdOuVda6Ag_zAdwSvi8,9935
|
|
59
59
|
KekikStream/Plugins/DiziPal.py,sha256=MBONjermWBm3sN-8ZSILnfXI2F_V2kH65gpTNOuL9dI,10198
|
|
60
|
-
KekikStream/Plugins/DiziYou.py,sha256=
|
|
61
|
-
KekikStream/Plugins/Dizilla.py,sha256=
|
|
60
|
+
KekikStream/Plugins/DiziYou.py,sha256=xE0INtCLOZDo73sWQoYT6Su8T66hGK9rBD-gXnk8MiU,9016
|
|
61
|
+
KekikStream/Plugins/Dizilla.py,sha256=jDklWkUrrAGhDO9pMvgIXVcKdSHDHlguu0JgifM7Bx8,11546
|
|
62
62
|
KekikStream/Plugins/FilmBip.py,sha256=Tfx2dUc1Qs7ZQoJtsBtjOJXCKmTe56m74lNhuUYYU14,6182
|
|
63
|
-
KekikStream/Plugins/FilmMakinesi.py,sha256=
|
|
63
|
+
KekikStream/Plugins/FilmMakinesi.py,sha256=izPKGbqQuA6AmLAnFjlBoe8iwnNOrr0Pcy5L2dZfM78,5185
|
|
64
64
|
KekikStream/Plugins/FilmModu.py,sha256=b27hchMoYZwG3I-kM1sveW7rHKOF5OuepdjPgKIehEM,6706
|
|
65
65
|
KekikStream/Plugins/FullHDFilm.py,sha256=kkb-JtWf23uiEzP9f_uds0tROYiKOyxcX0D-jNtQFi0,7005
|
|
66
|
-
KekikStream/Plugins/FullHDFilmizlesene.py,sha256=
|
|
67
|
-
KekikStream/Plugins/HDFilmCehennemi.py,sha256=
|
|
68
|
-
KekikStream/Plugins/JetFilmizle.py,sha256=
|
|
66
|
+
KekikStream/Plugins/FullHDFilmizlesene.py,sha256=FAacwtXo72DIl_1bHWgHPIxqmqBJAVPtNQ3yIZPYjlU,6152
|
|
67
|
+
KekikStream/Plugins/HDFilmCehennemi.py,sha256=D2VvgNvCcHfjkitzSfA19OFp-mI0sgUm6OSVej0ZgTY,9544
|
|
68
|
+
KekikStream/Plugins/JetFilmizle.py,sha256=3tcx4ZT7oQs_xolhQeiqgirpWtknBjP7J7Qgy0bvIeM,5963
|
|
69
69
|
KekikStream/Plugins/KultFilmler.py,sha256=VZET3RUoOVYKE-C2YbkMW8oNcxz6zE2pR7a3z-B4nD4,8987
|
|
70
|
-
KekikStream/Plugins/RecTV.py,sha256=
|
|
71
|
-
KekikStream/Plugins/RoketDizi.py,sha256=
|
|
72
|
-
KekikStream/Plugins/SelcukFlix.py,sha256=
|
|
73
|
-
KekikStream/Plugins/SezonlukDizi.py,sha256=
|
|
74
|
-
KekikStream/Plugins/SineWix.py,sha256=
|
|
75
|
-
KekikStream/Plugins/Sinefy.py,sha256=
|
|
70
|
+
KekikStream/Plugins/RecTV.py,sha256=dF3Ogf7KE_zpfLQRjVcEJQMuWtBtHo6iB73_ECQEJ58,7544
|
|
71
|
+
KekikStream/Plugins/RoketDizi.py,sha256=isVijJ6YRtsBQ6DVB2K3n6uV-1GXZahujLF7IWvBrqs,8472
|
|
72
|
+
KekikStream/Plugins/SelcukFlix.py,sha256=WYVtGMxngpqrXk7PX_B4ya6Pji7dOjQsXoukk30f2d0,12744
|
|
73
|
+
KekikStream/Plugins/SezonlukDizi.py,sha256=dT2xPPkdaYV43qsL4Le_5Yel8eoPkHtnXIOXqz-Ya-c,6326
|
|
74
|
+
KekikStream/Plugins/SineWix.py,sha256=xdTeg8GHUpyZsY6EQ5I1ZIT4-lB_qwBwvHQVmdMPpEI,7364
|
|
75
|
+
KekikStream/Plugins/Sinefy.py,sha256=YMwG7ykdjzAY_GEvV4xv9NJ6ubew7qeMLz4KkvYpaNk,9749
|
|
76
76
|
KekikStream/Plugins/SinemaCX.py,sha256=DUvYa7J4a2D5ivLO_sQiaStoV5FDxmz8onJyFwAidvY,7177
|
|
77
|
-
KekikStream/Plugins/Sinezy.py,sha256=
|
|
77
|
+
KekikStream/Plugins/Sinezy.py,sha256=EttAZogKoKMP8RP_X1fSfi8vVxA2RWizwgnLkmnhERQ,5675
|
|
78
78
|
KekikStream/Plugins/SuperFilmGeldi.py,sha256=Ohm21BPsJH_S1tx5i2APEgAOD25k2NiwRP7rSgAKvRs,5289
|
|
79
|
-
KekikStream/Plugins/UgurFilm.py,sha256=
|
|
80
|
-
kekikstream-1.8.
|
|
81
|
-
kekikstream-1.8.
|
|
82
|
-
kekikstream-1.8.
|
|
83
|
-
kekikstream-1.8.
|
|
84
|
-
kekikstream-1.8.
|
|
85
|
-
kekikstream-1.8.
|
|
79
|
+
KekikStream/Plugins/UgurFilm.py,sha256=eKGzmSi8k_QbXnYPWXZRdmCxxc32zZh4rynmdxCbm1o,4832
|
|
80
|
+
kekikstream-1.8.5.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
81
|
+
kekikstream-1.8.5.dist-info/METADATA,sha256=PA0T8ikorAFyFbYMnmhrz3dJIpkHYUQAc5DSXtvx0ek,4958
|
|
82
|
+
kekikstream-1.8.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
83
|
+
kekikstream-1.8.5.dist-info/entry_points.txt,sha256=dFwdiTx8djyehI0Gsz-rZwjAfZzUzoBSrmzRu9ubjJc,50
|
|
84
|
+
kekikstream-1.8.5.dist-info/top_level.txt,sha256=DNmGJDXl27Drdfobrak8KYLmocW_uznVYFJOzcjUgmY,12
|
|
85
|
+
kekikstream-1.8.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|