KekikStream 2.4.8__py3-none-any.whl → 2.4.9__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of KekikStream might be problematic. Click here for more details.
- KekikStream/Extractors/JetV.py +55 -0
- KekikStream/Extractors/Veev.py +145 -0
- KekikStream/Extractors/VidBiz.py +62 -0
- KekikStream/Extractors/VidHide.py +56 -7
- KekikStream/Extractors/Vtbe.py +38 -0
- KekikStream/Extractors/Zeus.py +61 -0
- KekikStream/Plugins/HDFilmCehennemi.py +37 -14
- KekikStream/Plugins/JetFilmizle.py +82 -49
- {kekikstream-2.4.8.dist-info → kekikstream-2.4.9.dist-info}/METADATA +1 -1
- {kekikstream-2.4.8.dist-info → kekikstream-2.4.9.dist-info}/RECORD +14 -9
- {kekikstream-2.4.8.dist-info → kekikstream-2.4.9.dist-info}/WHEEL +0 -0
- {kekikstream-2.4.8.dist-info → kekikstream-2.4.9.dist-info}/entry_points.txt +0 -0
- {kekikstream-2.4.8.dist-info → kekikstream-2.4.9.dist-info}/licenses/LICENSE +0 -0
- {kekikstream-2.4.8.dist-info → kekikstream-2.4.9.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
|
+
|
|
3
|
+
from KekikStream.Core import ExtractorBase, ExtractResult, HTMLHelper
|
|
4
|
+
import json, re
|
|
5
|
+
|
|
6
|
+
class JetV(ExtractorBase):
|
|
7
|
+
name = "JetV"
|
|
8
|
+
main_url = "https://jetv.xyz"
|
|
9
|
+
|
|
10
|
+
async def extract(self, url: str, referer: str = None) -> list[ExtractResult]:
|
|
11
|
+
istek = await self.httpx.get(url, headers={"Referer": referer} if referer else None)
|
|
12
|
+
text = istek.text
|
|
13
|
+
|
|
14
|
+
# Script içindeki sources kısmını bul
|
|
15
|
+
# "sources": [ ... ]
|
|
16
|
+
sources_str = HTMLHelper(text).regex_first(r'"sources":\s*(\[.*?\])')
|
|
17
|
+
if not sources_str:
|
|
18
|
+
# Altenatif: sources: [ ... ] (tırnaksız sources)
|
|
19
|
+
sources_str = HTMLHelper(text).regex_first(r'sources:\s*(\[.*?\])')
|
|
20
|
+
|
|
21
|
+
if not sources_str:
|
|
22
|
+
raise ValueError(f"JetV: Sources bulunamadı. {url}")
|
|
23
|
+
|
|
24
|
+
# file: -> "file":
|
|
25
|
+
clean_json = re.sub(r'(\w+):', r'"\1":', sources_str)
|
|
26
|
+
# ' -> "
|
|
27
|
+
clean_json = clean_json.replace("'", '"')
|
|
28
|
+
|
|
29
|
+
try:
|
|
30
|
+
sources = json.loads(clean_json)
|
|
31
|
+
except:
|
|
32
|
+
# Basit parser yetmediyse, manuel parse deneyelim (tek kaynak varsa)
|
|
33
|
+
file_url = HTMLHelper(sources_str).regex_first(r'file["\']?:\s*["\']([^"\']+)["\']')
|
|
34
|
+
label = HTMLHelper(sources_str).regex_first(r'label["\']?:\s*["\']([^"\']+)["\']')
|
|
35
|
+
if file_url:
|
|
36
|
+
sources = [{"file": file_url, "label": label or "Unknown"}]
|
|
37
|
+
else:
|
|
38
|
+
raise ValueError("JetV: JSON parse hatası")
|
|
39
|
+
|
|
40
|
+
results = []
|
|
41
|
+
for source in sources:
|
|
42
|
+
file_path = source.get("file")
|
|
43
|
+
label = source.get("label", "Unknown")
|
|
44
|
+
|
|
45
|
+
if not file_path:
|
|
46
|
+
continue
|
|
47
|
+
|
|
48
|
+
results.append(ExtractResult(
|
|
49
|
+
name = f"{self.name} | {label}",
|
|
50
|
+
url = self.fix_url(file_path),
|
|
51
|
+
referer = url,
|
|
52
|
+
user_agent = self.httpx.headers.get("User-Agent", "")
|
|
53
|
+
))
|
|
54
|
+
|
|
55
|
+
return results
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
|
+
|
|
3
|
+
from KekikStream.Core import ExtractorBase, ExtractResult, HTMLHelper
|
|
4
|
+
from contextlib import suppress
|
|
5
|
+
|
|
6
|
+
class Veev(ExtractorBase):
|
|
7
|
+
name = "Veev"
|
|
8
|
+
main_url = "https://veev.to"
|
|
9
|
+
|
|
10
|
+
supported_domains = ["veev.to", "kinoger.to", "poophq.com", "doods.pro", "dood.so", "dood.li", "dood.wf", "dood.cx", "dood.sh", "dood.watch", "dood.pm", "dood.to", "dood.ws"]
|
|
11
|
+
|
|
12
|
+
def can_handle_url(self, url: str) -> bool:
|
|
13
|
+
return any(domain in url for domain in self.supported_domains)
|
|
14
|
+
|
|
15
|
+
def veev_decode(self, encoded: str) -> str:
|
|
16
|
+
if not encoded:
|
|
17
|
+
return ""
|
|
18
|
+
|
|
19
|
+
result = []
|
|
20
|
+
# Python dictionary key integer, value string
|
|
21
|
+
# Başlangıçta 0-255 ascii karakterleri
|
|
22
|
+
lut = {i: chr(i) for i in range(256)}
|
|
23
|
+
n = 256
|
|
24
|
+
|
|
25
|
+
c = encoded[0]
|
|
26
|
+
result.append(c)
|
|
27
|
+
|
|
28
|
+
for char in encoded[1:]:
|
|
29
|
+
code = ord(char)
|
|
30
|
+
if code < 256:
|
|
31
|
+
nc = char
|
|
32
|
+
else:
|
|
33
|
+
nc = lut.get(code, c + c[0])
|
|
34
|
+
|
|
35
|
+
result.append(nc)
|
|
36
|
+
lut[n] = c + nc[0]
|
|
37
|
+
n += 1
|
|
38
|
+
c = nc
|
|
39
|
+
|
|
40
|
+
return "".join(result)
|
|
41
|
+
|
|
42
|
+
def build_array(self, encoded: str) -> list[list[int]]:
|
|
43
|
+
result = []
|
|
44
|
+
iterator = iter(encoded)
|
|
45
|
+
|
|
46
|
+
def next_int_or_zero():
|
|
47
|
+
try:
|
|
48
|
+
char = next(iterator)
|
|
49
|
+
if char.isdigit():
|
|
50
|
+
return int(char)
|
|
51
|
+
return 0
|
|
52
|
+
except StopIteration:
|
|
53
|
+
return 0
|
|
54
|
+
|
|
55
|
+
count = next_int_or_zero()
|
|
56
|
+
while count != 0:
|
|
57
|
+
row = []
|
|
58
|
+
for _ in range(count):
|
|
59
|
+
row.append(next_int_or_zero())
|
|
60
|
+
result.append(list(reversed(row)))
|
|
61
|
+
count = next_int_or_zero()
|
|
62
|
+
|
|
63
|
+
return result
|
|
64
|
+
|
|
65
|
+
def decode_url(self, encoded: str, rules: list[int]) -> str:
|
|
66
|
+
text = encoded
|
|
67
|
+
for r in rules:
|
|
68
|
+
if r == 1:
|
|
69
|
+
text = text[::-1]
|
|
70
|
+
|
|
71
|
+
# Hex decode
|
|
72
|
+
with suppress(Exception):
|
|
73
|
+
# remove optional whitespace just in case
|
|
74
|
+
clean_hex = "".join(text.split())
|
|
75
|
+
arr = bytes.fromhex(clean_hex)
|
|
76
|
+
# utf-8 decode, replace errors
|
|
77
|
+
text = arr.decode('utf-8', errors='replace')
|
|
78
|
+
|
|
79
|
+
text = text.replace("dXRmOA==", "")
|
|
80
|
+
|
|
81
|
+
return text
|
|
82
|
+
|
|
83
|
+
async def extract(self, url: str, referer: str = None) -> ExtractResult:
|
|
84
|
+
# URL'den ID çıkar
|
|
85
|
+
# https://veev.to/e/lla8v3k6arev
|
|
86
|
+
video_id = url.split("/")[-1]
|
|
87
|
+
|
|
88
|
+
# Sayfayı al
|
|
89
|
+
# Referer lazım mı? Genelde lazım olabilir.
|
|
90
|
+
page_url = f"{self.main_url}/e/{video_id}"
|
|
91
|
+
resp = await self.httpx.get(page_url, headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"})
|
|
92
|
+
html = resp.text
|
|
93
|
+
|
|
94
|
+
# Regex ile şifreli stringleri bul
|
|
95
|
+
# Regex: [.\s'](?:fc|_vvto\[[^]]*)(?:['\]]*)?\s*[:=]\s*['"]([^'"]+)
|
|
96
|
+
# Python regex için düzenleme gerekebilir.
|
|
97
|
+
found_values = HTMLHelper(html).regex_all(r"[.\s'](?:fc|_vvto\[[^]]*)(?:['\]]*)?\s*[:=]\s*['\"]([^'\"]+)")
|
|
98
|
+
|
|
99
|
+
if not found_values:
|
|
100
|
+
raise ValueError(f"Veev: Token bulunamadı. {url}")
|
|
101
|
+
|
|
102
|
+
# Kotlin kodunda sondan başlayıp deniyor (reversed)
|
|
103
|
+
for f in reversed(found_values):
|
|
104
|
+
try:
|
|
105
|
+
ch = self.veev_decode(f)
|
|
106
|
+
if ch == f:
|
|
107
|
+
continue # Decode olmadıysa geç
|
|
108
|
+
|
|
109
|
+
# API Call
|
|
110
|
+
dl_url = f"{self.main_url}/dl?op=player_api&cmd=gi&file_code={video_id}&r={self.main_url}&ch={ch}&ie=1"
|
|
111
|
+
api_resp = await self.httpx.get(dl_url, headers={"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0.0.0 Safari/537.36"})
|
|
112
|
+
|
|
113
|
+
data = api_resp.json()
|
|
114
|
+
file_obj = data.get("file")
|
|
115
|
+
if not file_obj or file_obj.get("file_status") != "OK":
|
|
116
|
+
continue
|
|
117
|
+
|
|
118
|
+
dv = file_obj.get("dv")
|
|
119
|
+
# dv json string içinde s key'inde olabilir (Kotlin: getString("s"))
|
|
120
|
+
# Ancak api yanıtını görmeden emin olamayız, json yapısına göre file->dv bir string mi object mi?
|
|
121
|
+
# Kotlin: file.getJSONArray("dv").getJSONObject(0).getString("s")
|
|
122
|
+
# Demek ki dv bir array
|
|
123
|
+
|
|
124
|
+
encoded_dv = None
|
|
125
|
+
if isinstance(dv, list) and len(dv) > 0:
|
|
126
|
+
if isinstance(dv[0], dict):
|
|
127
|
+
encoded_dv = dv[0].get("s")
|
|
128
|
+
|
|
129
|
+
if not encoded_dv:
|
|
130
|
+
continue
|
|
131
|
+
|
|
132
|
+
# Decode
|
|
133
|
+
# rules = buildArray(ch)[0]
|
|
134
|
+
rules = self.build_array(ch)[0]
|
|
135
|
+
|
|
136
|
+
final_url = self.decode_url(self.veev_decode(encoded_dv), rules)
|
|
137
|
+
|
|
138
|
+
if final_url.startswith("http"):
|
|
139
|
+
return ExtractResult(name=self.name, url=self.fix_url(final_url), referer=self.main_url)
|
|
140
|
+
|
|
141
|
+
except Exception as e:
|
|
142
|
+
# print(f"Veev Error: {e}")
|
|
143
|
+
continue
|
|
144
|
+
|
|
145
|
+
raise ValueError(f"Veev: Video URL'si çözülemedi. {url}")
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
|
+
|
|
3
|
+
from KekikStream.Core import ExtractorBase, ExtractResult, HTMLHelper
|
|
4
|
+
from Kekik.Sifreleme import Packer
|
|
5
|
+
|
|
6
|
+
class VidBiz(ExtractorBase):
|
|
7
|
+
name = "VidBiz"
|
|
8
|
+
main_url = "https://videolar.biz"
|
|
9
|
+
|
|
10
|
+
async def extract(self, url: str, referer: str = None) -> list[ExtractResult]:
|
|
11
|
+
istek = await self.httpx.get(url, headers={"Referer": referer} if referer else None)
|
|
12
|
+
text = istek.text
|
|
13
|
+
|
|
14
|
+
# Eval script bul (kaken içeriyor olmalı)
|
|
15
|
+
eval_script = HTMLHelper(text).regex_first(r'(eval\(function[\s\S]+?)<\/script>') or \
|
|
16
|
+
HTMLHelper(text).regex_first(r'(eval\(function[\s\S]+)')
|
|
17
|
+
if not eval_script:
|
|
18
|
+
raise ValueError(f"VidBiz: Packed script bulunamadı. {url}")
|
|
19
|
+
|
|
20
|
+
unpacked = ""
|
|
21
|
+
try:
|
|
22
|
+
unpacked = Packer.unpack(eval_script)
|
|
23
|
+
except:
|
|
24
|
+
raise ValueError("VidBiz: Unpack hatası")
|
|
25
|
+
|
|
26
|
+
# window.kaken="..."
|
|
27
|
+
kaken = HTMLHelper(unpacked).regex_first(r'window\.kaken\s*=\s*"([^"]+)"')
|
|
28
|
+
if not kaken:
|
|
29
|
+
raise ValueError("VidBiz: Kaken token bulunamadı")
|
|
30
|
+
|
|
31
|
+
# API POST
|
|
32
|
+
# Content-Type: text/plain önemli olabilir
|
|
33
|
+
resp = await self.httpx.post(
|
|
34
|
+
url = "https://s2.videolar.biz/api/",
|
|
35
|
+
content = kaken, # data yerine content=raw string
|
|
36
|
+
headers = {"Content-Type": "text/plain", "Referer": url}
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
try:
|
|
40
|
+
data = resp.json()
|
|
41
|
+
except:
|
|
42
|
+
raise ValueError("VidBiz: API yanıtı JSON değil")
|
|
43
|
+
|
|
44
|
+
if data.get("status") != "ok":
|
|
45
|
+
raise ValueError(f"VidBiz: API hatası {data}")
|
|
46
|
+
|
|
47
|
+
results = []
|
|
48
|
+
for source in data.get("sources", []):
|
|
49
|
+
file_url = source.get("file")
|
|
50
|
+
label = source.get("label", "Unknown")
|
|
51
|
+
|
|
52
|
+
if not file_url:
|
|
53
|
+
continue
|
|
54
|
+
|
|
55
|
+
results.append(ExtractResult(
|
|
56
|
+
name = f"{self.name} | {label}",
|
|
57
|
+
url = self.fix_url(file_url),
|
|
58
|
+
referer = url,
|
|
59
|
+
user_agent = self.httpx.headers.get("User-Agent", "")
|
|
60
|
+
))
|
|
61
|
+
|
|
62
|
+
return results
|
|
@@ -9,7 +9,16 @@ class VidHide(ExtractorBase):
|
|
|
9
9
|
main_url = "https://vidhidepro.com"
|
|
10
10
|
|
|
11
11
|
# Birden fazla domain destekle
|
|
12
|
-
supported_domains = [
|
|
12
|
+
supported_domains = [
|
|
13
|
+
"vidhidepro.com", "vidhide.com", "rubyvidhub.com",
|
|
14
|
+
"vidhidevip.com", "vidhideplus.com", "vidhidepre.com",
|
|
15
|
+
"movearnpre.com", "oneupload.to",
|
|
16
|
+
"filelions.live", "filelions.online", "filelions.to",
|
|
17
|
+
"kinoger.be",
|
|
18
|
+
"smoothpre.com",
|
|
19
|
+
"dhtpre.com",
|
|
20
|
+
"peytonepre.com"
|
|
21
|
+
]
|
|
13
22
|
|
|
14
23
|
def can_handle_url(self, url: str) -> bool:
|
|
15
24
|
return any(domain in url for domain in self.supported_domains)
|
|
@@ -21,6 +30,8 @@ class VidHide(ExtractorBase):
|
|
|
21
30
|
return url.replace("/download/", "/v/")
|
|
22
31
|
elif "/file/" in url:
|
|
23
32
|
return url.replace("/file/", "/v/")
|
|
33
|
+
elif "/embed/" in url:
|
|
34
|
+
return url.replace("/embed/", "/v/")
|
|
24
35
|
else:
|
|
25
36
|
return url.replace("/f/", "/v/")
|
|
26
37
|
|
|
@@ -32,18 +43,56 @@ class VidHide(ExtractorBase):
|
|
|
32
43
|
})
|
|
33
44
|
|
|
34
45
|
embed_url = self.get_embed_url(url)
|
|
35
|
-
istek = await self.httpx.get(embed_url)
|
|
36
|
-
|
|
46
|
+
istek = await self.httpx.get(embed_url, follow_redirects=True)
|
|
47
|
+
text = istek.text
|
|
48
|
+
|
|
49
|
+
# Silinmiş dosya kontrolü
|
|
50
|
+
if "File is no longer available" in text or "File Not Found" in text:
|
|
51
|
+
raise ValueError(f"VidHide: Video silinmiş. {url}")
|
|
52
|
+
|
|
53
|
+
# JS Redirect Kontrolü (OneUpload vb.)
|
|
54
|
+
if js_redirect := HTMLHelper(text).regex_first(r"window\.location\.replace\(['\"]([^'\"]+)['\"]\)") or \
|
|
55
|
+
HTMLHelper(text).regex_first(r"window\.location\.href\s*=\s*['\"]([^'\"]+)['\"]"):
|
|
56
|
+
# Redirect url'i al
|
|
57
|
+
target_url = js_redirect
|
|
58
|
+
# Bazen path relative olabilir ama genelde full url
|
|
59
|
+
if not target_url.startswith("http"):
|
|
60
|
+
# urljoin gerekebilir ama şimdilik doğrudan deneyelim veya fix_url
|
|
61
|
+
target_url = self.fix_url(target_url) # fix_url base'e göre düzeltebilir mi? ExtractorBase.fix_url genelde şema ekler.
|
|
62
|
+
pass
|
|
63
|
+
|
|
64
|
+
# Yeniden istek at
|
|
65
|
+
istek = await self.httpx.get(target_url, headers={"Referer": embed_url}, follow_redirects=True)
|
|
66
|
+
text = istek.text
|
|
67
|
+
|
|
68
|
+
sel = HTMLHelper(text)
|
|
37
69
|
|
|
38
70
|
unpacked = ""
|
|
39
|
-
|
|
71
|
+
# Eval script bul (regex ile daha sağlam)
|
|
72
|
+
if eval_match := sel.regex_first(r'(eval\s*\(\s*function[\s\S]+?)<\/script>'):
|
|
40
73
|
try:
|
|
41
|
-
unpacked = Packer.unpack(
|
|
74
|
+
unpacked = Packer.unpack(eval_match)
|
|
75
|
+
if "var links" in unpacked:
|
|
76
|
+
unpacked = unpacked.split("var links")[1]
|
|
42
77
|
except:
|
|
43
78
|
pass
|
|
44
79
|
|
|
45
|
-
content = unpacked or
|
|
46
|
-
|
|
80
|
+
content = unpacked or text
|
|
81
|
+
|
|
82
|
+
# Regex: Kotlin mantığı (: "url")
|
|
83
|
+
# Ayrıca sources: [...] mantığını da ekle
|
|
84
|
+
m3u8_url = HTMLHelper(content).regex_first(r'sources:\s*\[\s*\{\s*file:\s*"([^"]+)"')
|
|
85
|
+
|
|
86
|
+
if not m3u8_url:
|
|
87
|
+
# Genel arama (hls:, file: vb.)
|
|
88
|
+
# Kotlin Regex: :\s*"(.*?m3u8.*?)"
|
|
89
|
+
match = HTMLHelper(content).regex_first(r':\s*["\']([^"\']+\.m3u8[^"\']*)["\']')
|
|
90
|
+
if match:
|
|
91
|
+
m3u8_url = match
|
|
92
|
+
|
|
93
|
+
if not m3u8_url:
|
|
94
|
+
# Son şans: herhangi bir m3u8 linki
|
|
95
|
+
m3u8_url = HTMLHelper(content).regex_first(r'["\']([^"\']+\.m3u8[^"\']*)["\']')
|
|
47
96
|
|
|
48
97
|
if not m3u8_url:
|
|
49
98
|
raise ValueError(f"VidHide: Video URL bulunamadı. {url}")
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
|
+
|
|
3
|
+
from KekikStream.Core import ExtractorBase, ExtractResult, HTMLHelper
|
|
4
|
+
from Kekik.Sifreleme import Packer
|
|
5
|
+
|
|
6
|
+
class Vtbe(ExtractorBase):
|
|
7
|
+
name = "Vtbe"
|
|
8
|
+
main_url = "https://vtbe.to"
|
|
9
|
+
|
|
10
|
+
async def extract(self, url: str, referer: str = None) -> list[ExtractResult]:
|
|
11
|
+
# Iframe ise embed url'i düzeltmek gerekebilir ama genelde embed-xxxx.html formatı
|
|
12
|
+
istek = await self.httpx.get(url, headers={"Referer": referer or self.main_url})
|
|
13
|
+
text = istek.text
|
|
14
|
+
|
|
15
|
+
# Packed script bul: function(p,a,c,k,e,d)
|
|
16
|
+
packed = HTMLHelper(text).regex_first(r'(eval\s*\(\s*function[\s\S]+?)<\/script>')
|
|
17
|
+
|
|
18
|
+
if not packed:
|
|
19
|
+
raise ValueError(f"Vtbe: Packed script bulunamadı. {url}")
|
|
20
|
+
|
|
21
|
+
unpacked = ""
|
|
22
|
+
try:
|
|
23
|
+
unpacked = Packer.unpack(packed)
|
|
24
|
+
except:
|
|
25
|
+
raise ValueError("Vtbe: Unpack hatası")
|
|
26
|
+
|
|
27
|
+
# sources:[{file:"..."
|
|
28
|
+
file_url = HTMLHelper(unpacked).regex_first(r'sources:\s*\[\s*\{\s*file:\s*"([^"]+)"')
|
|
29
|
+
|
|
30
|
+
if not file_url:
|
|
31
|
+
raise ValueError("Vtbe: Video URL (file) bulunamadı")
|
|
32
|
+
|
|
33
|
+
return ExtractResult(
|
|
34
|
+
name = self.name,
|
|
35
|
+
url = self.fix_url(file_url),
|
|
36
|
+
referer = url,
|
|
37
|
+
user_agent = self.httpx.headers.get("User-Agent", "")
|
|
38
|
+
)
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
|
+
|
|
3
|
+
from KekikStream.Core import ExtractorBase, ExtractResult, HTMLHelper
|
|
4
|
+
|
|
5
|
+
class Zeus(ExtractorBase):
|
|
6
|
+
name = "Zeus"
|
|
7
|
+
main_url = "https://d2rs.com"
|
|
8
|
+
|
|
9
|
+
async def extract(self, url: str, referer: str = None) -> list[ExtractResult]:
|
|
10
|
+
# Iframe içeriğini al
|
|
11
|
+
istek = await self.httpx.get(url, headers={"Referer": referer} if referer else None)
|
|
12
|
+
text = istek.text
|
|
13
|
+
|
|
14
|
+
# 'q' parametresini bul
|
|
15
|
+
# form.append("q", "...")
|
|
16
|
+
q_param = HTMLHelper(text).regex_first(r'form\.append\("q",\s*"([^"]+)"\)')
|
|
17
|
+
|
|
18
|
+
if not q_param:
|
|
19
|
+
raise ValueError(f"Zeus: 'q' parametresi bulunamadı. {url}")
|
|
20
|
+
|
|
21
|
+
# API'ye POST at
|
|
22
|
+
resp = await self.httpx.post(
|
|
23
|
+
url = "https://d2rs.com/zeus/api.php",
|
|
24
|
+
data = {"q": q_param},
|
|
25
|
+
headers = {"Referer": url}
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
try:
|
|
29
|
+
sources = resp.json()
|
|
30
|
+
except:
|
|
31
|
+
raise ValueError("Zeus: API yanıtı geçersiz JSON")
|
|
32
|
+
|
|
33
|
+
results = []
|
|
34
|
+
# [{"file": "...", "label": "Full HD", "type": "video/mp4"}, ...]
|
|
35
|
+
for i, source in enumerate(sources, 1):
|
|
36
|
+
file_path = source.get("file")
|
|
37
|
+
label = source.get("label") or ""
|
|
38
|
+
type_ = source.get("type", "")
|
|
39
|
+
|
|
40
|
+
if not file_path:
|
|
41
|
+
continue
|
|
42
|
+
|
|
43
|
+
full_url = f"https://d2rs.com/zeus/{file_path}"
|
|
44
|
+
|
|
45
|
+
# İsimlendirme
|
|
46
|
+
if label:
|
|
47
|
+
source_name = f"{self.name} | {label}"
|
|
48
|
+
else:
|
|
49
|
+
source_name = f"{self.name} | Kaynak {i}"
|
|
50
|
+
|
|
51
|
+
results.append(ExtractResult(
|
|
52
|
+
name = source_name,
|
|
53
|
+
url = self.fix_url(full_url),
|
|
54
|
+
referer = url,
|
|
55
|
+
user_agent = self.httpx.headers.get("User-Agent", "")
|
|
56
|
+
))
|
|
57
|
+
|
|
58
|
+
if not results:
|
|
59
|
+
raise ValueError("Zeus: Kaynak bulunamadı")
|
|
60
|
+
|
|
61
|
+
return results
|
|
@@ -12,20 +12,43 @@ class HDFilmCehennemi(PluginBase):
|
|
|
12
12
|
description = "Türkiye'nin en hızlı hd film izleme sitesi. Tek ve gerçek hdfilmcehennemi sitesi."
|
|
13
13
|
|
|
14
14
|
main_page = {
|
|
15
|
-
f"{main_url}"
|
|
16
|
-
f"{main_url}/yabancidiziizle-
|
|
17
|
-
f"{main_url}/
|
|
18
|
-
f"{main_url}/
|
|
19
|
-
f"{main_url}/
|
|
20
|
-
f"{main_url}/
|
|
21
|
-
f"{main_url}/
|
|
22
|
-
f"{main_url}/
|
|
23
|
-
f"{main_url}/
|
|
24
|
-
f"{main_url}/
|
|
25
|
-
f"{main_url}/
|
|
26
|
-
f"{main_url}/
|
|
27
|
-
f"{main_url}/
|
|
28
|
-
f"{main_url}/
|
|
15
|
+
f"{main_url}" : "Yeni Eklenen Filmler",
|
|
16
|
+
f"{main_url}/yabancidiziizle-5" : "Yeni Eklenen Diziler",
|
|
17
|
+
f"{main_url}/dil/turkce-dublajli-film-izleyin-5" : "Türkçe Dublaj Filmler",
|
|
18
|
+
f"{main_url}/dil/turkce-altyazili-filmleri-izleme-sitesi-3" : "Türkçe Altyazılı Filmler",
|
|
19
|
+
f"{main_url}/category/tavsiye-filmler-izle3" : "Tavsiye Filmler",
|
|
20
|
+
f"{main_url}/imdb-7-puan-uzeri-filmler-2" : "IMDB 7+ Filmler",
|
|
21
|
+
f"{main_url}/en-cok-yorumlananlar-2" : "En Çok Yorumlananlar",
|
|
22
|
+
f"{main_url}/en-cok-begenilen-filmleri-izle-4" : "En Çok Beğenilenler",
|
|
23
|
+
f"{main_url}/serifilmlerim-4" : "Seri Filmler",
|
|
24
|
+
f"{main_url}/category/nette-ilk-filmler" : "Nette İlk Filmler",
|
|
25
|
+
f"{main_url}/category/4k-film-izle-5" : "4K Filmler",
|
|
26
|
+
f"{main_url}/category/1080p-hd-film-izle-5" : "1080p Filmler",
|
|
27
|
+
f"{main_url}/category/amazon-yapimlarini-izle" : "Amazon Yapımları",
|
|
28
|
+
f"{main_url}/category/netflix-yapimlari-izle" : "Netflix Yapımları",
|
|
29
|
+
f"{main_url}/category/marvel-yapimlarini-izle-5" : "Marvel Filmleri",
|
|
30
|
+
f"{main_url}/category/dc-yapimlarini-izle-1" : "DC Filmleri",
|
|
31
|
+
f"{main_url}/tur/aile-filmleri-izleyin-7" : "Aile Filmleri",
|
|
32
|
+
f"{main_url}/tur/aksiyon-filmleri-izleyin-6" : "Aksiyon Filmleri",
|
|
33
|
+
f"{main_url}/tur/animasyon-filmlerini-izleyin-5" : "Animasyon Filmleri",
|
|
34
|
+
f"{main_url}/tur/belgesel-filmlerini-izle-2" : "Belgesel Filmleri",
|
|
35
|
+
f"{main_url}/tur/bilim-kurgu-filmlerini-izleyin-5" : "Bilim Kurgu Filmleri",
|
|
36
|
+
f"{main_url}/tur/biyografi-filmleri-izle-3" : "Biyografi Filmleri",
|
|
37
|
+
f"{main_url}/tur/dram-filmlerini-izle-2" : "Dram Filmleri",
|
|
38
|
+
f"{main_url}/tur/fantastik-filmlerini-izleyin-3" : "Fantastik Filmleri",
|
|
39
|
+
f"{main_url}/tur/gerilim-filmlerini-izle-2" : "Gerilim Filmleri",
|
|
40
|
+
f"{main_url}/tur/gizem-filmleri-izle-3" : "Gizem Filmleri",
|
|
41
|
+
f"{main_url}/tur/komedi-filmlerini-izleyin-2" : "Komedi Filmleri",
|
|
42
|
+
f"{main_url}/tur/korku-filmlerini-izle-5" : "Korku Filmleri",
|
|
43
|
+
f"{main_url}/tur/macera-filmlerini-izleyin-4" : "Macera Filmleri",
|
|
44
|
+
f"{main_url}/tur/muzik-filmlerini-izle-844" : "Müzik Filmleri",
|
|
45
|
+
f"{main_url}/tur/polisiye-filmleri-izle" : "Polisiye Filmleri",
|
|
46
|
+
f"{main_url}/tur/romantik-filmleri-izle-3" : "Romantik Filmleri",
|
|
47
|
+
f"{main_url}/tur/savas-filmleri-izle-5" : "Savaş Filmleri",
|
|
48
|
+
f"{main_url}/tur/spor-filmleri-izle-3" : "Spor Filmleri",
|
|
49
|
+
f"{main_url}/tur/suc-filmleri-izle-3" : "Suç Filmleri",
|
|
50
|
+
f"{main_url}/tur/tarih-filmleri-izle-5" : "Tarih Filmleri",
|
|
51
|
+
f"{main_url}/tur/western-filmleri-izle-3" : "Western Filmleri"
|
|
29
52
|
}
|
|
30
53
|
|
|
31
54
|
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
2
|
|
|
3
|
-
from KekikStream.Core
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, ExtractResult, HTMLHelper
|
|
4
|
+
import asyncio
|
|
4
5
|
|
|
5
6
|
class JetFilmizle(PluginBase):
|
|
6
7
|
name = "JetFilmizle"
|
|
@@ -42,17 +43,15 @@ class JetFilmizle(PluginBase):
|
|
|
42
43
|
|
|
43
44
|
results = []
|
|
44
45
|
for veri in secici.select("article.movie"):
|
|
45
|
-
# h2-h6 içindeki a linki
|
|
46
46
|
title_text = None
|
|
47
47
|
for h_tag in ["h2", "h3", "h4", "h5", "h6"]:
|
|
48
48
|
title_text = secici.select_text(f"{h_tag} a", veri)
|
|
49
49
|
if title_text:
|
|
50
50
|
break
|
|
51
51
|
|
|
52
|
-
href = secici.select_attr("a", "href", veri)
|
|
53
|
-
poster = secici.select_poster("img", veri)
|
|
54
|
-
|
|
55
52
|
title = self.clean_title(title_text) if title_text else None
|
|
53
|
+
href = secici.select_attr("a", "href", veri)
|
|
54
|
+
poster = secici.select_poster("img", veri)
|
|
56
55
|
|
|
57
56
|
if title and href:
|
|
58
57
|
results.append(MainPageResult(
|
|
@@ -74,17 +73,15 @@ class JetFilmizle(PluginBase):
|
|
|
74
73
|
|
|
75
74
|
results = []
|
|
76
75
|
for article in secici.select("article.movie"):
|
|
77
|
-
# h2-h6 içindeki a linki
|
|
78
76
|
title_text = None
|
|
79
77
|
for h_tag in ["h2", "h3", "h4", "h5", "h6"]:
|
|
80
78
|
title_text = secici.select_text(f"{h_tag} a", article)
|
|
81
79
|
if title_text:
|
|
82
80
|
break
|
|
83
81
|
|
|
84
|
-
href = secici.select_attr("a", "href", article)
|
|
85
|
-
poster = secici.select_poster("img", article)
|
|
86
|
-
|
|
87
82
|
title = self.clean_title(title_text) if title_text else None
|
|
83
|
+
href = secici.select_attr("a", "href", article)
|
|
84
|
+
poster = secici.select_poster("img", article)
|
|
88
85
|
|
|
89
86
|
if title and href:
|
|
90
87
|
results.append(SearchResult(
|
|
@@ -126,53 +123,89 @@ class JetFilmizle(PluginBase):
|
|
|
126
123
|
rating = rating,
|
|
127
124
|
year = year,
|
|
128
125
|
actors = actors,
|
|
129
|
-
duration =
|
|
126
|
+
duration = total_minutes if total_minutes else None
|
|
130
127
|
)
|
|
131
128
|
|
|
132
|
-
async def
|
|
133
|
-
istek = await self.httpx.get(url)
|
|
134
|
-
secici = HTMLHelper(istek.text)
|
|
135
|
-
|
|
129
|
+
async def _process_source(self, url: str, name: str, html: str | None) -> list[ExtractResult]:
|
|
136
130
|
results = []
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
# 2) Sayfa numaralarından linkleri topla (Fragman hariç)
|
|
151
|
-
page_links = []
|
|
152
|
-
for link in secici.select("a.post-page-numbers"):
|
|
153
|
-
isim = secici.select_text("span", link) or ""
|
|
154
|
-
if isim != "Fragman":
|
|
155
|
-
href = link.attrs.get("href")
|
|
156
|
-
if href:
|
|
157
|
-
page_links.append((self.fix_url(href), isim))
|
|
158
|
-
|
|
159
|
-
# 3) Her sayfa linkindeki iframe'leri bul
|
|
160
|
-
for page_url, isim in page_links:
|
|
161
|
-
try:
|
|
162
|
-
page_resp = await self.httpx.get(page_url)
|
|
163
|
-
page_sel = HTMLHelper(page_resp.text)
|
|
164
|
-
|
|
165
|
-
for iframe in page_sel.select("div#movie iframe"):
|
|
131
|
+
try:
|
|
132
|
+
if html:
|
|
133
|
+
secici = HTMLHelper(html)
|
|
134
|
+
else:
|
|
135
|
+
resp = await self.httpx.get(url)
|
|
136
|
+
secici = HTMLHelper(resp.text)
|
|
137
|
+
|
|
138
|
+
# Iframe'leri bul
|
|
139
|
+
container = secici.select_first("div#movie") or secici.select_first("div.film-content")
|
|
140
|
+
|
|
141
|
+
if container:
|
|
142
|
+
for iframe in secici.select("iframe", container):
|
|
166
143
|
src = (iframe.attrs.get("src") or
|
|
167
144
|
iframe.attrs.get("data-src") or
|
|
168
145
|
iframe.attrs.get("data-lazy-src"))
|
|
169
|
-
|
|
146
|
+
|
|
170
147
|
if src and src != "about:blank":
|
|
171
148
|
iframe_url = self.fix_url(src)
|
|
172
|
-
|
|
149
|
+
# name_override KULLANMA, extractor kendi ismini versin
|
|
150
|
+
# Sonra biz düzenleriz
|
|
151
|
+
data = await self.extract(iframe_url)
|
|
152
|
+
|
|
173
153
|
if data:
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
154
|
+
items = data if isinstance(data, list) else [data]
|
|
155
|
+
|
|
156
|
+
for item in items:
|
|
157
|
+
# Sadece kalite bilgisi içeriyorsa ekle, yoksa sadece buton adını kullan
|
|
158
|
+
# Özellikle Zeus için kalite önemli (1080p, 720p)
|
|
159
|
+
# Diğerlerinde plugin adı (Apollo, JetPlay vb.) önemsiz
|
|
160
|
+
|
|
161
|
+
# Kalite kontrolü (basitçe)
|
|
162
|
+
quality_indicators = ["1080p", "720p", "480p", "360p", "240p", "144p", "4k", "2k"]
|
|
163
|
+
has_quality = any(q in item.name.lower() for q in quality_indicators)
|
|
164
|
+
|
|
165
|
+
if has_quality:
|
|
166
|
+
# Buton Adı | Extractor Adı (Kalite içerdiği için)
|
|
167
|
+
# Örn: Zeus | 1080p
|
|
168
|
+
# Eğer Extractor adı zaten Buton adını içeriyorsa (Zeus | 1080p -> Zeus) tekrar ekleme
|
|
169
|
+
if name.lower() not in item.name.lower():
|
|
170
|
+
item.name = f"{name} | {item.name}"
|
|
171
|
+
else:
|
|
172
|
+
# Kalite yoksa sadece Buton adını kullan
|
|
173
|
+
# Örn: Apollo | JetTv -> JetTv
|
|
174
|
+
item.name = name
|
|
175
|
+
|
|
176
|
+
results.append(item)
|
|
177
|
+
return results
|
|
178
|
+
except Exception:
|
|
179
|
+
return []
|
|
177
180
|
|
|
178
|
-
|
|
181
|
+
async def load_links(self, url: str) -> list[ExtractResult]:
|
|
182
|
+
istek = await self.httpx.get(url)
|
|
183
|
+
secici = HTMLHelper(istek.text)
|
|
184
|
+
|
|
185
|
+
sources = []
|
|
186
|
+
if film_part := secici.select_first("div.film_part"):
|
|
187
|
+
# Tüm spanları gez
|
|
188
|
+
for span in secici.select("span", film_part):
|
|
189
|
+
# Eğer bu span bir <a> etiketi içinde değilse, aktif kaynaktır
|
|
190
|
+
if span.parent.tag != "a":
|
|
191
|
+
name = span.text(strip=True)
|
|
192
|
+
if name:
|
|
193
|
+
sources.append((url, name, istek.text)) # html content var
|
|
194
|
+
break
|
|
195
|
+
|
|
196
|
+
# Diğer kaynak linkleri
|
|
197
|
+
for link in secici.select("a.post-page-numbers", film_part):
|
|
198
|
+
name = secici.select_text("span", link) or link.text(strip=True)
|
|
199
|
+
href = link.attrs.get("href")
|
|
200
|
+
if name != "Fragman" and href:
|
|
201
|
+
sources.append((self.fix_url(href), name, None)) # html yok, çekilecek
|
|
202
|
+
|
|
203
|
+
# Eğer film_part yoksa, sadece mevcut sayfayı tara (Tek part olabilir)
|
|
204
|
+
if not sources:
|
|
205
|
+
sources.append((url, "JetFilmizle", istek.text))
|
|
206
|
+
|
|
207
|
+
tasks = []
|
|
208
|
+
for page_url, source_name, html_content in sources:
|
|
209
|
+
tasks.append(self._process_source(page_url, source_name, html_content))
|
|
210
|
+
|
|
211
|
+
return [item for sublist in await asyncio.gather(*tasks) for item in sublist]
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: KekikStream
|
|
3
|
-
Version: 2.4.
|
|
3
|
+
Version: 2.4.9
|
|
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
|
|
@@ -28,6 +28,7 @@ KekikStream/Extractors/HDPlayerSystem.py,sha256=hoPN7fqVRBK97BnQ7vF_5TlEO28BD3Dr
|
|
|
28
28
|
KekikStream/Extractors/HotStream.py,sha256=37H9pK4HSEqGR6QKgxz887JCBXfXB1NXDpBGuhvPmXo,1078
|
|
29
29
|
KekikStream/Extractors/JFVid.py,sha256=rdy0bmqZIruejn1G1YNxVM3wlqxkdFRd4zunxxZlev4,746
|
|
30
30
|
KekikStream/Extractors/JetTv.py,sha256=Cdx1XZEtQZkrmOdZdgM9E1iBkCNzVTExjrI_F-3Nv-I,1176
|
|
31
|
+
KekikStream/Extractors/JetV.py,sha256=knyDiOCSBMC1eQHo5LRFx5apn3NQflKY3xyloLDGkaI,2069
|
|
31
32
|
KekikStream/Extractors/MailRu.py,sha256=n87wBc9jQ4nP8OJbqS7LsHHCKuRxlsgdtL_xHVn0rdY,779
|
|
32
33
|
KekikStream/Extractors/MixPlayHD.py,sha256=otA2SKDnJisY4Zt9DCuNdjNVHtSquHoMVvP3_5Q0poY,1205
|
|
33
34
|
KekikStream/Extractors/MixTiger.py,sha256=kF_AKkJoyAS6peQ94eu3pLzS-VeZ_8IYjpaDrTo3x_I,1135
|
|
@@ -46,15 +47,19 @@ KekikStream/Extractors/TauVideo.py,sha256=2ai9BwwM6qlCgxK7E0B642LtOF5y4hEb9tQ2aD
|
|
|
46
47
|
KekikStream/Extractors/TurboImgz.py,sha256=-RyC4EWtJdK85Ei01lntqivnSmk4tXOlmSXv70cQJ70,679
|
|
47
48
|
KekikStream/Extractors/TurkeyPlayer.py,sha256=zdX0IOO3M-kgAYWex2WwJJu9aGf8WhOY-ZIrRmZRiC0,1246
|
|
48
49
|
KekikStream/Extractors/VCTPlay.py,sha256=MdCH9GhhKod4oPT3ePH8rhicUWuNT-GsE42S72o1NJ4,876
|
|
49
|
-
KekikStream/Extractors/
|
|
50
|
+
KekikStream/Extractors/Veev.py,sha256=DowOuKhCAmVs0sMeQRxxhWRUf4MR6fhx1yeNUmy_Le4,5271
|
|
51
|
+
KekikStream/Extractors/VidBiz.py,sha256=V9nTt8Uaqn5F9x9WMZbW3wqaeajGLdBhLryXoeStChk,2212
|
|
52
|
+
KekikStream/Extractors/VidHide.py,sha256=YswpcBz6Eqq_qGZhHpRcxcvTK0S3hZSNPfNjQRrn_W4,4109
|
|
50
53
|
KekikStream/Extractors/VidMoly.py,sha256=LUUomzPvf4J7PG3rf7drV4WM-sBHOupsllj017eluew,4106
|
|
51
54
|
KekikStream/Extractors/VidMoxy.py,sha256=qTkTFRqTgQVi-E94zY5lQC2-AYFhkl8LqaOJpgGdErc,1452
|
|
52
55
|
KekikStream/Extractors/VidPapi.py,sha256=yqjA5gadCE2lZ9ksT6zZOz-1zCcCYJxZsg0Ccgz2X10,1988
|
|
53
56
|
KekikStream/Extractors/VideoSeyred.py,sha256=sNxw5OHQ8AzRJIRGXGjql8nK1E6Cbg9qhKP5PuOyeM8,1216
|
|
54
57
|
KekikStream/Extractors/Videostr.py,sha256=CGL9GDzN0QzDir6ss8oUvDYYbGt2k8323P2_z5tVZVI,2563
|
|
55
58
|
KekikStream/Extractors/Vidoza.py,sha256=VSqCI-SYnLh6COnLHpg0feRX37t2WhPxbo08us5wCcc,655
|
|
59
|
+
KekikStream/Extractors/Vtbe.py,sha256=d_ZnLHnYiQltwMOWsop-EbLb0cqMiRyp5foiOm5k2es,1392
|
|
56
60
|
KekikStream/Extractors/YTDLP.py,sha256=vE08jS9kLrLxiZA8TpofPQg2-ec_6d5DkM9esoh_GI8,7419
|
|
57
61
|
KekikStream/Extractors/YildizKisaFilm.py,sha256=jeCCSIwZvQUr-CSylleUIP--JtN18_wUGl0vQXMCsV4,936
|
|
62
|
+
KekikStream/Extractors/Zeus.py,sha256=OifOjIVZWeXSoGu4F2wpxv0c-ABm-2UYD9g5L4dwkjs,2003
|
|
58
63
|
KekikStream/Plugins/BelgeselX.py,sha256=tJw1GZQoqxE7HISCVYUEL2ZP-8Mftdl4WytYA0ftSUc,9648
|
|
59
64
|
KekikStream/Plugins/DiziBox.py,sha256=SuRQxNZetwJJTlobuxB0h7NMeHUMrYMv_94JuCXydds,10204
|
|
60
65
|
KekikStream/Plugins/DiziMom.py,sha256=mRu9YUHs7XeLzXOqKIWcsI82yeltTW-6Q423wt71D5U,8044
|
|
@@ -69,8 +74,8 @@ KekikStream/Plugins/Filmatek.py,sha256=AdOeBVP1rfq5R1YJlQj2saT77rnzVHX54tEOAH-t9
|
|
|
69
74
|
KekikStream/Plugins/FilmciBaba.py,sha256=miwQ7ODHGcAOBacUZf0lqolBElpvOk8oeckWVJYJau0,6936
|
|
70
75
|
KekikStream/Plugins/FullHDFilmizlesene.py,sha256=dJ1xo1D3ujPCQE6PewpqdvSMKlBbifA67uU7BAMmvVM,6274
|
|
71
76
|
KekikStream/Plugins/HDFilm.py,sha256=m6tjV1O1l5U_jqkGKizi62GOdSMd5osyOS2_9jehS-w,10754
|
|
72
|
-
KekikStream/Plugins/HDFilmCehennemi.py,sha256=
|
|
73
|
-
KekikStream/Plugins/JetFilmizle.py,sha256=
|
|
77
|
+
KekikStream/Plugins/HDFilmCehennemi.py,sha256=h3FTKN-psrzvN0Juw8Am83MV8QL9aX-RSWhYqXRQU-E,17368
|
|
78
|
+
KekikStream/Plugins/JetFilmizle.py,sha256=YyZmOWoh_SFGRARrKioq8fhv8VgzTiURFypJMoW8nzU,10279
|
|
74
79
|
KekikStream/Plugins/KultFilmler.py,sha256=iHk3X8CwNxHRgGFZRK6BDqvZLs0p9GK5oi8IAm6w3Lw,8441
|
|
75
80
|
KekikStream/Plugins/RecTV.py,sha256=MRoP8KQF2V9kVlRNTQkRz9YFkBmMy3_skiNE47-RAlk,7151
|
|
76
81
|
KekikStream/Plugins/RoketDizi.py,sha256=2OIDct56NgmQJyv0gIi9ZprpxSL3u41ZdEst5q1mhq4,9222
|
|
@@ -85,9 +90,9 @@ KekikStream/Plugins/SuperFilmGeldi.py,sha256=jJKBrLPI4rXI8n55lIdZOTyzNccPAEEIkmT
|
|
|
85
90
|
KekikStream/Plugins/UgurFilm.py,sha256=NO6c1hHlylCfoP8fM-aVsxpBIyTAyu4uBHVM8CjybuI,5037
|
|
86
91
|
KekikStream/Plugins/Watch32.py,sha256=NeESk1unb5SYs6kwkb3dDymv2yYOkRU2QJCPI9izXKk,7915
|
|
87
92
|
KekikStream/Plugins/YabanciDizi.py,sha256=m4I8OM7Br_RRUSY0RAMpqcZ-_BwyjKXWHQuF_jS4EnE,9876
|
|
88
|
-
kekikstream-2.4.
|
|
89
|
-
kekikstream-2.4.
|
|
90
|
-
kekikstream-2.4.
|
|
91
|
-
kekikstream-2.4.
|
|
92
|
-
kekikstream-2.4.
|
|
93
|
-
kekikstream-2.4.
|
|
93
|
+
kekikstream-2.4.9.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
94
|
+
kekikstream-2.4.9.dist-info/METADATA,sha256=AuylDm8bUfwDBeEQ4CBg0hi6csQXcMrS1dvytuP-Qr0,10745
|
|
95
|
+
kekikstream-2.4.9.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
96
|
+
kekikstream-2.4.9.dist-info/entry_points.txt,sha256=dFwdiTx8djyehI0Gsz-rZwjAfZzUzoBSrmzRu9ubjJc,50
|
|
97
|
+
kekikstream-2.4.9.dist-info/top_level.txt,sha256=DNmGJDXl27Drdfobrak8KYLmocW_uznVYFJOzcjUgmY,12
|
|
98
|
+
kekikstream-2.4.9.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|