KekikStream 0.9.3__tar.gz → 1.0.1__tar.gz

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Core/Media/MediaHandler.py +4 -0
  2. kekikstream-1.0.1/KekikStream/Extractors/MolyStream.py +17 -0
  3. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Plugins/DiziBox.py +6 -2
  4. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Plugins/Dizilla.py +1 -1
  5. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Plugins/SezonlukDizi.py +2 -2
  6. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Plugins/Shorten.py +7 -7
  7. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/__init__.py +126 -61
  8. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream.egg-info/PKG-INFO +1 -1
  9. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream.egg-info/SOURCES.txt +1 -0
  10. {kekikstream-0.9.3 → kekikstream-1.0.1}/PKG-INFO +1 -1
  11. {kekikstream-0.9.3 → kekikstream-1.0.1}/setup.py +1 -1
  12. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/CLI/__init__.py +0 -0
  13. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/CLI/pypi_kontrol.py +0 -0
  14. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Core/Extractor/ExtractorBase.py +0 -0
  15. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Core/Extractor/ExtractorLoader.py +0 -0
  16. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Core/Extractor/ExtractorManager.py +0 -0
  17. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Core/Extractor/ExtractorModels.py +0 -0
  18. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Core/Media/MediaManager.py +0 -0
  19. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Core/Plugin/PluginBase.py +0 -0
  20. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Core/Plugin/PluginLoader.py +0 -0
  21. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Core/Plugin/PluginManager.py +0 -0
  22. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Core/Plugin/PluginModels.py +0 -0
  23. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Core/UI/UIManager.py +0 -0
  24. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Core/__init__.py +0 -0
  25. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Extractors/CloseLoad.py +0 -0
  26. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Extractors/ContentX.py +0 -0
  27. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Extractors/FourCX.py +0 -0
  28. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Extractors/FourPichive.py +0 -0
  29. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Extractors/FourPlayRu.py +0 -0
  30. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Extractors/HDStreamAble.py +0 -0
  31. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Extractors/Hotlinger.py +0 -0
  32. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Extractors/MailRu.py +0 -0
  33. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Extractors/MixPlayHD.py +0 -0
  34. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Extractors/Odnoklassniki.py +0 -0
  35. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Extractors/OkRuHTTP.py +0 -0
  36. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Extractors/OkRuSSL.py +0 -0
  37. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Extractors/PeaceMakerst.py +0 -0
  38. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Extractors/Pichive.py +0 -0
  39. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Extractors/PixelDrain.py +0 -0
  40. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Extractors/PlayRu.py +0 -0
  41. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Extractors/RapidVid.py +0 -0
  42. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Extractors/SibNet.py +0 -0
  43. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Extractors/Sobreatsesuyp.py +0 -0
  44. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Extractors/TRsTX.py +0 -0
  45. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Extractors/TauVideo.py +0 -0
  46. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Extractors/TurboImgz.py +0 -0
  47. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Extractors/VidMoly.py +0 -0
  48. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Extractors/VidMoxy.py +0 -0
  49. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Extractors/VideoSeyred.py +0 -0
  50. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Plugins/DiziYou.py +0 -0
  51. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Plugins/FilmMakinesi.py +0 -0
  52. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Plugins/FullHDFilmizlesene.py +0 -0
  53. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Plugins/JetFilmizle.py +0 -0
  54. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Plugins/RecTV.py +0 -0
  55. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Plugins/SineWix.py +0 -0
  56. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/Plugins/UgurFilm.py +0 -0
  57. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/__main__.py +0 -0
  58. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream/requirements.txt +0 -0
  59. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream.egg-info/dependency_links.txt +0 -0
  60. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream.egg-info/entry_points.txt +0 -0
  61. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream.egg-info/requires.txt +0 -0
  62. {kekikstream-0.9.3 → kekikstream-1.0.1}/KekikStream.egg-info/top_level.txt +0 -0
  63. {kekikstream-0.9.3 → kekikstream-1.0.1}/LICENSE +0 -0
  64. {kekikstream-0.9.3 → kekikstream-1.0.1}/MANIFEST.in +0 -0
  65. {kekikstream-0.9.3 → kekikstream-1.0.1}/README.md +0 -0
  66. {kekikstream-0.9.3 → kekikstream-1.0.1}/setup.cfg +0 -0
@@ -14,6 +14,10 @@ class MediaHandler:
14
14
  self.title = title
15
15
 
16
16
  def play_media(self, extract_data: ExtractResult):
17
+ # Referer varsa headers'a ekle
18
+ if extract_data.referer:
19
+ self.headers.update({"Referer": extract_data.referer})
20
+
17
21
  # Google Drive gibi özel durumlar için yt-dlp kullan
18
22
  if self.headers.get("User-Agent") == "googleusercontent":
19
23
  return self.play_with_ytdlp(extract_data)
@@ -0,0 +1,17 @@
1
+ # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
+
3
+ from KekikStream.Core import ExtractorBase, ExtractResult
4
+ from Kekik.Sifreleme import AESManager
5
+ import re, json
6
+
7
+ class MolyStream(ExtractorBase):
8
+ name = "MolyStream"
9
+ main_url = "https://dbx.molystream.org"
10
+
11
+ async def extract(self, url, referer=None) -> ExtractResult:
12
+ return ExtractResult(
13
+ name = self.name,
14
+ url = url,
15
+ referer = url.replace("/sheila", ""),
16
+ subtitles = []
17
+ )
@@ -57,7 +57,7 @@ class DiziBox(PluginBase):
57
57
  episodes.append(Episode(
58
58
  season = ep_season,
59
59
  episode = ep_episode,
60
- title = ep_title.strip(),
60
+ title = "",
61
61
  url = ep_href,
62
62
  ))
63
63
 
@@ -89,8 +89,12 @@ class DiziBox(PluginBase):
89
89
 
90
90
  crypt_data = re.search(r"CryptoJS\.AES\.decrypt\(\"(.*)\",\"", istek.text)[1]
91
91
  crypt_pass = re.search(r"\",\"(.*)\"\);", istek.text)[1]
92
+ decode = CryptoJS.decrypt(crypt_pass, crypt_data)
92
93
 
93
- results.append(CryptoJS.decrypt(crypt_pass, crypt_data))
94
+ if video_match := re.search(r"file: '(.*)',", decode):
95
+ results.append(video_match[1])
96
+ else:
97
+ results.append(decode)
94
98
 
95
99
  elif "/player/moly/moly.php" in iframe_link:
96
100
  iframe_link = iframe_link.replace("moly.php?h=", "moly.php?wmode=opaque&h=")
@@ -77,7 +77,7 @@ class Dizilla(PluginBase):
77
77
  bolumler.append(Episode(
78
78
  season = sezon.get("seasonNumber"),
79
79
  episode = bolum.get("episodeNumber"),
80
- title = bolum.get("name"),
80
+ title = "",
81
81
  url = await self.url_base_degis(bolum.get("url"), self.main_url),
82
82
  ))
83
83
 
@@ -82,7 +82,7 @@ class SezonlukDizi(PluginBase):
82
82
  links = []
83
83
  for dil, label in [("1", "AltYazı"), ("0", "Dublaj")]:
84
84
  dil_istek = await self.oturum.post(
85
- url = f"{self.main_url}/ajax/dataAlternatif2.asp",
85
+ url = f"{self.main_url}/ajax/dataAlternatif22.asp",
86
86
  headers = {"X-Requested-With": "XMLHttpRequest"},
87
87
  data = {"bid": bid, "dil": dil},
88
88
  )
@@ -95,7 +95,7 @@ class SezonlukDizi(PluginBase):
95
95
  if dil_json.get("status") == "success":
96
96
  for veri in dil_json.get("data", []):
97
97
  veri_response = await self.oturum.post(
98
- url = f"{self.main_url}/ajax/dataEmbed.asp",
98
+ url = f"{self.main_url}/ajax/dataEmbed22.asp",
99
99
  headers = {"X-Requested-With": "XMLHttpRequest"},
100
100
  data = {"id": veri.get("id")},
101
101
  )
@@ -65,13 +65,13 @@ async def extract_next_f_push_data(source_code):
65
65
 
66
66
  class Shorten(PluginBase):
67
67
  name = "Shorten"
68
- main_url = "http://localhost:8080"
68
+ main_url = "https://shorten.com"
69
69
  token = None
70
70
 
71
71
  async def __giris(self):
72
- await self.oturum.get("https://shorten.com/tr", follow_redirects=True)
72
+ await self.oturum.get(f"{self.main_url}/tr", follow_redirects=True)
73
73
 
74
- self.token = await self.oturum.get("https://shorten.com/api/session")
74
+ self.token = await self.oturum.get(f"{self.main_url}/api/session")
75
75
  self.token = self.token.json().get("token")
76
76
 
77
77
  self.oturum.headers.update({"Authorization": f"Bearer {self.token}"})
@@ -94,7 +94,7 @@ class Shorten(PluginBase):
94
94
  if not self.token:
95
95
  await self.__giris()
96
96
 
97
- istek = await self.oturum.get(f"https://shorten.com/tr/series/{slug}", follow_redirects=True)
97
+ istek = await self.oturum.get(f"{self.main_url}/tr/series/{slug}", follow_redirects=True)
98
98
  veriler = await extract_next_f_push_data(istek.text)
99
99
  veriler = veriler["8"][-1]["children"][-2][-1]["children"][-1]["data"]
100
100
  return [
@@ -114,7 +114,7 @@ class Shorten(PluginBase):
114
114
  "User-Agent" : "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36",
115
115
  "Content-Type" : "application/json",
116
116
  "Origin" : "https://vod.byteplusapi.com",
117
- "Referer" : "https://shorten.com/",
117
+ "Referer" : f"{self.main_url}/",
118
118
  }
119
119
  )
120
120
 
@@ -128,7 +128,7 @@ class Shorten(PluginBase):
128
128
  raw_req = await self.raw_bolumler(slug)
129
129
  number, _hash = raw_req[0].values()
130
130
 
131
- istek = await self.oturum.get(f"https://shorten.com/tr/series/{slug}/episode-{number}-{_hash}", follow_redirects=True)
131
+ istek = await self.oturum.get(f"{self.main_url}/tr/series/{slug}/episode-{number}-{_hash}", follow_redirects=True)
132
132
  veriler = await extract_next_f_push_data(istek.text)
133
133
  veriler = veriler["b"][3]["children"][1][3]["children"][3]["children"][3]["children"][-1]
134
134
 
@@ -188,7 +188,7 @@ class Shorten(PluginBase):
188
188
  self._data[ep_model.url] = {
189
189
  "ext_name" : self.name,
190
190
  "name" : f"{ep_model.title}",
191
- "referer" : "https://shorten.com/tr",
191
+ "referer" : f"{self.main_url}/tr",
192
192
  "subtitles" : []
193
193
  }
194
194
 
@@ -7,19 +7,22 @@ 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
+ KekikStream sınıfı, eklenti, çıkarıcı, arayüz ve medya yönetimini yürütür.
12
+ """
11
13
  self.eklentiler_yonetici = PluginManager()
12
14
  self.cikaricilar_yonetici = ExtractorManager()
13
15
  self.arayuz_yonetici = UIManager()
14
16
  self.medya_yonetici = MediaManager()
15
17
  self.suanki_eklenti: PluginBase = None
16
18
  self.secilen_sonuc = None
19
+ self.dizi = False
17
20
 
18
21
  async def baslat(self):
19
- # Konsolu temizle ve başlık göster
20
- self.arayuz_yonetici.clear_console()
21
- konsol.rule("[bold cyan]KekikStream Başlatılıyor[/bold cyan]")
22
-
22
+ """
23
+ Uygulamayı başlatır: konsolu temizler, başlığı gösterir ve eklenti seçimiyle devam eder.
24
+ """
25
+ self._temizle_ve_baslik_goster("[bold cyan]KekikStream Başlatılıyor[/bold cyan]")
23
26
  # Eklenti kontrolü
24
27
  if not self.eklentiler_yonetici.get_plugin_names():
25
28
  return konsol.print("[bold red]Hiçbir eklenti bulunamadı![/bold red]")
@@ -30,8 +33,17 @@ class KekikStream:
30
33
  # Program kapanırken tüm eklentileri kapat
31
34
  await self.eklentiler_yonetici.close_plugins()
32
35
 
36
+ def _temizle_ve_baslik_goster(self, baslik: str):
37
+ """
38
+ Konsolu temizler ve verilen başlıkla bir kural (separator) gösterir.
39
+ """
40
+ self.arayuz_yonetici.clear_console()
41
+ konsol.rule(baslik)
42
+
33
43
  async def sonuc_bulunamadi(self):
34
- # Sonuç bulunamadığında kullanıcıya seçenekler sun
44
+ """
45
+ Arama sonucunda hiçbir içerik bulunamadığında kullanıcıya seçenekler sunar.
46
+ """
35
47
  secim = await self.arayuz_yonetici.select_from_list(
36
48
  message = "Ne yapmak istersiniz?",
37
49
  choices = ["Tüm Eklentilerde Ara", "Ana Menü", "Çıkış"]
@@ -46,7 +58,9 @@ class KekikStream:
46
58
  cikis_yap(False)
47
59
 
48
60
  async def eklenti_secimi(self):
49
- # Fuzzy ile eklenti seçimi yap
61
+ """
62
+ Kullanıcıdan eklenti seçimi alır ve seçime göre arama işlemini başlatır.
63
+ """
50
64
  eklenti_adi = await self.arayuz_yonetici.select_from_fuzzy(
51
65
  message = "Arama yapılacak eklentiyi seçin:",
52
66
  choices = ["Tüm Eklentilerde Ara", *self.eklentiler_yonetici.get_plugin_names()]
@@ -59,9 +73,10 @@ class KekikStream:
59
73
  await self.eklenti_ile_arama()
60
74
 
61
75
  async def eklenti_ile_arama(self):
62
- # Seçilen eklentide arama yap
63
- self.arayuz_yonetici.clear_console()
64
- konsol.rule(f"[bold cyan]{self.suanki_eklenti.name} Eklentisinde Arama Yapın[/bold cyan]")
76
+ """
77
+ Seçilen eklentiyle arama yapar; kullanıcıdan sorgu alır, sonuçları listeler ve seçim sonrası detayları gösterir.
78
+ """
79
+ self._temizle_ve_baslik_goster(f"[bold cyan]{self.suanki_eklenti.name} Eklentisinde Arama Yapın[/bold cyan]")
65
80
 
66
81
  # Kullanıcıdan sorgu al ve ara
67
82
  sorgu = await self.arayuz_yonetici.prompt_text("Arama sorgusu girin:")
@@ -71,21 +86,24 @@ class KekikStream:
71
86
  konsol.print("[bold red]Arama sonucu bulunamadı![/bold red]")
72
87
  return await self.sonuc_bulunamadi()
73
88
 
74
- if secilen_sonuc := await self.eklenti_sonuc_secimi(sonuclar):
89
+ secilen_sonuc = await self.eklenti_sonuc_secimi(sonuclar)
90
+ if secilen_sonuc:
75
91
  await self.sonuc_detaylari_goster({"plugin": self.suanki_eklenti.name, "url": secilen_sonuc})
76
92
 
77
- async def eklenti_sonuc_secimi(self, sonuclar):
78
- # Arama sonuçlarından birini seç
93
+ async def eklenti_sonuc_secimi(self, sonuclar: list):
94
+ """
95
+ Arama sonuçlarından kullanıcıya seçim yaptırır.
96
+ """
79
97
  return await self.arayuz_yonetici.select_from_fuzzy(
80
98
  message = "İçerik sonuçlarından birini seçin:",
81
99
  choices = [{"name": sonuc.title, "value": sonuc.url} for sonuc in sonuclar]
82
100
  )
83
101
 
84
102
  async def tum_eklentilerde_arama(self):
85
- # Tüm eklentilerde arama yap
86
- self.arayuz_yonetici.clear_console()
87
- konsol.rule("[bold cyan]Tüm Eklentilerde Arama Yapın[/bold cyan]")
88
-
103
+ """
104
+ Tüm eklentilerde arama yapar ve sonuçlara göre işlem yapar.
105
+ """
106
+ self._temizle_ve_baslik_goster("[bold cyan]Tüm Eklentilerde Arama Yapın[/bold cyan]")
89
107
  sorgu = await self.arayuz_yonetici.prompt_text("Arama sorgusu girin:")
90
108
  sonuclar = await self.tum_eklentilerde_arama_sorgula(sorgu)
91
109
 
@@ -95,11 +113,13 @@ class KekikStream:
95
113
  secilen_sonuc = await self.tum_sonuc_secimi(sonuclar)
96
114
 
97
115
  if secilen_sonuc:
98
- return await self.sonuc_detaylari_goster(secilen_sonuc)
116
+ await self.sonuc_detaylari_goster(secilen_sonuc)
99
117
 
100
118
  async def tum_eklentilerde_arama_sorgula(self, sorgu: str) -> list:
119
+ """
120
+ Tüm eklentilerde arama yapar ve bulunan sonuçları listeler.
121
+ """
101
122
  tum_sonuclar = []
102
-
103
123
  # Her eklentide arama yap
104
124
  for eklenti_adi, eklenti in self.eklentiler_yonetici.plugins.items():
105
125
  # Eklenti türü kontrolü
@@ -107,13 +127,24 @@ class KekikStream:
107
127
  konsol.print(f"[yellow][!] {eklenti_adi} geçerli bir PluginBase değil, atlanıyor...[/yellow]")
108
128
  continue
109
129
 
130
+ if eklenti_adi in ["Shorten"]:
131
+ continue
132
+
110
133
  konsol.log(f"[yellow][~] {eklenti_adi:<19} aranıyor...[/]")
111
134
  try:
112
135
  sonuclar = await eklenti.search(sorgu)
113
136
  if sonuclar:
114
137
  # Sonuçları listeye ekle
115
138
  tum_sonuclar.extend(
116
- [{"plugin": eklenti_adi, "title": sonuc.title, "url": sonuc.url, "poster": sonuc.poster} for sonuc in sonuclar]
139
+ [
140
+ {
141
+ "plugin" : eklenti_adi,
142
+ "title" : sonuc.title,
143
+ "url" : sonuc.url,
144
+ "poster" : sonuc.poster
145
+ }
146
+ for sonuc in sonuclar
147
+ ]
117
148
  )
118
149
  except Exception as hata:
119
150
  konsol.print(f"[bold red]{eklenti_adi} » hata oluştu: {hata}[/bold red]")
@@ -121,12 +152,12 @@ class KekikStream:
121
152
  if not tum_sonuclar:
122
153
  konsol.print("[bold red]Hiçbir sonuç bulunamadı![/bold red]")
123
154
  await self.sonuc_bulunamadi()
124
- return []
125
-
126
155
  return tum_sonuclar
127
156
 
128
- async def tum_sonuc_secimi(self, sonuclar):
129
- # Tüm sonuçlardan birini seç
157
+ async def tum_sonuc_secimi(self, sonuclar: list):
158
+ """
159
+ Tüm arama sonuçlarından kullanıcıya seçim yaptırır.
160
+ """
130
161
  secenekler = [
131
162
  {"name": f"[{sonuc['plugin']}]".ljust(21) + f" » {sonuc['title']}", "value": sonuc}
132
163
  for sonuc in sonuclar
@@ -137,7 +168,21 @@ class KekikStream:
137
168
  choices = secenekler
138
169
  )
139
170
 
171
+ async def _medya_bilgisi_yukle(self, url: str, deneme: int = 3):
172
+ """
173
+ Belirtilen URL için medya bilgilerini, belirlenen deneme sayısı kadar yüklemeye çalışır.
174
+ """
175
+ for _ in range(deneme):
176
+ with suppress(Exception):
177
+ return await self.suanki_eklenti.load_item(url)
178
+
179
+ konsol.print("[bold red]Medya bilgileri yüklenemedi![/bold red]")
180
+ return None
181
+
140
182
  async def sonuc_detaylari_goster(self, secilen_sonuc):
183
+ """
184
+ Seçilen sonucun detaylarını gösterir; medya bilgilerini yükler, dizi ise bölüm seçimi sağlar.
185
+ """
141
186
  self.secilen_sonuc = secilen_sonuc
142
187
  try:
143
188
  # Seçilen sonucun detaylarını al
@@ -149,41 +194,45 @@ class KekikStream:
149
194
  else:
150
195
  url = secilen_sonuc
151
196
 
152
- # Medya bilgilerini yükle (3 deneme hakkı)
153
- medya_bilgi = None
154
- for _ in range(3):
155
- with suppress(Exception):
156
- medya_bilgi = await self.suanki_eklenti.load_item(url)
157
- break
158
- if not medya_bilgi:
159
- konsol.print("[bold red]Medya bilgileri yüklenemedi![/bold red]")
160
- return await self.sonuc_bulunamadi()
197
+ medya_bilgi = await self._medya_bilgisi_yukle(url)
198
+ if not medya_bilgi:
199
+ return await self.sonuc_bulunamadi()
161
200
 
162
201
  except Exception as hata:
163
202
  konsol.log(secilen_sonuc)
164
203
  return hata_yakala(hata)
165
204
 
166
- # Medya başlığını ayarla ve bilgileri göster
205
+ # Medya bilgilerini göster ve başlığı ayarla
167
206
  self.medya_yonetici.set_title(f"{self.suanki_eklenti.name} | {medya_bilgi.title}")
168
207
  self.arayuz_yonetici.display_media_info(f"{self.suanki_eklenti.name} | {medya_bilgi.title}", medya_bilgi)
169
208
 
170
- # Dizi ise bölüm seçimi yap
209
+ # Eğer medya bilgisi dizi ise bölüm seçimi yapılır
171
210
  if isinstance(medya_bilgi, SeriesInfo):
172
- secilen_bolum = await self.arayuz_yonetici.select_from_fuzzy(
173
- message = "İzlemek istediğiniz bölümü seçin:",
174
- choices = [
175
- {"name": f"{bolum.season}. Sezon {bolum.episode}. Bölüm{f' - {bolum.title}' if bolum.title else ''}", "value": bolum.url}
176
- for bolum in medya_bilgi.episodes
177
- ]
178
- )
179
- if secilen_bolum:
180
- baglantilar = await self.suanki_eklenti.load_links(secilen_bolum)
181
- await self.baglanti_secenekleri_goster(baglantilar)
211
+ self.dizi = True
212
+ await self.dizi_bolum_secimi(medya_bilgi)
182
213
  else:
183
214
  baglantilar = await self.suanki_eklenti.load_links(medya_bilgi.url)
184
215
  await self.baglanti_secenekleri_goster(baglantilar)
185
216
 
217
+ async def dizi_bolum_secimi(self, medya_bilgi: SeriesInfo):
218
+ """
219
+ Dizi içeriği için bölüm seçimi yapar ve seçilen bölümün bağlantılarını yükler.
220
+ """
221
+ secilen_bolum = await self.arayuz_yonetici.select_from_fuzzy(
222
+ message = "İzlemek istediğiniz bölümü seçin:",
223
+ choices = [
224
+ {"name": f"{bolum.season}. Sezon {bolum.episode}. Bölüm" + (f" - {bolum.title}" if bolum.title else ""), "value": bolum.url}
225
+ for bolum in medya_bilgi.episodes
226
+ ]
227
+ )
228
+ if secilen_bolum:
229
+ baglantilar = await self.suanki_eklenti.load_links(secilen_bolum)
230
+ await self.baglanti_secenekleri_goster(baglantilar)
231
+
186
232
  async def baglanti_secenekleri_goster(self, baglantilar):
233
+ """
234
+ Bağlantı seçeneklerini kullanıcıya sunar ve seçilen bağlantıya göre oynatma işlemini gerçekleştirir.
235
+ """
187
236
  if not baglantilar:
188
237
  konsol.print("[bold red]Hiçbir bağlantı bulunamadı![/bold red]")
189
238
  return await self.sonuc_bulunamadi()
@@ -202,16 +251,7 @@ class KekikStream:
202
251
 
203
252
  # Doğrudan oynatma seçeneği
204
253
  if not haritalama:
205
- secilen_link = await self.arayuz_yonetici.select_from_list(
206
- message = "Doğrudan oynatmak için bir bağlantı seçin:",
207
- choices = [{"name": value["ext_name"], "value": key} for key, value in self.suanki_eklenti._data.items() if key in baglantilar]
208
- )
209
- if secilen_link:
210
- await self.medya_oynat(secilen_link)
211
-
212
- self.arayuz_yonetici.clear_console()
213
- konsol.rule(f"[bold cyan]{self.suanki_eklenti.name} » Bi Bölüm Daha?[/bold cyan]")
214
- return await self.sonuc_detaylari_goster(self.secilen_sonuc)
254
+ return await self.direkt_oynat(baglantilar)
215
255
 
216
256
  # Kullanıcı seçenekleri
217
257
  secim = await self.arayuz_yonetici.select_from_list(
@@ -234,16 +274,39 @@ class KekikStream:
234
274
  case _:
235
275
  await self.baslat()
236
276
 
237
- async def medya_oynat(self, secilen_link):
238
- # Eklentinin kendi oynatıcısı varsa onu kullan
277
+ async def direkt_oynat(self, baglantilar):
278
+ """
279
+ Extractor eşleşmesi yoksa, doğrudan oynatma seçeneği sunar.
280
+ """
281
+ secilen_link = await self.arayuz_yonetici.select_from_list(
282
+ message = "Doğrudan oynatmak için bir bağlantı seçin:",
283
+ choices = [
284
+ {"name": value["ext_name"], "value": key}
285
+ for key, value in self.suanki_eklenti._data.items() if key in baglantilar
286
+ ]
287
+ )
288
+ if secilen_link:
289
+ await self.medya_oynat(secilen_link)
290
+
291
+ async def bi_bolum_daha(self):
292
+ self._temizle_ve_baslik_goster(f"[bold cyan]{self.suanki_eklenti.name} » Bi Bölüm Daha?[/bold cyan]")
293
+ return await self.sonuc_detaylari_goster(self.secilen_sonuc)
294
+
295
+ async def medya_oynat(self, secilen_link: str):
296
+ """
297
+ Seçilen bağlantıya göre medya oynatma işlemini gerçekleştirir.
298
+ """
239
299
  if hasattr(self.suanki_eklenti, "play") and callable(self.suanki_eklenti.play):
240
300
  konsol.log(f"[yellow][»] Oynatılıyor : {secilen_link}")
241
- return await self.suanki_eklenti.play(
242
- name = self.suanki_eklenti._data[secilen_link]["name"],
301
+ data = self.suanki_eklenti._data.get(secilen_link, {})
302
+
303
+ await self.suanki_eklenti.play(
304
+ name = data.get("name"),
243
305
  url = secilen_link,
244
- referer = self.suanki_eklenti._data[secilen_link]["referer"],
245
- subtitles = self.suanki_eklenti._data[secilen_link]["subtitles"]
306
+ referer = data.get("referer"),
307
+ subtitles = data.get("subtitles")
246
308
  )
309
+ return await self.bi_bolum_daha() if self.dizi else await self.baslat()
247
310
 
248
311
  # Uygun çıkarıcıyı bul
249
312
  cikarici: ExtractorBase = self.cikaricilar_yonetici.find_extractor(secilen_link)
@@ -275,6 +338,8 @@ class KekikStream:
275
338
  self.medya_yonetici.set_headers({"Referer": secilen_data.referer})
276
339
  konsol.log(f"[yellow][»] Oynatılıyor : {secilen_data.url}")
277
340
  self.medya_yonetici.play_media(secilen_data)
341
+
342
+ await self.bi_bolum_daha() if self.dizi else await self.baslat()
278
343
 
279
344
  def basla():
280
345
  try:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: KekikStream
3
- Version: 0.9.3
3
+ Version: 1.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
@@ -34,6 +34,7 @@ KekikStream/Extractors/HDStreamAble.py
34
34
  KekikStream/Extractors/Hotlinger.py
35
35
  KekikStream/Extractors/MailRu.py
36
36
  KekikStream/Extractors/MixPlayHD.py
37
+ KekikStream/Extractors/MolyStream.py
37
38
  KekikStream/Extractors/Odnoklassniki.py
38
39
  KekikStream/Extractors/OkRuHTTP.py
39
40
  KekikStream/Extractors/OkRuSSL.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: KekikStream
3
- Version: 0.9.3
3
+ Version: 1.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
@@ -6,7 +6,7 @@ from io import open
6
6
  setup(
7
7
  # ? Genel Bilgiler
8
8
  name = "KekikStream",
9
- version = "0.9.3",
9
+ version = "1.0.1",
10
10
  url = "https://github.com/keyiflerolsun/KekikStream",
11
11
  description = "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ı",
12
12
  keywords = ["KekikStream", "KekikAkademi", "keyiflerolsun"],
File without changes
File without changes
File without changes
File without changes