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.
Files changed (29) hide show
  1. KekikStream/Core/Extractor/ExtractorBase.py +5 -5
  2. KekikStream/Core/Extractor/ExtractorLoader.py +25 -17
  3. KekikStream/Core/Extractor/ExtractorManager.py +1 -1
  4. KekikStream/Core/Plugin/PluginBase.py +4 -1
  5. KekikStream/Core/Plugin/PluginLoader.py +11 -7
  6. KekikStream/Extractors/CloseLoad.py +1 -1
  7. KekikStream/Extractors/ContentX_.py +40 -0
  8. KekikStream/Extractors/{OkRuHTTP.py → Odnoklassniki_.py} +5 -1
  9. KekikStream/Extractors/{HDStreamAble.py → PeaceMakerst_.py} +1 -1
  10. KekikStream/Extractors/RapidVid_.py +7 -0
  11. KekikStream/Extractors/{VidMolyMe.py → VidMoly_.py} +1 -1
  12. KekikStream/Plugins/Dizilla.py +1 -1
  13. KekikStream/Plugins/FilmMakinesi.py +2 -0
  14. KekikStream/Plugins/JetFilmizle.py +52 -37
  15. KekikStream/Plugins/Sinefy.py +4 -1
  16. KekikStream/Plugins/Sinezy.py +16 -1
  17. {kekikstream-1.9.9.dist-info → kekikstream-2.0.1.dist-info}/METADATA +27 -1
  18. {kekikstream-1.9.9.dist-info → kekikstream-2.0.1.dist-info}/RECORD +22 -27
  19. KekikStream/Extractors/FourCX.py +0 -7
  20. KekikStream/Extractors/FourPichive.py +0 -7
  21. KekikStream/Extractors/FourPlayRu.py +0 -7
  22. KekikStream/Extractors/Hotlinger.py +0 -7
  23. KekikStream/Extractors/OkRuSSL.py +0 -7
  24. KekikStream/Extractors/Pichive.py +0 -7
  25. KekikStream/Extractors/PlayRu.py +0 -7
  26. {kekikstream-1.9.9.dist-info → kekikstream-2.0.1.dist-info}/WHEEL +0 -0
  27. {kekikstream-1.9.9.dist-info → kekikstream-2.0.1.dist-info}/entry_points.txt +0 -0
  28. {kekikstream-1.9.9.dist-info → kekikstream-2.0.1.dist-info}/licenses/LICENSE +0 -0
  29. {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({"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 15.7; rv:135.0) Gecko/20100101 Firefox/135.0"})
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
- # Global çıkarıcıları yükle
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
- extractors.extend(local_extractors)
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
- if extractor := self._load_extractor(directory, module_name):
61
- # konsol.log(f"[magenta]Extractor Yüklendi\t: {extractor.__name__}[/magenta]")
62
- extractors.append(extractor)
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 None
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
- if obj.__module__ == module_name and isinstance(obj, type) and issubclass(obj, ExtractorBase) and obj is not ExtractorBase:
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
- return obj
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 None
98
+ return []
@@ -63,7 +63,7 @@ class ExtractorManager:
63
63
  """
64
64
  # Lazy loading: İlk kullanımda extractorları initialize et
65
65
  self._ensure_initialized()
66
-
66
+
67
67
  mapping = {}
68
68
  for link in links:
69
69
  # Cached instance'ları kullan
@@ -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({"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 15.7; rv:135.0) Gecko/20100101 Firefox/135.0"})
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
- # Global eklentileri yükle
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
- plugins |= self._load_from_directory(self.local_plugins_dir)
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]")
@@ -6,7 +6,7 @@ import re
6
6
 
7
7
  class CloseLoadExtractor(ExtractorBase):
8
8
  name = "CloseLoad"
9
- main_url = "https://closeload.filmmakinesi.sh"
9
+ main_url = "https://closeload.filmmakinesi.to"
10
10
 
11
11
  async def extract(self, url, referer=None) -> ExtractResult:
12
12
  if referer:
@@ -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"
@@ -4,4 +4,8 @@ from KekikStream.Extractors.Odnoklassniki import Odnoklassniki
4
4
 
5
5
  class OkRuHTTP(Odnoklassniki):
6
6
  name = "OkRuHTTP"
7
- main_url = "http://ok.ru"
7
+ main_url = "http://ok.ru"
8
+
9
+ class OkRuSSL(Odnoklassniki):
10
+ name = "OkRuSSL"
11
+ main_url = "https://ok.ru"
@@ -4,4 +4,4 @@ from KekikStream.Extractors.PeaceMakerst import PeaceMakerst
4
4
 
5
5
  class HDStreamAble(PeaceMakerst):
6
6
  name = "HDStreamAble"
7
- main_url = "https://hdstreamable.com"
7
+ main_url = "https://hdstreamable.com"
@@ -0,0 +1,7 @@
1
+ # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
+
3
+ from KekikStream.Extractors.RapidVid import RapidVid
4
+
5
+ class RapidFilm(RapidVid):
6
+ name = "RapidFilm"
7
+ main_url = "https://rapid.filmmakinesi.to"
@@ -4,4 +4,4 @@ from KekikStream.Extractors.VidMoly import VidMoly
4
4
 
5
5
  class VidMolyMe(VidMoly):
6
6
  name = "VidMolyMe"
7
- main_url = "https://vidmoly.me"
7
+ main_url = "https://vidmoly.me"
@@ -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("h3.text-white.opacity-60::text").get()
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
- year = secici.xpath("//div[@class='yap' and (contains(., 'Vizyon') or contains(., 'Yapım'))]/text()").get()
78
- year = year.strip() if year else None
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
- iframes = []
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
- for part in secici.css("div.film_part a"):
101
- part_href = part.attrib.get("href")
102
- if not part_href:
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
@@ -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]:
@@ -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: 1.9.9
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=EDuI3AfeWbQUW_v9iU4DCQYmtq5SIRGFkU8Ri9Mtkow,1774
8
- KekikStream/Core/Extractor/ExtractorLoader.py,sha256=7uxUXTAuF65KKkmbI6iRiCiUhx-IqrronB7ixhchcTU,4289
9
- KekikStream/Core/Extractor/ExtractorManager.py,sha256=W8LkEl0TXLYvbF6PWw9Q0BEYs17UQiHHrEOqBDyB_Eg,2652
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=maUXMGHZQ6JOJdQoHG9hmyy1-_XKR5z0BGw0YtEkSLI,4009
14
- KekikStream/Core/Plugin/PluginLoader.py,sha256=yZxMug-OcJ5RBm4fQkoquKrZxcBU7Pvt4IcY-d0WU8g,3393
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=NSDjcwEaQJ_Y3dSszmEFOyVeh3RA2TNlb_IfxAeJ5B8,884
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/OkRuHTTP.py,sha256=L-B0i_i_Vnm61GvUfd6cGIW-o_H4M-C7DO_cdw2rQPU,228
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/Pichive.py,sha256=BSVYFwL3Ax6yGoS1WkpOWtngxNyuZLoKzpPwjibpu2s,221
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/VidMolyMe.py,sha256=ogLiFUJVqFbhtzQrZ1gSB9me85DiHvntjWtSvidYVS8,218
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=jDklWkUrrAGhDO9pMvgIXVcKdSHDHlguu0JgifM7Bx8,11546
57
+ KekikStream/Plugins/Dizilla.py,sha256=gVLborMFjYr3w_KrB53lmB1W8lTzEAySHjv4gvOZp1A,11542
63
58
  KekikStream/Plugins/FilmBip.py,sha256=Tfx2dUc1Qs7ZQoJtsBtjOJXCKmTe56m74lNhuUYYU14,6182
64
- KekikStream/Plugins/FilmMakinesi.py,sha256=izPKGbqQuA6AmLAnFjlBoe8iwnNOrr0Pcy5L2dZfM78,5185
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=3tcx4ZT7oQs_xolhQeiqgirpWtknBjP7J7Qgy0bvIeM,5963
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=YMwG7ykdjzAY_GEvV4xv9NJ6ubew7qeMLz4KkvYpaNk,9749
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=EttAZogKoKMP8RP_X1fSfi8vVxA2RWizwgnLkmnhERQ,5675
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-1.9.9.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
82
- kekikstream-1.9.9.dist-info/METADATA,sha256=3WcSjVCazXL_jBuyWDwkWLc0C5lbE2VuO_UdQSu0Ntg,9079
83
- kekikstream-1.9.9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
84
- kekikstream-1.9.9.dist-info/entry_points.txt,sha256=dFwdiTx8djyehI0Gsz-rZwjAfZzUzoBSrmzRu9ubjJc,50
85
- kekikstream-1.9.9.dist-info/top_level.txt,sha256=DNmGJDXl27Drdfobrak8KYLmocW_uznVYFJOzcjUgmY,12
86
- kekikstream-1.9.9.dist-info/RECORD,,
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,,
@@ -1,7 +0,0 @@
1
- # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
-
3
- from KekikStream.Extractors.ContentX import ContentX
4
-
5
- class FourCX(ContentX):
6
- name = "FourCX"
7
- main_url = "https://four.contentx.me"
@@ -1,7 +0,0 @@
1
- # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
-
3
- from KekikStream.Extractors.ContentX import ContentX
4
-
5
- class FourPichive(ContentX):
6
- name = "FourPichive"
7
- main_url = "https://four.pichive.online"
@@ -1,7 +0,0 @@
1
- # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
-
3
- from KekikStream.Extractors.ContentX import ContentX
4
-
5
- class FourPlayRu(ContentX):
6
- name = "FourPlayRu"
7
- main_url = "https://four.playru.net"
@@ -1,7 +0,0 @@
1
- # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
-
3
- from KekikStream.Extractors.ContentX import ContentX
4
-
5
- class Hotlinger(ContentX):
6
- name = "Hotlinger"
7
- main_url = "https://hotlinger.com"
@@ -1,7 +0,0 @@
1
- # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
-
3
- from KekikStream.Extractors.Odnoklassniki import Odnoklassniki
4
-
5
- class OkRuSSL(Odnoklassniki):
6
- name = "OkRuSSL"
7
- main_url = "https://ok.ru"
@@ -1,7 +0,0 @@
1
- # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
-
3
- from KekikStream.Extractors.ContentX import ContentX
4
-
5
- class Pichive(ContentX):
6
- name = "Pichive"
7
- main_url = "https://pichive.online"
@@ -1,7 +0,0 @@
1
- # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
-
3
- from KekikStream.Extractors.ContentX import ContentX
4
-
5
- class PlayRu(ContentX):
6
- name = "PlayRu"
7
- main_url = "https://playru.net"