KekikStream 1.9.9__py3-none-any.whl → 2.0.1__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 +5 -5
- KekikStream/Core/Extractor/ExtractorLoader.py +25 -17
- KekikStream/Core/Extractor/ExtractorManager.py +1 -1
- KekikStream/Core/Plugin/PluginBase.py +4 -1
- KekikStream/Core/Plugin/PluginLoader.py +11 -7
- KekikStream/Extractors/CloseLoad.py +1 -1
- KekikStream/Extractors/ContentX_.py +40 -0
- KekikStream/Extractors/{OkRuHTTP.py → Odnoklassniki_.py} +5 -1
- KekikStream/Extractors/{HDStreamAble.py → PeaceMakerst_.py} +1 -1
- KekikStream/Extractors/RapidVid_.py +7 -0
- KekikStream/Extractors/{VidMolyMe.py → VidMoly_.py} +1 -1
- KekikStream/Plugins/Dizilla.py +1 -1
- KekikStream/Plugins/FilmMakinesi.py +2 -0
- KekikStream/Plugins/JetFilmizle.py +52 -37
- KekikStream/Plugins/Sinefy.py +4 -1
- KekikStream/Plugins/Sinezy.py +16 -1
- {kekikstream-1.9.9.dist-info → kekikstream-2.0.1.dist-info}/METADATA +27 -1
- {kekikstream-1.9.9.dist-info → kekikstream-2.0.1.dist-info}/RECORD +22 -27
- KekikStream/Extractors/FourCX.py +0 -7
- KekikStream/Extractors/FourPichive.py +0 -7
- KekikStream/Extractors/FourPlayRu.py +0 -7
- KekikStream/Extractors/Hotlinger.py +0 -7
- KekikStream/Extractors/OkRuSSL.py +0 -7
- KekikStream/Extractors/Pichive.py +0 -7
- KekikStream/Extractors/PlayRu.py +0 -7
- {kekikstream-1.9.9.dist-info → kekikstream-2.0.1.dist-info}/WHEEL +0 -0
- {kekikstream-1.9.9.dist-info → kekikstream-2.0.1.dist-info}/entry_points.txt +0 -0
- {kekikstream-1.9.9.dist-info → kekikstream-2.0.1.dist-info}/licenses/LICENSE +0 -0
- {kekikstream-1.9.9.dist-info → kekikstream-2.0.1.dist-info}/top_level.txt +0 -0
|
@@ -17,13 +17,13 @@ class ExtractorBase(ABC):
|
|
|
17
17
|
self.cloudscraper = CloudScraper()
|
|
18
18
|
|
|
19
19
|
# httpx - lightweight and safe for most HTTP requests
|
|
20
|
-
self.httpx = AsyncClient(
|
|
21
|
-
timeout = 3,
|
|
22
|
-
follow_redirects = True
|
|
23
|
-
)
|
|
20
|
+
self.httpx = AsyncClient(timeout = 10)
|
|
24
21
|
self.httpx.headers.update(self.cloudscraper.headers)
|
|
25
22
|
self.httpx.cookies.update(self.cloudscraper.cookies)
|
|
26
|
-
self.httpx.headers.update({
|
|
23
|
+
self.httpx.headers.update({
|
|
24
|
+
"User-Agent" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 15.7; rv:135.0) Gecko/20100101 Firefox/135.0",
|
|
25
|
+
"Accept" : "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
|
|
26
|
+
})
|
|
27
27
|
|
|
28
28
|
def can_handle_url(self, url: str) -> bool:
|
|
29
29
|
# URL'nin bu çıkarıcı tarafından işlenip işlenemeyeceğini kontrol et
|
|
@@ -19,19 +19,22 @@ class ExtractorLoader:
|
|
|
19
19
|
def load_all(self) -> list[ExtractorBase]:
|
|
20
20
|
extractors = []
|
|
21
21
|
|
|
22
|
-
#
|
|
23
|
-
if self.global_extractors_dir.exists():
|
|
24
|
-
# konsol.log(f"[green][*] Global Extractor dizininden yükleniyor: {self.global_extractors_dir}[/green]")
|
|
25
|
-
global_extractors = self._load_from_directory(self.global_extractors_dir)
|
|
26
|
-
# konsol.log(f"[green]Global Extractor'lar: {[e.__name__ for e in global_extractors]}[/green]")
|
|
27
|
-
extractors.extend(global_extractors)
|
|
28
|
-
|
|
29
|
-
# Yerel çıkarıcıları yükle
|
|
22
|
+
# Eğer yerel dizinde Extractor varsa, sadece onları yükle (eklenti geliştirme modu)
|
|
30
23
|
if self.local_extractors_dir.exists():
|
|
31
24
|
# konsol.log(f"[green][*] Yerel Extractor dizininden yükleniyor: {self.local_extractors_dir}[/green]")
|
|
32
25
|
local_extractors = self._load_from_directory(self.local_extractors_dir)
|
|
33
26
|
# konsol.log(f"[green]Yerel Extractor'lar: {[e.__name__ for e in local_extractors]}[/green]")
|
|
34
|
-
|
|
27
|
+
|
|
28
|
+
if local_extractors:
|
|
29
|
+
# konsol.log("[cyan][*] Yerel Extractor bulundu, global Extractor'lar atlanıyor (eklenti geliştirme modu)[/cyan]")
|
|
30
|
+
extractors.extend(local_extractors)
|
|
31
|
+
|
|
32
|
+
# Yerel dizinde Extractor yoksa, global'leri yükle
|
|
33
|
+
if not extractors and self.global_extractors_dir.exists():
|
|
34
|
+
# konsol.log(f"[green][*] Global Extractor dizininden yükleniyor: {self.global_extractors_dir}[/green]")
|
|
35
|
+
global_extractors = self._load_from_directory(self.global_extractors_dir)
|
|
36
|
+
# konsol.log(f"[green]Global Extractor'lar: {[e.__name__ for e in global_extractors]}[/green]")
|
|
37
|
+
extractors.extend(global_extractors)
|
|
35
38
|
|
|
36
39
|
# Benzersizliği sağlama (modül adı + sınıf adı bazında)
|
|
37
40
|
unique_extractors = []
|
|
@@ -57,9 +60,10 @@ class ExtractorLoader:
|
|
|
57
60
|
if file.endswith(".py") and not file.startswith("__"):
|
|
58
61
|
module_name = file[:-3] # .py uzantısını kaldır
|
|
59
62
|
# konsol.log(f"[cyan]Okunan Dosya\t\t: {module_name}[/cyan]")
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
+
module_extractors = self._load_extractor(directory, module_name)
|
|
64
|
+
if module_extractors:
|
|
65
|
+
# konsol.log(f"[magenta]Extractor Yüklendi\t: {[e.__name__ for e in module_extractors]}[/magenta]")
|
|
66
|
+
extractors.extend(module_extractors)
|
|
63
67
|
|
|
64
68
|
# konsol.log(f"[yellow]{directory} dizininden yüklenen Extractor'lar: {[e.__name__ for e in extractors]}[/yellow]")
|
|
65
69
|
return extractors
|
|
@@ -70,21 +74,25 @@ class ExtractorLoader:
|
|
|
70
74
|
path = directory / f"{module_name}.py"
|
|
71
75
|
spec = importlib.util.spec_from_file_location(module_name, path)
|
|
72
76
|
if not spec or not spec.loader:
|
|
73
|
-
return
|
|
77
|
+
return []
|
|
74
78
|
|
|
75
79
|
# Modülü içe aktar
|
|
76
80
|
module = importlib.util.module_from_spec(spec)
|
|
77
81
|
spec.loader.exec_module(module)
|
|
78
82
|
|
|
79
|
-
# Yalnızca doğru modülden gelen ExtractorBase sınıflarını yükle
|
|
83
|
+
# Yalnızca doğru modülden gelen ExtractorBase sınıflarını yükle (TÜM CLASS'LAR)
|
|
84
|
+
extractors = []
|
|
80
85
|
for attr in dir(module):
|
|
81
86
|
obj = getattr(module, attr)
|
|
82
|
-
|
|
87
|
+
# isinstance kontrolünü __module__ kontrolünden ÖNCE yap
|
|
88
|
+
if isinstance(obj, type) and issubclass(obj, ExtractorBase) and obj is not ExtractorBase and obj.__module__ == module_name:
|
|
83
89
|
# konsol.log(f"[green]Yüklenen sınıf\t\t: {module_name}.{obj.__name__} ({obj.__module__}.{obj.__name__})[/green]")
|
|
84
|
-
|
|
90
|
+
extractors.append(obj)
|
|
91
|
+
|
|
92
|
+
return extractors
|
|
85
93
|
|
|
86
94
|
except Exception as hata:
|
|
87
95
|
konsol.log(f"[red][!] Extractor yüklenirken hata oluştu: {module_name}\nHata: {hata}")
|
|
88
96
|
konsol.print(f"[dim]{traceback.format_exc()}[/dim]")
|
|
89
97
|
|
|
90
|
-
return
|
|
98
|
+
return []
|
|
@@ -34,7 +34,10 @@ class PluginBase(ABC):
|
|
|
34
34
|
)
|
|
35
35
|
self.httpx.headers.update(self.cloudscraper.headers)
|
|
36
36
|
self.httpx.cookies.update(self.cloudscraper.cookies)
|
|
37
|
-
self.httpx.headers.update({
|
|
37
|
+
self.httpx.headers.update({
|
|
38
|
+
"User-Agent" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 15.7; rv:135.0) Gecko/20100101 Firefox/135.0",
|
|
39
|
+
"Accept" : "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
|
|
40
|
+
})
|
|
38
41
|
|
|
39
42
|
self.media_handler = MediaHandler()
|
|
40
43
|
self.ex_manager = ExtractorManager()
|
|
@@ -19,15 +19,19 @@ class PluginLoader:
|
|
|
19
19
|
def load_all(self) -> dict[str, PluginBase]:
|
|
20
20
|
plugins = {}
|
|
21
21
|
|
|
22
|
-
#
|
|
23
|
-
if self.global_plugins_dir.exists():
|
|
24
|
-
# konsol.log(f"[green][*] Global Eklenti dizininden yükleniyor: {self.global_plugins_dir}[/green]")
|
|
25
|
-
plugins |= self._load_from_directory(self.global_plugins_dir)
|
|
26
|
-
|
|
27
|
-
# Yerel eklentileri yükle
|
|
22
|
+
# Eğer yerel dizinde Plugin varsa, sadece onları yükle (eklenti geliştirme modu)
|
|
28
23
|
if self.local_plugins_dir.exists():
|
|
29
24
|
# konsol.log(f"[green][*] Yerel Eklenti dizininden yükleniyor: {self.local_plugins_dir}[/green]")
|
|
30
|
-
|
|
25
|
+
local_plugins = self._load_from_directory(self.local_plugins_dir)
|
|
26
|
+
|
|
27
|
+
if local_plugins:
|
|
28
|
+
# konsol.log("[cyan][*] Yerel Plugin bulundu, global Plugin'ler atlanıyor (eklenti geliştirme modu)[/cyan]")
|
|
29
|
+
plugins |= local_plugins
|
|
30
|
+
|
|
31
|
+
# Yerel dizinde Plugin yoksa, global'leri yükle
|
|
32
|
+
if not plugins and self.global_plugins_dir.exists():
|
|
33
|
+
# konsol.log(f"[green][*] Global Eklenti dizininden yükleniyor: {self.global_plugins_dir}[/green]")
|
|
34
|
+
plugins |= self._load_from_directory(self.global_plugins_dir)
|
|
31
35
|
|
|
32
36
|
if not plugins:
|
|
33
37
|
konsol.print("[yellow][!] Yüklenecek bir Eklenti bulunamadı![/yellow]")
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
|
+
|
|
3
|
+
from KekikStream.Extractors.ContentX import ContentX
|
|
4
|
+
|
|
5
|
+
# DPlayer82 Family - https://dplayer82.site subdomains
|
|
6
|
+
class SNDPlayer(ContentX):
|
|
7
|
+
name = "SNDPlayer"
|
|
8
|
+
main_url = "https://sn.dplayer82.site"
|
|
9
|
+
|
|
10
|
+
class FourDPlayer(ContentX):
|
|
11
|
+
name = "FourDPlayer"
|
|
12
|
+
main_url = "https://four.dplayer82.site"
|
|
13
|
+
|
|
14
|
+
class ORGDPlayer(ContentX):
|
|
15
|
+
name = "ORGDPlayer"
|
|
16
|
+
main_url = "https://org.dplayer82.site"
|
|
17
|
+
|
|
18
|
+
# Hotlinger
|
|
19
|
+
class Hotlinger(ContentX):
|
|
20
|
+
name = "Hotlinger"
|
|
21
|
+
main_url = "https://hotlinger.com"
|
|
22
|
+
|
|
23
|
+
# Pichive Family
|
|
24
|
+
class Pichive(ContentX):
|
|
25
|
+
name = "Pichive"
|
|
26
|
+
main_url = "https://pichive.me"
|
|
27
|
+
|
|
28
|
+
class FourPichive(ContentX):
|
|
29
|
+
name = "FourPichive"
|
|
30
|
+
main_url = "https://four.pichive.me"
|
|
31
|
+
|
|
32
|
+
# PlayRu Family
|
|
33
|
+
class FourPlayRu(ContentX):
|
|
34
|
+
name = "FourPlayRu"
|
|
35
|
+
main_url = "https://four.playru.net"
|
|
36
|
+
|
|
37
|
+
# CX Family
|
|
38
|
+
class FourCX(ContentX):
|
|
39
|
+
name = "FourCX"
|
|
40
|
+
main_url = "https://four.contentx.me"
|
KekikStream/Plugins/Dizilla.py
CHANGED
|
@@ -137,7 +137,7 @@ class Dizilla(PluginBase):
|
|
|
137
137
|
year = veri.get("datePublished").split("-")[0]
|
|
138
138
|
|
|
139
139
|
# Tags extraction from page content (h3 tag)
|
|
140
|
-
tags_raw = secici.css("
|
|
140
|
+
tags_raw = secici.css("div.poster.poster h3::text").get()
|
|
141
141
|
tags = [t.strip() for t in tags_raw.split(",")] if tags_raw else []
|
|
142
142
|
|
|
143
143
|
rating = veri.get("aggregateRating", {}).get("ratingValue")
|
|
@@ -83,6 +83,7 @@ class FilmMakinesi(PluginBase):
|
|
|
83
83
|
rating = rating.strip().split()[0]
|
|
84
84
|
year = secici.css("span.date a::text").get().strip()
|
|
85
85
|
actors = secici.css("div.cast-name::text").getall()
|
|
86
|
+
tags = secici.css("div.genre a::text").getall()
|
|
86
87
|
duration = secici.css("div.time::text").get()
|
|
87
88
|
if duration:
|
|
88
89
|
duration = duration.split()[1].strip()
|
|
@@ -92,6 +93,7 @@ class FilmMakinesi(PluginBase):
|
|
|
92
93
|
poster = self.fix_url(poster),
|
|
93
94
|
title = self.clean_title(title),
|
|
94
95
|
description = description,
|
|
96
|
+
tags = tags,
|
|
95
97
|
rating = rating,
|
|
96
98
|
year = year,
|
|
97
99
|
actors = actors,
|
|
@@ -74,8 +74,15 @@ class JetFilmizle(PluginBase):
|
|
|
74
74
|
rating_raw = secici.css("section.movie-exp div.imdb_puan span::text").get()
|
|
75
75
|
rating = rating_raw.strip() if rating_raw else None
|
|
76
76
|
|
|
77
|
-
|
|
78
|
-
|
|
77
|
+
|
|
78
|
+
# Year - div.yap içinde 4 haneli sayı ara
|
|
79
|
+
year_div = secici.xpath("//div[@class='yap' and (contains(., 'Vizyon') or contains(., 'Yapım'))]/text()").get()
|
|
80
|
+
year = None
|
|
81
|
+
if year_div:
|
|
82
|
+
year_match = re.search(r'(\d{4})', year_div.strip())
|
|
83
|
+
if year_match:
|
|
84
|
+
year = year_match.group(1)
|
|
85
|
+
|
|
79
86
|
actors = secici.css("div[itemprop='actor'] a span::text").getall()
|
|
80
87
|
|
|
81
88
|
return MovieInfo(
|
|
@@ -93,42 +100,50 @@ class JetFilmizle(PluginBase):
|
|
|
93
100
|
istek = await self.httpx.get(url)
|
|
94
101
|
secici = Selector(istek.text)
|
|
95
102
|
|
|
96
|
-
|
|
97
|
-
if main_iframe := secici.css("div#movie iframe::attr(data-src), div#movie iframe::attr(data), div#movie iframe::attr(src)").get():
|
|
98
|
-
iframes.append(self.fix_url(main_iframe))
|
|
103
|
+
results = []
|
|
99
104
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
105
|
+
# 1) Ana iframe'leri kontrol et
|
|
106
|
+
for iframe in secici.css("iframe"):
|
|
107
|
+
src = (iframe.css("::attr(src)").get() or
|
|
108
|
+
iframe.css("::attr(data-src)").get() or
|
|
109
|
+
iframe.css("::attr(data-lazy-src)").get())
|
|
110
|
+
|
|
111
|
+
if src and src != "about:blank":
|
|
112
|
+
iframe_url = self.fix_url(src)
|
|
113
|
+
extractor = self.ex_manager.find_extractor(iframe_url)
|
|
114
|
+
results.append({
|
|
115
|
+
"url": iframe_url,
|
|
116
|
+
"name": extractor.name if extractor else "Ana Player"
|
|
117
|
+
})
|
|
118
|
+
|
|
119
|
+
# 2) Sayfa numaralarından linkleri topla (Fragman hariç)
|
|
120
|
+
page_links = []
|
|
121
|
+
for link in secici.css("a.post-page-numbers"):
|
|
122
|
+
isim = link.css("span::text").get() or ""
|
|
123
|
+
if isim != "Fragman":
|
|
124
|
+
href = link.css("::attr(href)").get()
|
|
125
|
+
if href:
|
|
126
|
+
page_links.append((self.fix_url(href), isim))
|
|
127
|
+
|
|
128
|
+
# 3) Her sayfa linkindeki iframe'leri bul
|
|
129
|
+
for page_url, isim in page_links:
|
|
130
|
+
try:
|
|
131
|
+
page_resp = await self.httpx.get(page_url)
|
|
132
|
+
page_sel = Selector(page_resp.text)
|
|
133
|
+
|
|
134
|
+
for iframe in page_sel.css("div#movie iframe"):
|
|
135
|
+
src = (iframe.css("::attr(src)").get() or
|
|
136
|
+
iframe.css("::attr(data-src)").get() or
|
|
137
|
+
iframe.css("::attr(data-lazy-src)").get())
|
|
138
|
+
|
|
139
|
+
if src and src != "about:blank":
|
|
140
|
+
iframe_url = self.fix_url(src)
|
|
141
|
+
extractor = self.ex_manager.find_extractor(iframe_url)
|
|
142
|
+
results.append({
|
|
143
|
+
"url": iframe_url,
|
|
144
|
+
"name": f"{extractor.name if extractor else 'Player'} | {isim}"
|
|
145
|
+
})
|
|
146
|
+
except Exception:
|
|
103
147
|
continue
|
|
104
148
|
|
|
105
|
-
part_istek = await self.httpx.get(part_href)
|
|
106
|
-
part_secici = Selector(part_istek.text)
|
|
107
|
-
|
|
108
|
-
if iframe := part_secici.css("div#movie iframe::attr(data-src), div#movie iframe::attr(data), div#movie iframe::attr(src)").get():
|
|
109
|
-
iframes.append(self.fix_url(iframe))
|
|
110
|
-
else:
|
|
111
|
-
for link in part_secici.css("div#movie p a"):
|
|
112
|
-
if download_link := link.attrib.get("href"):
|
|
113
|
-
iframes.append(self.fix_url(download_link))
|
|
114
|
-
|
|
115
|
-
processed_iframes = []
|
|
116
|
-
for iframe in iframes:
|
|
117
|
-
if "jetv.xyz" in iframe:
|
|
118
|
-
jetv_istek = await self.httpx.get(iframe)
|
|
119
|
-
jetv_secici = Selector(jetv_istek.text)
|
|
120
|
-
|
|
121
|
-
if jetv_iframe := jetv_secici.css("iframe::attr(src)").get():
|
|
122
|
-
processed_iframes.append(self.fix_url(jetv_iframe))
|
|
123
|
-
else:
|
|
124
|
-
processed_iframes.append(iframe)
|
|
125
|
-
|
|
126
|
-
results = []
|
|
127
|
-
for idx, iframe in enumerate(processed_iframes):
|
|
128
|
-
extractor = self.ex_manager.find_extractor(iframe)
|
|
129
|
-
results.append({
|
|
130
|
-
"url" : iframe,
|
|
131
|
-
"name" : f"{extractor.name if extractor else f'Player {idx + 1}'}"
|
|
132
|
-
})
|
|
133
|
-
|
|
134
149
|
return results
|
KekikStream/Plugins/Sinefy.py
CHANGED
|
@@ -153,6 +153,7 @@ class Sinefy(PluginBase):
|
|
|
153
153
|
tags = sel.css("div.item.categories a::text").getall()
|
|
154
154
|
rating = sel.css("span.color-imdb::text").get()
|
|
155
155
|
actors = sel.css("div.content h5::text").getall()
|
|
156
|
+
year = sel.css("span.item.year::text").get() # Year bilgisi eklendi
|
|
156
157
|
|
|
157
158
|
episodes = []
|
|
158
159
|
season_elements = sel.css("section.episodes-box")
|
|
@@ -207,6 +208,7 @@ class Sinefy(PluginBase):
|
|
|
207
208
|
rating = rating,
|
|
208
209
|
tags = tags,
|
|
209
210
|
actors = actors,
|
|
211
|
+
year = year,
|
|
210
212
|
episodes = episodes
|
|
211
213
|
)
|
|
212
214
|
else:
|
|
@@ -217,7 +219,8 @@ class Sinefy(PluginBase):
|
|
|
217
219
|
description = description,
|
|
218
220
|
rating = rating,
|
|
219
221
|
tags = tags,
|
|
220
|
-
actors = actors
|
|
222
|
+
actors = actors,
|
|
223
|
+
year = year
|
|
221
224
|
)
|
|
222
225
|
|
|
223
226
|
async def load_links(self, url: str) -> list[dict]:
|
KekikStream/Plugins/Sinezy.py
CHANGED
|
@@ -94,6 +94,20 @@ class Sinezy(PluginBase):
|
|
|
94
94
|
|
|
95
95
|
tags = sel.css("div.detail span a::text").getall()
|
|
96
96
|
actors = sel.css("span.oyn p::text").getall() # Might need splitting logic
|
|
97
|
+
|
|
98
|
+
year = None
|
|
99
|
+
info_text = sel.css("span.info::text").get()
|
|
100
|
+
if info_text:
|
|
101
|
+
year_match = re.search(r'\b(19\d{2}|20\d{2})\b', info_text)
|
|
102
|
+
if year_match:
|
|
103
|
+
year = year_match.group(1)
|
|
104
|
+
|
|
105
|
+
# Bulunamadıysa tüm sayfada ara
|
|
106
|
+
if not year:
|
|
107
|
+
all_text = " ".join(sel.css("::text").getall())
|
|
108
|
+
year_match = re.search(r'\b(19\d{2}|20\d{2})\b', all_text)
|
|
109
|
+
if year_match:
|
|
110
|
+
year = year_match.group(1)
|
|
97
111
|
|
|
98
112
|
return MovieInfo(
|
|
99
113
|
title = title,
|
|
@@ -102,7 +116,8 @@ class Sinezy(PluginBase):
|
|
|
102
116
|
description = description,
|
|
103
117
|
tags = tags,
|
|
104
118
|
rating = rating,
|
|
105
|
-
actors = actors
|
|
119
|
+
actors = actors,
|
|
120
|
+
year = year
|
|
106
121
|
)
|
|
107
122
|
|
|
108
123
|
async def load_links(self, url: str) -> list[dict]:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: KekikStream
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.1
|
|
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
|
|
@@ -235,6 +235,32 @@ KekikStream/
|
|
|
235
235
|
3. `get_main_page`, `search`, `load_item`, `load_links` metodlarını implemente edin.
|
|
236
236
|
4. Plugin'i test edin (örnek: `Tests/Single.py`).
|
|
237
237
|
|
|
238
|
+
### 🔧 Geliştirme Modu
|
|
239
|
+
|
|
240
|
+
KekikStream, eklenti geliştiricileri için otomatik bir **geliştirme modu** sunar:
|
|
241
|
+
|
|
242
|
+
**Plugin Geliştirme:**
|
|
243
|
+
- Çalışma dizininde `Plugins/` klasörü oluşturup içine plugin dosyası eklerseniz, **sadece bu local plugin'ler** yüklenir
|
|
244
|
+
- Global plugin'ler (sisteme kurulu olanlar) otomatik olarak atlanır
|
|
245
|
+
- Bu sayede test sırasında diğer plugin'lerle karışma olmaz
|
|
246
|
+
|
|
247
|
+
**Extractor Geliştirme:**
|
|
248
|
+
- Çalışma dizininde `Extractors/` klasörü oluşturup içine extractor dosyası eklerseniz, **sadece bu local extractor'lar** yüklenir
|
|
249
|
+
- Global extractor'lar otomatik olarak atlanır
|
|
250
|
+
- Kendi extractor'ınızı izole bir ortamda test edebilirsiniz
|
|
251
|
+
|
|
252
|
+
**Örnek:**
|
|
253
|
+
```bash
|
|
254
|
+
# Çalışma dizininizde
|
|
255
|
+
mkdir Plugins
|
|
256
|
+
touch Plugins/MyTestPlugin.py # Plugin'inizi yazın
|
|
257
|
+
|
|
258
|
+
# KekikStream'i çalıştırın - sadece MyTestPlugin yüklenecek
|
|
259
|
+
KekikStream
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
> 💡 **Not:** Yerel dizinde herhangi bir Plugin/Extractor dosyası bulunmazsa, sistem normal şekilde global olanları yükler.
|
|
263
|
+
|
|
238
264
|
---
|
|
239
265
|
|
|
240
266
|
## 📊 Performans
|
|
@@ -4,42 +4,37 @@ KekikStream/requirements.txt,sha256=0fO-7byqgLMr4NyJO7fQBFOnLv0zcAeqk7tLhHXqonk,
|
|
|
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=
|
|
8
|
-
KekikStream/Core/Extractor/ExtractorLoader.py,sha256=
|
|
9
|
-
KekikStream/Core/Extractor/ExtractorManager.py,sha256=
|
|
7
|
+
KekikStream/Core/Extractor/ExtractorBase.py,sha256=_9l0VIZpFHBdzVLI_hp1RQRf4CmsxrTt-FIKEaF1Z04,1824
|
|
8
|
+
KekikStream/Core/Extractor/ExtractorLoader.py,sha256=GPGCmgFpDBywR8CsNw43-ddseZhSKTjAUETp1Ohbi6E,4796
|
|
9
|
+
KekikStream/Core/Extractor/ExtractorManager.py,sha256=VYkj4CCE5Puqsr6PCeN8i_OS0hfYKI4NScj98BLO39o,2644
|
|
10
10
|
KekikStream/Core/Extractor/ExtractorModels.py,sha256=Qj_gbIeGRewaZXNfYkTi4FFRRq6XBOc0HS0tXGDwajI,445
|
|
11
11
|
KekikStream/Core/Media/MediaHandler.py,sha256=MEn3spPAThVloN3WcoCwWhpoyMA7tAZvcwYjmjJsX3U,7678
|
|
12
12
|
KekikStream/Core/Media/MediaManager.py,sha256=AaUq2D7JSJIphjoAj2fjLOJjswm7Qf5hjYCbBdrbnDU,438
|
|
13
|
-
KekikStream/Core/Plugin/PluginBase.py,sha256=
|
|
14
|
-
KekikStream/Core/Plugin/PluginLoader.py,sha256=
|
|
13
|
+
KekikStream/Core/Plugin/PluginBase.py,sha256=xR1J6unUDpUNe_fHRtZSryEbAPdf-qdT3LpMsjT_kBk,4126
|
|
14
|
+
KekikStream/Core/Plugin/PluginLoader.py,sha256=GcDqN1u3nJeoGKH_oDFHCpwteJlLCxHNbmPrC5L-hZE,3692
|
|
15
15
|
KekikStream/Core/Plugin/PluginManager.py,sha256=CZVg1eegi8vfMfccx0DRV0Box8kXz-aoULTQLgbPbvM,893
|
|
16
16
|
KekikStream/Core/Plugin/PluginModels.py,sha256=Yvx-6Fkn8QCIcuqAkFbCP5EJcq3XBkK_P8S0tRNhS6E,2476
|
|
17
17
|
KekikStream/Core/UI/UIManager.py,sha256=T4V_kdTTWa-UDamgLSKa__dWJuzcvRK9NuwBlzU9Bzc,1693
|
|
18
|
-
KekikStream/Extractors/CloseLoad.py,sha256=
|
|
18
|
+
KekikStream/Extractors/CloseLoad.py,sha256=rc1lYy32ThB4ApC1hZdqVQ3cAVHvRGHOMdjomWeDgaQ,884
|
|
19
19
|
KekikStream/Extractors/ContentX.py,sha256=u1sDdM79MNx9OdPTPcAA0OQDS7537IO8aJlffxhMi8c,2976
|
|
20
|
+
KekikStream/Extractors/ContentX_.py,sha256=OGFRq-GVjFqz7ISL9UPLonmjzPS2ycb0En0PI7gVKtk,1016
|
|
20
21
|
KekikStream/Extractors/DzenRu.py,sha256=X0Rhm1-W4YjQwVrJs8YFqVcCxMaZi8rsKiLhK_ZsYlU,1185
|
|
21
22
|
KekikStream/Extractors/ExPlay.py,sha256=EJNVKAbaIxlbOsCx7J9aLfNHKOFoqSLZZUw7W4QYeH0,1827
|
|
22
23
|
KekikStream/Extractors/FirePlayer.py,sha256=HlJjFgii0fGZK7cgwpoZAIoajabl7IQX6ZrAQT1fBIw,2188
|
|
23
|
-
KekikStream/Extractors/FourCX.py,sha256=4FrMj1IZBBpN_g1P6S3A-8eUu7QFwlt4fJXzJ7vfe0Q,221
|
|
24
|
-
KekikStream/Extractors/FourPichive.py,sha256=iq3BCUbih1UVF4y4BIWO--0hX5jP2nxqesNx3MGP3kQ,234
|
|
25
|
-
KekikStream/Extractors/FourPlayRu.py,sha256=wq1ylxKpsO_IBoYr_ALzB2dVrQpJ-jY9lf2zPhcAZX8,228
|
|
26
24
|
KekikStream/Extractors/HDPlayerSystem.py,sha256=EgnFzx5Q4PkuwAtuff5SYU9k59B-CyOdySl7lbCZ9hM,1312
|
|
27
|
-
KekikStream/Extractors/HDStreamAble.py,sha256=66n5EvIdX_or5cdnlJ_Uqmzi50n4rl9c5VCw8kBqhQk,245
|
|
28
|
-
KekikStream/Extractors/Hotlinger.py,sha256=NFMRgUmb6BCrJfa7Hi0VarDNYvCeVknBWEk24FKBBa0,224
|
|
29
25
|
KekikStream/Extractors/JetTv.py,sha256=aA3WeOvR-tszac-WSwunZZb1NRy25TQH8vxY3TDscRI,1596
|
|
30
26
|
KekikStream/Extractors/MailRu.py,sha256=xQVCWwYqNoG5T43VAW1_m0v4e80FbO-1pNPKkwhTccU,1218
|
|
31
27
|
KekikStream/Extractors/MixPlayHD.py,sha256=POV_yq3KoZ6S6EqFsKYULEBz92NdUa2BpYKNo0eNQH8,1552
|
|
32
28
|
KekikStream/Extractors/MixTiger.py,sha256=mMEYhhr5-u6GgIrLESeFTRdwDykgSXKJO4KtkMML1bw,2124
|
|
33
29
|
KekikStream/Extractors/MolyStream.py,sha256=IeeBw9tJJrL5QQ-t2Yp-a-6lnDc3Y00UNiaN6m-o-7c,1160
|
|
34
30
|
KekikStream/Extractors/Odnoklassniki.py,sha256=EQAuCdr69vN11ZBE5uThuXqlR8NVWanROWYkubo22mo,3809
|
|
35
|
-
KekikStream/Extractors/
|
|
36
|
-
KekikStream/Extractors/OkRuSSL.py,sha256=FHJ5XZ1dO5ED3mIku3e3vnq8K0slrcr0jqhaUnHmfVk,227
|
|
31
|
+
KekikStream/Extractors/Odnoklassniki_.py,sha256=AbcJ65Pq1zA2wQGXZNgNBToweOniFYR3jkWXFXJJpfg,316
|
|
37
32
|
KekikStream/Extractors/PeaceMakerst.py,sha256=ZKk454eNZpeamht61UH9yMYe00_zGb3MSyujfDlbVDc,2096
|
|
38
|
-
KekikStream/Extractors/
|
|
33
|
+
KekikStream/Extractors/PeaceMakerst_.py,sha256=-PdSR8yFy6MEc6EodXvHksj8O_j6Xu8yceoSjM2pGYg,246
|
|
39
34
|
KekikStream/Extractors/PixelDrain.py,sha256=Uk2pPvtBzaKtRXu1iNO8FLHd0EAuIOIzI1H_n02tg-U,964
|
|
40
|
-
KekikStream/Extractors/PlayRu.py,sha256=DQMZyCSJwLkrh-gfDD8T1DvUFNBAKUXpByeCAWuK6YY,215
|
|
41
35
|
KekikStream/Extractors/PlayerFilmIzle.py,sha256=vDumIya3gWN8h1to5XCzBWePa6gdNU2DVTK3OrPr04U,2425
|
|
42
36
|
KekikStream/Extractors/RapidVid.py,sha256=TxNnLUmYaAHi-rFkoLu4eQULzkUSvQnfoEZAjyzQFns,2917
|
|
37
|
+
KekikStream/Extractors/RapidVid_.py,sha256=siYK1oDCASzV8MhhDbGh5qlSDtZLi4EHNlO0HwdgeNU,233
|
|
43
38
|
KekikStream/Extractors/SetPlay.py,sha256=FsbLlYFXp7_28-ta6XAoqDQAEGYTVZOZayebkY1mWe8,1906
|
|
44
39
|
KekikStream/Extractors/SetPrime.py,sha256=ob09y-Sm91YR7rIRzikhZiMHX6D4Djm5QzFTg6KbO4k,1536
|
|
45
40
|
KekikStream/Extractors/SibNet.py,sha256=zJTkzlr34ufKCWzKKCgJrzhb2o-fpjTjFdi38gv6N6g,849
|
|
@@ -50,7 +45,7 @@ KekikStream/Extractors/TurboImgz.py,sha256=nnWnP1K4JZbMj6S-YuXxej31UZtF4JcboSW4n
|
|
|
50
45
|
KekikStream/Extractors/TurkeyPlayer.py,sha256=FX_H3vzXjAD7IjK11bjJVVw_VdPQ4n6YQLfjQ6E3t7o,1247
|
|
51
46
|
KekikStream/Extractors/VidHide.py,sha256=TVoS9CMV1WSE83vPC4FFxsNE71n-_DtVJm66_1Wt8pU,2538
|
|
52
47
|
KekikStream/Extractors/VidMoly.py,sha256=bxzIymYHrms4gBdK2jfsoug2tjq-PuicOxeR2NjcAjw,3654
|
|
53
|
-
KekikStream/Extractors/
|
|
48
|
+
KekikStream/Extractors/VidMoly_.py,sha256=737BzqogzknVhSebZgVDh70gsEgNo9s2mafySrDzr6o,219
|
|
54
49
|
KekikStream/Extractors/VidMoxy.py,sha256=LT7wTKBtuuagXwfGjWZwQF2NQGuChurZJ-I6gM0Jcek,1771
|
|
55
50
|
KekikStream/Extractors/VidPapi.py,sha256=g9ohdL9VJrxy4N7xerbIRz3ZxjsXFHlJWy0NaZ31hFY,3259
|
|
56
51
|
KekikStream/Extractors/VideoSeyred.py,sha256=M6QPZ_isX9vM_7LPo-2I_8Cf1vB9awHw8vvzBODtoiQ,1977
|
|
@@ -59,28 +54,28 @@ KekikStream/Extractors/YildizKisaFilm.py,sha256=R_JlrOVeMiDlXYcuTdItnKvidyx8_u3B
|
|
|
59
54
|
KekikStream/Plugins/DiziBox.py,sha256=sxM7ckKeKwMrMkRNUAvh5wE9wdOuVda6Ag_zAdwSvi8,9935
|
|
60
55
|
KekikStream/Plugins/DiziPal.py,sha256=MBONjermWBm3sN-8ZSILnfXI2F_V2kH65gpTNOuL9dI,10198
|
|
61
56
|
KekikStream/Plugins/DiziYou.py,sha256=xE0INtCLOZDo73sWQoYT6Su8T66hGK9rBD-gXnk8MiU,9016
|
|
62
|
-
KekikStream/Plugins/Dizilla.py,sha256=
|
|
57
|
+
KekikStream/Plugins/Dizilla.py,sha256=gVLborMFjYr3w_KrB53lmB1W8lTzEAySHjv4gvOZp1A,11542
|
|
63
58
|
KekikStream/Plugins/FilmBip.py,sha256=Tfx2dUc1Qs7ZQoJtsBtjOJXCKmTe56m74lNhuUYYU14,6182
|
|
64
|
-
KekikStream/Plugins/FilmMakinesi.py,sha256=
|
|
59
|
+
KekikStream/Plugins/FilmMakinesi.py,sha256=lYys9qyoIxDFBWaf7TIv9NrdmtGu_GLU1VJWGp6xL9A,5280
|
|
65
60
|
KekikStream/Plugins/FilmModu.py,sha256=b27hchMoYZwG3I-kM1sveW7rHKOF5OuepdjPgKIehEM,6706
|
|
66
61
|
KekikStream/Plugins/FullHDFilm.py,sha256=kkb-JtWf23uiEzP9f_uds0tROYiKOyxcX0D-jNtQFi0,7005
|
|
67
62
|
KekikStream/Plugins/FullHDFilmizlesene.py,sha256=FAacwtXo72DIl_1bHWgHPIxqmqBJAVPtNQ3yIZPYjlU,6152
|
|
68
63
|
KekikStream/Plugins/HDFilmCehennemi.py,sha256=D2VvgNvCcHfjkitzSfA19OFp-mI0sgUm6OSVej0ZgTY,9544
|
|
69
|
-
KekikStream/Plugins/JetFilmizle.py,sha256=
|
|
64
|
+
KekikStream/Plugins/JetFilmizle.py,sha256=GU47RGHzVmnJxdHDD1zWQDu2qCCWQ3vFOs_eRR_YY14,6503
|
|
70
65
|
KekikStream/Plugins/KultFilmler.py,sha256=VZET3RUoOVYKE-C2YbkMW8oNcxz6zE2pR7a3z-B4nD4,8987
|
|
71
66
|
KekikStream/Plugins/RecTV.py,sha256=dF3Ogf7KE_zpfLQRjVcEJQMuWtBtHo6iB73_ECQEJ58,7544
|
|
72
67
|
KekikStream/Plugins/RoketDizi.py,sha256=h0g0Wi72TG4et7TS7ANro9LLlCiR_W0CJdkWCUzprE8,9027
|
|
73
68
|
KekikStream/Plugins/SelcukFlix.py,sha256=WYVtGMxngpqrXk7PX_B4ya6Pji7dOjQsXoukk30f2d0,12744
|
|
74
69
|
KekikStream/Plugins/SezonlukDizi.py,sha256=dT2xPPkdaYV43qsL4Le_5Yel8eoPkHtnXIOXqz-Ya-c,6326
|
|
75
70
|
KekikStream/Plugins/SineWix.py,sha256=xdTeg8GHUpyZsY6EQ5I1ZIT4-lB_qwBwvHQVmdMPpEI,7364
|
|
76
|
-
KekikStream/Plugins/Sinefy.py,sha256=
|
|
71
|
+
KekikStream/Plugins/Sinefy.py,sha256=jeziEG92EyePCejTdeKkNtMxg0-nkhrofazwNX12Y7c,9902
|
|
77
72
|
KekikStream/Plugins/SinemaCX.py,sha256=dEoZJJLnTgayBeCbGoR1qSUjrnTeRx5ZLck_dSPDL4c,7177
|
|
78
|
-
KekikStream/Plugins/Sinezy.py,sha256=
|
|
73
|
+
KekikStream/Plugins/Sinezy.py,sha256=gdszlee5QpUka0qMzGMbBoXwJCtZbe5hlA5o9FJQI1o,6226
|
|
79
74
|
KekikStream/Plugins/SuperFilmGeldi.py,sha256=Ohm21BPsJH_S1tx5i2APEgAOD25k2NiwRP7rSgAKvRs,5289
|
|
80
75
|
KekikStream/Plugins/UgurFilm.py,sha256=eKGzmSi8k_QbXnYPWXZRdmCxxc32zZh4rynmdxCbm1o,4832
|
|
81
|
-
kekikstream-
|
|
82
|
-
kekikstream-
|
|
83
|
-
kekikstream-
|
|
84
|
-
kekikstream-
|
|
85
|
-
kekikstream-
|
|
86
|
-
kekikstream-
|
|
76
|
+
kekikstream-2.0.1.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
77
|
+
kekikstream-2.0.1.dist-info/METADATA,sha256=c8nPKpK2FHnT8s4TRs4CELzavGnIsBF-I4KUkR0GbOo,10090
|
|
78
|
+
kekikstream-2.0.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
79
|
+
kekikstream-2.0.1.dist-info/entry_points.txt,sha256=dFwdiTx8djyehI0Gsz-rZwjAfZzUzoBSrmzRu9ubjJc,50
|
|
80
|
+
kekikstream-2.0.1.dist-info/top_level.txt,sha256=DNmGJDXl27Drdfobrak8KYLmocW_uznVYFJOzcjUgmY,12
|
|
81
|
+
kekikstream-2.0.1.dist-info/RECORD,,
|
KekikStream/Extractors/FourCX.py
DELETED
KekikStream/Extractors/PlayRu.py
DELETED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|