KekikStream 0.8.1__py3-none-any.whl → 0.8.3__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of KekikStream might be problematic. Click here for more details.

@@ -5,12 +5,15 @@ from httpx import AsyncClient, Timeout
5
5
  from cloudscraper import CloudScraper
6
6
  from typing import Optional
7
7
  from .ExtractorModels import ExtractResult
8
+ from urllib.parse import urljoin
8
9
 
9
10
  class ExtractorBase(ABC):
11
+ # Çıkarıcının temel özellikleri
10
12
  name = "Extractor"
11
13
  main_url = ""
12
14
 
13
15
  def __init__(self):
16
+ # HTTP istekleri için oturum oluştur
14
17
  self.oturum = AsyncClient(
15
18
  headers = {
16
19
  "User-Agent" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5)",
@@ -18,21 +21,24 @@ class ExtractorBase(ABC):
18
21
  },
19
22
  timeout = Timeout(10.0)
20
23
  )
24
+ # CloudFlare korumalı siteler için scraper ayarla
21
25
  self.cloudscraper = CloudScraper()
22
26
 
23
27
  def can_handle_url(self, url: str) -> bool:
24
- """URL'nin bu extractor tarafından işlenip işlenemeyeceğini kontrol eder."""
28
+ # URL'nin bu çıkarıcı tarafından işlenip işlenemeyeceğini kontrol et
25
29
  return self.main_url in url
26
30
 
27
31
  @abstractmethod
28
32
  async def extract(self, url: str, referer: Optional[str] = None) -> ExtractResult:
29
- """Bir URL'den medya bilgilerini çıkarır."""
33
+ # Alt sınıflar tarafından uygulanacak medya çıkarma fonksiyonu
30
34
  pass
31
35
 
32
36
  async def close(self):
37
+ # HTTP oturumunu güvenli bir şekilde kapat
33
38
  await self.oturum.aclose()
34
39
 
35
40
  def fix_url(self, url: str) -> str:
41
+ # Eksik URL'leri düzelt ve tam URL formatına çevir
36
42
  if not url:
37
43
  return ""
38
44
 
@@ -7,8 +7,11 @@ import os, importlib.util
7
7
 
8
8
  class ExtractorLoader:
9
9
  def __init__(self, extractors_dir: str):
10
+ # Yerel ve global çıkarıcı dizinlerini ayarla
10
11
  self.local_extractors_dir = Path(extractors_dir)
11
12
  self.global_extractors_dir = Path(__file__).parent.parent.parent / extractors_dir
13
+
14
+ # Dizin kontrolü
12
15
  if not self.local_extractors_dir.exists() and not self.global_extractors_dir.exists():
13
16
  konsol.log(f"[red][!] Extractor dizini bulunamadı: {self.global_extractors_dir}[/red]")
14
17
  cikis_yap(False)
@@ -16,14 +19,14 @@ class ExtractorLoader:
16
19
  def load_all(self) -> list[ExtractorBase]:
17
20
  extractors = []
18
21
 
19
- # Global Extractor'ları yükle
22
+ # Global çıkarıcıları yükle
20
23
  if self.global_extractors_dir.exists():
21
24
  konsol.log(f"[green][*] Global Extractor dizininden yükleniyor: {self.global_extractors_dir}[/green]")
22
25
  global_extractors = self._load_from_directory(self.global_extractors_dir)
23
26
  konsol.log(f"[green]Global Extractor'lar: {[e.__name__ for e in global_extractors]}[/green]")
24
27
  extractors.extend(global_extractors)
25
28
 
26
- # Yerel Extractor'ları yükle
29
+ # Yerel çıkarıcıları yükle
27
30
  if self.local_extractors_dir.exists():
28
31
  konsol.log(f"[green][*] Yerel Extractor dizininden yükleniyor: {self.local_extractors_dir}[/green]")
29
32
  local_extractors = self._load_from_directory(self.local_extractors_dir)
@@ -32,12 +35,12 @@ class ExtractorLoader:
32
35
 
33
36
  # Benzersizliği sağlama (modül adı + sınıf adı bazında)
34
37
  unique_extractors = []
35
- seen = set()
38
+ seen_names = set()
36
39
  for ext in extractors:
37
40
  identifier = f"{ext.__module__}.{ext.__name__}"
38
- if identifier not in seen:
41
+ if identifier not in seen_names:
39
42
  unique_extractors.append(ext)
40
- seen.add(identifier)
43
+ seen_names.add(identifier)
41
44
 
42
45
  konsol.log(f"[blue]Sonuç Extractor'lar: {[e.__name__ for e in unique_extractors]}[/blue]")
43
46
 
@@ -48,12 +51,14 @@ class ExtractorLoader:
48
51
 
49
52
  def _load_from_directory(self, directory: Path) -> list[ExtractorBase]:
50
53
  extractors = []
54
+
55
+ # Dizindeki tüm .py dosyalarını tara
51
56
  for file in os.listdir(directory):
52
57
  if file.endswith(".py") and not file.startswith("__"):
53
- module_name = file[:-3]
54
- konsol.log(f"[cyan]Modül yükleniyor: {module_name}[/cyan]")
58
+ module_name = file[:-3] # .py uzantısını kaldır
59
+ konsol.log(f"[cyan]Okunan Dosya\t\t: {module_name}[/cyan]")
55
60
  if extractor := self._load_extractor(directory, module_name):
56
- konsol.log(f"[magenta]Extractor bulundu: {extractor.__name__}[/magenta]")
61
+ konsol.log(f"[magenta]Extractor Yüklendi\t: {extractor.__name__}[/magenta]")
57
62
  extractors.append(extractor)
58
63
 
59
64
  konsol.log(f"[yellow]{directory} dizininden yüklenen Extractor'lar: {[e.__name__ for e in extractors]}[/yellow]")
@@ -61,11 +66,13 @@ class ExtractorLoader:
61
66
 
62
67
  def _load_extractor(self, directory: Path, module_name: str):
63
68
  try:
69
+ # Modül dosyasını bul ve yükle
64
70
  path = directory / f"{module_name}.py"
65
71
  spec = importlib.util.spec_from_file_location(module_name, path)
66
72
  if not spec or not spec.loader:
67
73
  return None
68
74
 
75
+ # Modülü içe aktar
69
76
  module = importlib.util.module_from_spec(spec)
70
77
  spec.loader.exec_module(module)
71
78
 
@@ -73,7 +80,7 @@ class ExtractorLoader:
73
80
  for attr in dir(module):
74
81
  obj = getattr(module, attr)
75
82
  if obj.__module__ == module_name and isinstance(obj, type) and issubclass(obj, ExtractorBase) and obj is not ExtractorBase:
76
- konsol.log(f"[green]Yüklenen sınıf: {module_name}.{obj.__name__} ({obj.__module__}.{obj.__name__})[/green]")
83
+ konsol.log(f"[green]Yüklenen sınıf\t\t: {module_name}.{obj.__name__} ({obj.__module__}.{obj.__name__})[/green]")
77
84
  return obj
78
85
 
79
86
  except Exception as hata:
@@ -5,10 +5,12 @@ from .ExtractorBase import ExtractorBase
5
5
 
6
6
  class ExtractorManager:
7
7
  def __init__(self, extractor_dir="Extractors"):
8
+ # Çıkarıcı yükleyiciyi başlat ve tüm çıkarıcıları yükle
8
9
  self.extractor_loader = ExtractorLoader(extractor_dir)
9
10
  self.extractors = self.extractor_loader.load_all()
10
11
 
11
- def find_extractor(self, link):
12
+ def find_extractor(self, link) -> ExtractorBase:
13
+ # Verilen bağlantıyı işleyebilecek çıkarıcıyı bul
12
14
  for extractor_cls in self.extractors:
13
15
  extractor:ExtractorBase = extractor_cls()
14
16
  if extractor.can_handle_url(link):
@@ -16,7 +18,8 @@ class ExtractorManager:
16
18
 
17
19
  return None
18
20
 
19
- def map_links_to_extractors(self, links):
21
+ def map_links_to_extractors(self, links) -> dict:
22
+ # Bağlantıları uygun çıkarıcılarla eşleştir
20
23
  mapping = {}
21
24
  for link in links:
22
25
  for extractor_cls in self.extractors:
@@ -6,6 +6,7 @@ import subprocess, os
6
6
 
7
7
  class MediaHandler:
8
8
  def __init__(self, title: str = "KekikStream", headers: dict = None):
9
+ # Varsayılan HTTP başlıklarını ayarla
9
10
  if headers is None:
10
11
  headers = {"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5)"}
11
12
 
@@ -13,12 +14,15 @@ class MediaHandler:
13
14
  self.title = title
14
15
 
15
16
  def play_media(self, extract_data: ExtractResult):
17
+ # Google Drive gibi özel durumlar için yt-dlp kullan
16
18
  if self.headers.get("User-Agent") == "googleusercontent":
17
19
  return self.play_with_ytdlp(extract_data)
18
20
 
21
+ # İşletim sistemine göre oynatıcı seç
19
22
  if subprocess.check_output(['uname', '-o']).strip() == b'Android':
20
23
  return self.play_with_android_mxplayer(extract_data)
21
24
 
25
+ # Cookie veya alt yazılar varsa mpv kullan
22
26
  if "Cookie" in self.headers or extract_data.subtitles:
23
27
  return self.play_with_mpv(extract_data)
24
28
 
@@ -7,55 +7,69 @@ import os, importlib.util, traceback
7
7
 
8
8
  class PluginLoader:
9
9
  def __init__(self, plugins_dir: str):
10
+ # Yerel ve global eklenti dizinlerini ayarla
10
11
  self.local_plugins_dir = Path(plugins_dir).resolve()
11
12
  self.global_plugins_dir = Path(__file__).parent.parent.parent / plugins_dir
13
+
14
+ # Dizin kontrolü
12
15
  if not self.local_plugins_dir.exists() and not self.global_plugins_dir.exists():
13
- konsol.log(f"[red][!] Extractor dizini bulunamadı: {plugins_dir}[/red]")
16
+ konsol.log(f"[red][!] Eklenti dizini bulunamadı: {plugins_dir}[/red]")
14
17
  cikis_yap(False)
15
18
 
16
19
  def load_all(self) -> dict[str, PluginBase]:
17
20
  plugins = {}
18
21
 
22
+ # Global eklentileri yükle
19
23
  if self.global_plugins_dir.exists():
20
- konsol.log(f"[green][*] Global Plugin dizininden yükleniyor: {self.global_plugins_dir}[/green]")
24
+ konsol.log(f"[green][*] Global Eklenti dizininden yükleniyor: {self.global_plugins_dir}[/green]")
21
25
  plugins |= self._load_from_directory(self.global_plugins_dir)
22
26
 
27
+ # Yerel eklentileri yükle
23
28
  if self.local_plugins_dir.exists():
24
- konsol.log(f"[green][*] Yerel Plugin dizininden yükleniyor: {self.local_plugins_dir}[/green]")
29
+ konsol.log(f"[green][*] Yerel Eklenti dizininden yükleniyor: {self.local_plugins_dir}[/green]")
25
30
  plugins |= self._load_from_directory(self.local_plugins_dir)
26
31
 
27
32
  if not plugins:
28
- konsol.print("[yellow][!] Yüklenecek bir Plugin bulunamadı![/yellow]")
33
+ konsol.print("[yellow][!] Yüklenecek bir Eklenti bulunamadı![/yellow]")
29
34
 
30
35
  return dict(sorted(plugins.items()))
31
36
 
32
37
  def _load_from_directory(self, directory: Path) -> dict[str, PluginBase]:
33
38
  plugins = {}
39
+
40
+ # Dizindeki tüm .py dosyalarını tara
34
41
  for file in os.listdir(directory):
35
42
  if file.endswith(".py") and not file.startswith("__"):
36
- module_name = file[:-3]
43
+ module_name = file[:-3] # .py uzantısını kaldır
44
+ konsol.log(f"[cyan]Okunan Dosya\t\t: {module_name}[/cyan]")
37
45
  if plugin := self._load_plugin(directory, module_name):
46
+ konsol.log(f"[magenta]Eklenti Yüklendi\t: {plugin.name}[/magenta]")
38
47
  plugins[module_name] = plugin
39
48
 
49
+ konsol.log(f"[yellow]{directory} dizininden yüklenen Eklentiler: {list(plugins.keys())}[/yellow]")
40
50
  return plugins
41
51
 
42
52
  def _load_plugin(self, directory: Path, module_name: str):
43
53
  try:
54
+ # Modül dosyasını bul ve yükle
44
55
  path = directory / f"{module_name}.py"
45
56
  spec = importlib.util.spec_from_file_location(module_name, path)
46
57
  if not spec or not spec.loader:
47
58
  raise ImportError(f"Spec oluşturulamadı: {module_name}")
48
59
 
60
+ # Modülü içe aktar
49
61
  module = importlib.util.module_from_spec(spec)
50
62
  spec.loader.exec_module(module)
51
63
 
64
+ # Yalnızca doğru modülden gelen PluginBase sınıflarını yükle
52
65
  for attr in dir(module):
53
66
  obj = getattr(module, attr)
54
67
  if isinstance(obj, type) and issubclass(obj, PluginBase) and obj is not PluginBase:
68
+ konsol.log(f"[yellow]Yüklenen sınıf\t\t: {module_name}.{obj.__name__} ({obj.__module__}.{obj.__name__})[/yellow]")
55
69
  return obj()
56
70
 
57
71
  except Exception as hata:
58
- konsol.print(f"[red][!] Plugin yüklenirken hata oluştu: {module_name}\nHata: {hata}")
72
+ konsol.print(f"[red][!] Eklenti yüklenirken hata oluştu: {module_name}\nHata: {hata}")
59
73
  konsol.print(f"[dim]{traceback.format_exc()}[/dim]")
60
74
 
61
75
  return None
@@ -5,16 +5,20 @@ from .PluginBase import PluginBase
5
5
 
6
6
  class PluginManager:
7
7
  def __init__(self, plugin_dir="Plugins"):
8
+ # Eklenti yükleyiciyi başlat ve tüm eklentileri yükle
8
9
  self.plugin_loader = PluginLoader(plugin_dir)
9
10
  self.plugins = self.plugin_loader.load_all()
10
11
 
11
12
  def get_plugin_names(self):
13
+ # Dizindeki tüm eklenti adlarını listeler ve sıralar
12
14
  return sorted(list(self.plugins.keys()))
13
15
 
14
16
  def select_plugin(self, plugin_name):
17
+ # Verilen eklenti adını kullanarak eklentiyi seç
15
18
  return self.plugins.get(plugin_name)
16
19
 
17
20
  async def close_plugins(self):
21
+ # Tüm eklentileri kapat
18
22
  for plugin in self.plugins.values():
19
23
  if isinstance(plugin, PluginBase):
20
24
  await plugin.close()
@@ -5,7 +5,7 @@ from parsel import Selector
5
5
 
6
6
  class JetFilmizle(PluginBase):
7
7
  name = "JetFilmizle"
8
- main_url = "https://jetfilmizle.media"
8
+ main_url = "https://jetfilmizle.nl"
9
9
 
10
10
  async def search(self, query: str) -> list[SearchResult]:
11
11
  istek = await self.oturum.post(
KekikStream/__init__.py CHANGED
@@ -7,6 +7,7 @@ from contextlib import suppress
7
7
 
8
8
  class KekikStream:
9
9
  def __init__(self):
10
+ # Yönetici sınıflarını başlat
10
11
  self.eklentiler_yonetici = PluginManager()
11
12
  self.cikaricilar_yonetici = ExtractorManager()
12
13
  self.arayuz_yonetici = UIManager()
@@ -14,17 +15,22 @@ class KekikStream:
14
15
  self.suanki_eklenti: PluginBase = None
15
16
 
16
17
  async def baslat(self):
18
+ # Konsolu temizle ve başlık göster
17
19
  self.arayuz_yonetici.clear_console()
18
20
  konsol.rule("[bold cyan]KekikStream Başlatılıyor[/bold cyan]")
21
+
22
+ # Eklenti kontrolü
19
23
  if not self.eklentiler_yonetici.get_plugin_names():
20
24
  return konsol.print("[bold red]Hiçbir eklenti bulunamadı![/bold red]")
21
25
 
22
26
  try:
23
27
  await self.eklenti_secimi()
24
28
  finally:
29
+ # Program kapanırken tüm eklentileri kapat
25
30
  await self.eklentiler_yonetici.close_plugins()
26
31
 
27
32
  async def sonuc_bulunamadi(self):
33
+ # Sonuç bulunamadığında kullanıcıya seçenekler sun
28
34
  secim = await self.arayuz_yonetici.select_from_list(
29
35
  message = "Ne yapmak istersiniz?",
30
36
  choices = ["Tüm Eklentilerde Ara", "Ana Menü", "Çıkış"]
@@ -39,6 +45,7 @@ class KekikStream:
39
45
  cikis_yap(False)
40
46
 
41
47
  async def eklenti_secimi(self):
48
+ # Fuzzy ile eklenti seçimi yap
42
49
  eklenti_adi = await self.arayuz_yonetici.select_from_fuzzy(
43
50
  message = "Arama yapılacak eklentiyi seçin:",
44
51
  choices = ["Tüm Eklentilerde Ara", *self.eklentiler_yonetici.get_plugin_names()]
@@ -51,9 +58,11 @@ class KekikStream:
51
58
  await self.eklenti_ile_arama()
52
59
 
53
60
  async def eklenti_ile_arama(self):
61
+ # Seçilen eklentide arama yap
54
62
  self.arayuz_yonetici.clear_console()
55
63
  konsol.rule(f"[bold cyan]{self.suanki_eklenti.name} Eklentisinde Arama Yapın[/bold cyan]")
56
64
 
65
+ # Kullanıcıdan sorgu al ve ara
57
66
  sorgu = await self.arayuz_yonetici.prompt_text("Arama sorgusu girin:")
58
67
  sonuclar = await self.suanki_eklenti.search(sorgu)
59
68
 
@@ -65,12 +74,14 @@ class KekikStream:
65
74
  await self.sonuc_detaylari_goster({"plugin": self.suanki_eklenti.name, "url": secilen_sonuc})
66
75
 
67
76
  async def eklenti_sonuc_secimi(self, sonuclar):
77
+ # Arama sonuçlarından birini seç
68
78
  return await self.arayuz_yonetici.select_from_fuzzy(
69
79
  message = "İçerik sonuçlarından birini seçin:",
70
80
  choices = [{"name": sonuc.title, "value": sonuc.url} for sonuc in sonuclar]
71
81
  )
72
82
 
73
83
  async def tum_eklentilerde_arama(self):
84
+ # Tüm eklentilerde arama yap
74
85
  self.arayuz_yonetici.clear_console()
75
86
  konsol.rule("[bold cyan]Tüm Eklentilerde Arama Yapın[/bold cyan]")
76
87
 
@@ -88,7 +99,9 @@ class KekikStream:
88
99
  async def tum_eklentilerde_arama_sorgula(self, sorgu: str) -> list:
89
100
  tum_sonuclar = []
90
101
 
102
+ # Her eklentide arama yap
91
103
  for eklenti_adi, eklenti in self.eklentiler_yonetici.plugins.items():
104
+ # Eklenti türü kontrolü
92
105
  if not isinstance(eklenti, PluginBase):
93
106
  konsol.print(f"[yellow][!] {eklenti_adi} geçerli bir PluginBase değil, atlanıyor...[/yellow]")
94
107
  continue
@@ -97,6 +110,7 @@ class KekikStream:
97
110
  try:
98
111
  sonuclar = await eklenti.search(sorgu)
99
112
  if sonuclar:
113
+ # Sonuçları listeye ekle
100
114
  tum_sonuclar.extend(
101
115
  [{"plugin": eklenti_adi, "title": sonuc.title, "url": sonuc.url, "poster": sonuc.poster} for sonuc in sonuclar]
102
116
  )
@@ -111,6 +125,7 @@ class KekikStream:
111
125
  return tum_sonuclar
112
126
 
113
127
  async def tum_sonuc_secimi(self, sonuclar):
128
+ # Tüm sonuçlardan birini seç
114
129
  secenekler = [
115
130
  {"name": f"[{sonuc['plugin']}]".ljust(21) + f" » {sonuc['title']}", "value": sonuc}
116
131
  for sonuc in sonuclar
@@ -123,6 +138,7 @@ class KekikStream:
123
138
 
124
139
  async def sonuc_detaylari_goster(self, secilen_sonuc):
125
140
  try:
141
+ # Seçilen sonucun detaylarını al
126
142
  if isinstance(secilen_sonuc, dict) and "plugin" in secilen_sonuc:
127
143
  eklenti_adi = secilen_sonuc["plugin"]
128
144
  url = secilen_sonuc["url"]
@@ -131,6 +147,7 @@ class KekikStream:
131
147
  else:
132
148
  url = secilen_sonuc
133
149
 
150
+ # Medya bilgilerini yükle (3 deneme hakkı)
134
151
  medya_bilgi = None
135
152
  for _ in range(3):
136
153
  with suppress(Exception):
@@ -144,9 +161,11 @@ class KekikStream:
144
161
  konsol.log(secilen_sonuc)
145
162
  return hata_yakala(hata)
146
163
 
164
+ # Medya başlığını ayarla ve bilgileri göster
147
165
  self.medya_yonetici.set_title(f"{self.suanki_eklenti.name} | {medya_bilgi.title}")
148
166
  self.arayuz_yonetici.display_media_info(f"{self.suanki_eklenti.name} | {medya_bilgi.title}", medya_bilgi)
149
167
 
168
+ # Dizi ise bölüm seçimi yap
150
169
  if isinstance(medya_bilgi, SeriesInfo):
151
170
  secilen_bolum = await self.arayuz_yonetici.select_from_fuzzy(
152
171
  message = "İzlemek istediğiniz bölümü seçin:",
@@ -167,15 +186,19 @@ class KekikStream:
167
186
  konsol.print("[bold red]Hiçbir bağlantı bulunamadı![/bold red]")
168
187
  return await self.sonuc_bulunamadi()
169
188
 
189
+ # Bağlantıları çıkarıcılarla eşleştir
170
190
  haritalama = self.cikaricilar_yonetici.map_links_to_extractors(baglantilar)
171
191
  play_fonksiyonu_var = hasattr(self.suanki_eklenti, "play") and callable(getattr(self.suanki_eklenti, "play", None))
172
192
  # ! DEBUG
173
193
  # konsol.print(baglantilar)
194
+
195
+ # Uygun çıkarıcı kontrolü
174
196
  if not haritalama and not play_fonksiyonu_var:
175
197
  konsol.print("[bold red]Hiçbir Extractor bulunamadı![/bold red]")
176
198
  konsol.print(baglantilar)
177
199
  return await self.sonuc_bulunamadi()
178
200
 
201
+ # Doğrudan oynatma seçeneği
179
202
  if not haritalama:
180
203
  secilen_link = await self.arayuz_yonetici.select_from_list(
181
204
  message = "Doğrudan oynatmak için bir bağlantı seçin:",
@@ -185,6 +208,7 @@ class KekikStream:
185
208
  await self.medya_oynat(secilen_link)
186
209
  return
187
210
 
211
+ # Kullanıcı seçenekleri
188
212
  secim = await self.arayuz_yonetici.select_from_list(
189
213
  message = "Ne yapmak istersiniz?",
190
214
  choices = ["İzle", "Tüm Eklentilerde Ara", "Ana Menü"]
@@ -206,6 +230,7 @@ class KekikStream:
206
230
  await self.baslat()
207
231
 
208
232
  async def medya_oynat(self, secilen_link):
233
+ # Eklentinin kendi oynatıcısı varsa onu kullan
209
234
  if hasattr(self.suanki_eklenti, "play") and callable(self.suanki_eklenti.play):
210
235
  konsol.log(f"[yellow][»] Oynatılıyor : {secilen_link}")
211
236
  return await self.suanki_eklenti.play(
@@ -215,16 +240,19 @@ class KekikStream:
215
240
  subtitles = self.suanki_eklenti._data[secilen_link]["subtitles"]
216
241
  )
217
242
 
243
+ # Uygun çıkarıcıyı bul
218
244
  cikarici: ExtractorBase = self.cikaricilar_yonetici.find_extractor(secilen_link)
219
245
  if not cikarici:
220
246
  return konsol.print("[bold red]Uygun Extractor bulunamadı.[/bold red]")
221
247
 
222
248
  try:
249
+ # Medya bilgilerini çıkar
223
250
  extract_data = await cikarici.extract(secilen_link, referer=self.suanki_eklenti.main_url)
224
251
  except Exception as hata:
225
252
  konsol.print(f"[bold red]{cikarici.name} » hata oluştu: {hata}[/bold red]")
226
253
  return await self.sonuc_bulunamadi()
227
254
 
255
+ # Birden fazla bağlantı varsa seçim yap
228
256
  if isinstance(extract_data, list):
229
257
  secilen_data = await self.arayuz_yonetici.select_from_list(
230
258
  message = "Birden fazla bağlantı bulundu, lütfen birini seçin:",
@@ -233,9 +261,11 @@ class KekikStream:
233
261
  else:
234
262
  secilen_data = extract_data
235
263
 
264
+ # Cookie varsa ayarla
236
265
  if secilen_data.headers.get("Cookie"):
237
266
  self.medya_yonetici.set_headers({"Cookie": secilen_data.headers.get("Cookie")})
238
267
 
268
+ # Başlık ve referrer ayarla
239
269
  self.medya_yonetici.set_title(f"{self.medya_yonetici.get_title()} | {secilen_data.name}")
240
270
  self.medya_yonetici.set_headers({"Referer": secilen_data.referer})
241
271
  konsol.log(f"[yellow][»] Oynatılıyor : {secilen_data.url}")
@@ -243,8 +273,10 @@ class KekikStream:
243
273
 
244
274
  def basla():
245
275
  try:
276
+ # PyPI güncellemelerini kontrol et
246
277
  pypi_kontrol_guncelle("KekikStream")
247
278
 
279
+ # Uygulamayı başlat
248
280
  app = KekikStream()
249
281
  run(app.baslat())
250
282
  cikis_yap(False)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: KekikStream
3
- Version: 0.8.1
3
+ Version: 0.8.3
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
@@ -1,18 +1,18 @@
1
- KekikStream/__init__.py,sha256=5hWi3i_D7qy-2re_9wn4cUMRPAf-uk8MVvw-PyNb-CY,10871
1
+ KekikStream/__init__.py,sha256=2ocXWKQcb05mHfRPHKxHt7nHufvPOzKESmTrIVfy70k,12174
2
2
  KekikStream/__main__.py,sha256=B81dQoeGEb-T5Sycs3eNAmW7unvx0Mef0syCjs4nPds,137
3
3
  KekikStream/requirements.txt,sha256=QWCXrrmKodIm7mGtIz9cWr9sks-lmL_TilKMrruWJn0,77
4
4
  KekikStream/CLI/__init__.py,sha256=U6oLq_O7u5y2eHhBnmfhZNns_EqHHJXJmzl8jvZFUNY,230
5
5
  KekikStream/CLI/pypi_kontrol.py,sha256=MchatOwCWCpFBtgt09yag9Rjal9XFyh2W_oVs2p7SNg,1518
6
6
  KekikStream/Core/__init__.py,sha256=2N0VFP4QsyDWn4pV77JX_5_XachD5qKzhuDor3klj58,657
7
- KekikStream/Core/Extractor/ExtractorBase.py,sha256=wmGl-Xiem4s5M7baVOxYLba7UdygCDAXggo6Up8pFJE,1409
8
- KekikStream/Core/Extractor/ExtractorLoader.py,sha256=QZqaZs8u2YWlY_cUkJKSKt6xV8FjDuU9up_VjyTNUqE,3922
9
- KekikStream/Core/Extractor/ExtractorManager.py,sha256=K11ESoZEc7oJyPb5uEGwfaANYJTU-e9qyzIMj4H8lT0,1014
7
+ KekikStream/Core/Extractor/ExtractorBase.py,sha256=ZyasO5m7iAsnh-mwhtlp-VXkZ4pIuWuHvCIskBX7FUg,1726
8
+ KekikStream/Core/Extractor/ExtractorLoader.py,sha256=ecrfz9mYizlENCjbyfjdfnOrQorxQTF4ZFGhPpU6JHk,4193
9
+ KekikStream/Core/Extractor/ExtractorManager.py,sha256=4L1H3jiTnf0kTq4W6uS7n95bBYHlKJ8_hh0og8z4erQ,1244
10
10
  KekikStream/Core/Extractor/ExtractorModels.py,sha256=huIcPQ5VIRfMx0LcL5SS1u4dldZbHjzHKEdSEtOPlc0,456
11
- KekikStream/Core/Media/MediaHandler.py,sha256=JEwAvLyQKAAys6_E97bHePxf7rYqDglowGEqUPhq35s,5961
11
+ KekikStream/Core/Media/MediaHandler.py,sha256=-yVOnI5pNKWgvrRgJ8DVKjvTWuHTwUC7JSKlKa06lSw,6179
12
12
  KekikStream/Core/Media/MediaManager.py,sha256=9ItiUguOkk3wg3YY5uf3mrjfwLPCvggnP8QviX0uiuE,526
13
13
  KekikStream/Core/Plugin/PluginBase.py,sha256=KuR89bkrChPAct4-PMjxbK4i6busXMMFeZjv-x4F1CQ,2521
14
- KekikStream/Core/Plugin/PluginLoader.py,sha256=o8m5U75HQvCi-lmsivqWvb6qyfifInEguqrD3R0bHQA,2576
15
- KekikStream/Core/Plugin/PluginManager.py,sha256=nKvglAYTKfEwGnc7rf5cOMXfYoy3MGJoWBPLhRE4ll8,669
14
+ KekikStream/Core/Plugin/PluginLoader.py,sha256=2UM3gNcEgd7k-FxG-JB5nTIS0K_clzvFtzGjMA_Sx7Q,3379
15
+ KekikStream/Core/Plugin/PluginManager.py,sha256=CZVg1eegi8vfMfccx0DRV0Box8kXz-aoULTQLgbPbvM,893
16
16
  KekikStream/Core/Plugin/PluginModels.py,sha256=q8tjkt_-uiJ7uNxOThYR0FgTQLZglVAOAaM0Kske-28,2063
17
17
  KekikStream/Core/UI/UIManager.py,sha256=T4V_kdTTWa-UDamgLSKa__dWJuzcvRK9NuwBlzU9Bzc,1693
18
18
  KekikStream/Extractors/CloseLoad.py,sha256=YmDB3YvuDaCUbQ0T_tmhnkEsC5mSdEN6GNoAR662fl8,990
@@ -45,14 +45,14 @@ KekikStream/Plugins/DiziYou.py,sha256=kpRY3U6lqaZKgn9ED2TprwU7qfLxuC2ZZmrRemegry
45
45
  KekikStream/Plugins/Dizilla.py,sha256=evWYvETw1c4RY0GB5P20cB_I_U7ZxzzvnG7RLNGJRPs,4258
46
46
  KekikStream/Plugins/FilmMakinesi.py,sha256=rz8TQeL41PJbeEmksgPHIhp6J-4vbSCBTeEH0ukExz4,2822
47
47
  KekikStream/Plugins/FullHDFilmizlesene.py,sha256=Fa0gRP_NoMfPC8HIKRxERjQVOv8Fyb-ayMJ2EooZ7BE,3080
48
- KekikStream/Plugins/JetFilmizle.py,sha256=FXkMSQtjYoxwIonjRENFa91rC42L_8SYRhjhuSgsu60,3919
48
+ KekikStream/Plugins/JetFilmizle.py,sha256=Gu4Ums-88x7jNKAtKkdSXyMaOyLv0_Kb6jnomhAWhM0,3916
49
49
  KekikStream/Plugins/RecTV.py,sha256=Pt2IQ2jLsQp7Mo85uM_ml3nxOR0uirX7vXOnE10CPm0,4886
50
50
  KekikStream/Plugins/SezonlukDizi.py,sha256=5BZVzQ2eQtymHxO0bzjA2ho4FFNahPFQly4hoHuH8lo,4441
51
51
  KekikStream/Plugins/SineWix.py,sha256=VvFeAS2-Y-KJ1Od16yZjUJLiESwsBBGb2GNG3BLLupU,4806
52
52
  KekikStream/Plugins/UgurFilm.py,sha256=yYXee5uxwNnPqFJZ6s6cRkmUyqS3Vv8x-iesPalc4j4,2930
53
- KekikStream-0.8.1.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
54
- KekikStream-0.8.1.dist-info/METADATA,sha256=tlrqj-FYr_tnPCeorPhZz8WleOkVjgQ_A14oo_5jRqc,4226
55
- KekikStream-0.8.1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
56
- KekikStream-0.8.1.dist-info/entry_points.txt,sha256=dFwdiTx8djyehI0Gsz-rZwjAfZzUzoBSrmzRu9ubjJc,50
57
- KekikStream-0.8.1.dist-info/top_level.txt,sha256=DNmGJDXl27Drdfobrak8KYLmocW_uznVYFJOzcjUgmY,12
58
- KekikStream-0.8.1.dist-info/RECORD,,
53
+ KekikStream-0.8.3.dist-info/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
54
+ KekikStream-0.8.3.dist-info/METADATA,sha256=CxKT0vhQw9uT534rpw-W2LZPZ1ElsWAFyDIv0rrMcHE,4226
55
+ KekikStream-0.8.3.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
56
+ KekikStream-0.8.3.dist-info/entry_points.txt,sha256=dFwdiTx8djyehI0Gsz-rZwjAfZzUzoBSrmzRu9ubjJc,50
57
+ KekikStream-0.8.3.dist-info/top_level.txt,sha256=DNmGJDXl27Drdfobrak8KYLmocW_uznVYFJOzcjUgmY,12
58
+ KekikStream-0.8.3.dist-info/RECORD,,