KekikStream 1.8.9__tar.gz → 1.9.4__tar.gz

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 (93) hide show
  1. kekikstream-1.9.4/KekikStream/Core/Extractor/ExtractorManager.py +70 -0
  2. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Core/Media/MediaHandler.py +5 -58
  3. kekikstream-1.9.4/KekikStream/Extractors/YTDLP.py +172 -0
  4. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream.egg-info/PKG-INFO +13 -20
  5. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream.egg-info/SOURCES.txt +1 -0
  6. {kekikstream-1.8.9 → kekikstream-1.9.4}/PKG-INFO +13 -20
  7. {kekikstream-1.8.9 → kekikstream-1.9.4}/README.md +12 -19
  8. {kekikstream-1.8.9 → kekikstream-1.9.4}/setup.py +1 -1
  9. kekikstream-1.8.9/KekikStream/Core/Extractor/ExtractorManager.py +0 -31
  10. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/CLI/__init__.py +0 -0
  11. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/CLI/pypi_kontrol.py +0 -0
  12. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Core/Extractor/ExtractorBase.py +0 -0
  13. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Core/Extractor/ExtractorLoader.py +0 -0
  14. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Core/Extractor/ExtractorModels.py +0 -0
  15. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Core/Media/MediaManager.py +0 -0
  16. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Core/Plugin/PluginBase.py +0 -0
  17. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Core/Plugin/PluginLoader.py +0 -0
  18. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Core/Plugin/PluginManager.py +0 -0
  19. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Core/Plugin/PluginModels.py +0 -0
  20. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Core/UI/UIManager.py +0 -0
  21. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Core/__init__.py +0 -0
  22. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/CloseLoad.py +0 -0
  23. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/ContentX.py +0 -0
  24. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/DzenRu.py +0 -0
  25. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/ExPlay.py +0 -0
  26. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/FirePlayer.py +0 -0
  27. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/FourCX.py +0 -0
  28. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/FourPichive.py +0 -0
  29. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/FourPlayRu.py +0 -0
  30. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/HDPlayerSystem.py +0 -0
  31. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/HDStreamAble.py +0 -0
  32. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/Hotlinger.py +0 -0
  33. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/JetTv.py +0 -0
  34. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/MailRu.py +0 -0
  35. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/MixPlayHD.py +0 -0
  36. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/MixTiger.py +0 -0
  37. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/MolyStream.py +0 -0
  38. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/Odnoklassniki.py +0 -0
  39. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/OkRuHTTP.py +0 -0
  40. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/OkRuSSL.py +0 -0
  41. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/PeaceMakerst.py +0 -0
  42. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/Pichive.py +0 -0
  43. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/PixelDrain.py +0 -0
  44. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/PlayRu.py +0 -0
  45. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/PlayerFilmIzle.py +0 -0
  46. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/RapidVid.py +0 -0
  47. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/SetPlay.py +0 -0
  48. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/SetPrime.py +0 -0
  49. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/SibNet.py +0 -0
  50. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/Sobreatsesuyp.py +0 -0
  51. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/TRsTX.py +0 -0
  52. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/TauVideo.py +0 -0
  53. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/TurboImgz.py +0 -0
  54. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/TurkeyPlayer.py +0 -0
  55. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/VidHide.py +0 -0
  56. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/VidMoly.py +0 -0
  57. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/VidMolyMe.py +0 -0
  58. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/VidMoxy.py +0 -0
  59. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/VidPapi.py +0 -0
  60. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/VideoSeyred.py +0 -0
  61. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Extractors/YildizKisaFilm.py +0 -0
  62. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Plugins/DiziBox.py +0 -0
  63. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Plugins/DiziPal.py +0 -0
  64. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Plugins/DiziYou.py +0 -0
  65. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Plugins/Dizilla.py +0 -0
  66. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Plugins/FilmBip.py +0 -0
  67. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Plugins/FilmMakinesi.py +0 -0
  68. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Plugins/FilmModu.py +0 -0
  69. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Plugins/FullHDFilm.py +0 -0
  70. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Plugins/FullHDFilmizlesene.py +0 -0
  71. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Plugins/HDFilmCehennemi.py +0 -0
  72. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Plugins/JetFilmizle.py +0 -0
  73. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Plugins/KultFilmler.py +0 -0
  74. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Plugins/RecTV.py +0 -0
  75. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Plugins/RoketDizi.py +0 -0
  76. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Plugins/SelcukFlix.py +0 -0
  77. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Plugins/SezonlukDizi.py +0 -0
  78. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Plugins/SineWix.py +0 -0
  79. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Plugins/Sinefy.py +0 -0
  80. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Plugins/SinemaCX.py +0 -0
  81. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Plugins/Sinezy.py +0 -0
  82. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Plugins/SuperFilmGeldi.py +0 -0
  83. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/Plugins/UgurFilm.py +0 -0
  84. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/__init__.py +0 -0
  85. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/__main__.py +0 -0
  86. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream/requirements.txt +0 -0
  87. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream.egg-info/dependency_links.txt +0 -0
  88. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream.egg-info/entry_points.txt +0 -0
  89. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream.egg-info/requires.txt +0 -0
  90. {kekikstream-1.8.9 → kekikstream-1.9.4}/KekikStream.egg-info/top_level.txt +0 -0
  91. {kekikstream-1.8.9 → kekikstream-1.9.4}/LICENSE +0 -0
  92. {kekikstream-1.8.9 → kekikstream-1.9.4}/MANIFEST.in +0 -0
  93. {kekikstream-1.8.9 → kekikstream-1.9.4}/setup.cfg +0 -0
@@ -0,0 +1,70 @@
1
+ # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
+
3
+ from .ExtractorLoader import ExtractorLoader
4
+ from .ExtractorBase import ExtractorBase
5
+
6
+ class ExtractorManager:
7
+ def __init__(self, extractor_dir="Extractors"):
8
+ # Çıkarıcı yükleyiciyi başlat ve tüm çıkarıcıları yükle
9
+ self.extractor_loader = ExtractorLoader(extractor_dir)
10
+ self.extractors = self.extractor_loader.load_all() # Sadece class'lar
11
+
12
+ # Lazy loading: Instance'lar ilk kullanımda oluşturulacak
13
+ self._extractor_instances = None # None = henüz oluşturulmadı
14
+ self._ytdlp_extractor = None
15
+ self._initialized = False
16
+
17
+ def _ensure_initialized(self):
18
+ """
19
+ Lazy initialization: İlk kullanımda TÜM extractorları initialize et
20
+
21
+ Startup'ta sadece class'ları yükledik (hızlı).
22
+ Şimdi instance'ları oluştur ve cache'le (bir kere).
23
+ """
24
+ if self._initialized:
25
+ return
26
+
27
+ # Instance listesi oluştur
28
+ self._extractor_instances = []
29
+
30
+ # TÜM extractorları instance'la
31
+ for extractor_cls in self.extractors:
32
+ instance = extractor_cls()
33
+
34
+ # YTDLP'yi ayrı tut
35
+ if instance.name == "yt-dlp":
36
+ self._ytdlp_extractor = instance
37
+ else:
38
+ self._extractor_instances.append(instance)
39
+
40
+ # YTDLP'yi EN BAŞA ekle
41
+ if self._ytdlp_extractor:
42
+ self._extractor_instances.insert(0, self._ytdlp_extractor)
43
+
44
+ self._initialized = True
45
+
46
+ def find_extractor(self, link) -> ExtractorBase:
47
+ """
48
+ Verilen bağlantıyı işleyebilecek çıkarıcıyı bul
49
+ """
50
+ self._ensure_initialized()
51
+ # Cached instance'ları kullan
52
+ for extractor in self._extractor_instances:
53
+ if extractor.can_handle_url(link):
54
+ return extractor
55
+
56
+ return None
57
+
58
+ def map_links_to_extractors(self, links) -> dict:
59
+ """
60
+ Bağlantıları uygun çıkarıcılarla eşleştir
61
+ """
62
+ mapping = {}
63
+ for link in links:
64
+ # Cached instance'ları kullan
65
+ for extractor in self._extractor_instances:
66
+ if extractor.can_handle_url(link):
67
+ mapping[link] = f"{extractor.name:<30} » {link.replace(extractor.main_url, '')}"
68
+ break # İlk eşleşmede dur
69
+
70
+ return mapping
@@ -2,62 +2,13 @@
2
2
 
3
3
  from ...CLI import konsol
4
4
  from ..Extractor.ExtractorModels import ExtractResult
5
- import subprocess, os, yt_dlp
5
+ import subprocess, os
6
6
 
7
7
  class MediaHandler:
8
8
  def __init__(self, title: str = "KekikStream"):
9
9
  self.title = title
10
10
  self.headers = {}
11
11
 
12
- def should_use_ytdlp(self, url: str, user_agent: str) -> bool:
13
- """
14
- yt-dlp gereken durumları profesyonel şekilde tespit et
15
-
16
- yt-dlp'nin native Python API'sini simulate mode ile kullanarak
17
- güvenilir ve performanslı tespit yapar.
18
-
19
- Args:
20
- url: Video URL'si
21
- user_agent: User-Agent string'i
22
-
23
- Returns:
24
- bool: yt-dlp kullanılması gerekiyorsa True
25
- """
26
- # 1. User-Agent bazlı kontrol (mevcut davranışı koru - RecTV, MolyStream için)
27
- ytdlp_user_agents = [
28
- "googleusercontent",
29
- "Mozilla/5.0 (X11; Linux x86_64; rv:101.0) Gecko/20100101 Firefox/101.0"
30
- ]
31
-
32
- if user_agent in ytdlp_user_agents:
33
- konsol.log("[cyan][ℹ] User-Agent bazlı yt-dlp tespiti[/cyan]")
34
- return True
35
-
36
- # 2. yt-dlp'nin native Python API'sini kullan (simulate mode)
37
- try:
38
- ydl_opts = {
39
- "simulate" : True, # Download yok, sadece tespit
40
- "quiet" : True, # Log kirliliği yok
41
- "no_warnings" : True, # Uyarı mesajları yok
42
- "extract_flat" : True # Minimal işlem
43
- }
44
-
45
- with yt_dlp.YoutubeDL(ydl_opts) as ydl:
46
- # URL'yi işleyebiliyor mu kontrol et
47
- info = ydl.extract_info(url, download=False, process=False)
48
-
49
- # Generic extractor ise atla
50
- if info and info.get("extractor_key") != "Generic":
51
- konsol.log(f"[cyan][ℹ] yt-dlp extractor: {info.get('extractor_key', 'Unknown')}[/cyan]")
52
- return True
53
-
54
- return False
55
-
56
- except Exception as e:
57
- # yt-dlp işleyemezse False döndür
58
- konsol.log(f"[yellow][⚠] yt-dlp kontrol hatası: {e}[/yellow]")
59
- return False
60
-
61
12
  def play_media(self, extract_data: ExtractResult):
62
13
  # user-agent ekle (varsayılan veya extract_data'dan)
63
14
  user_agent = extract_data.user_agent or "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_5)"
@@ -67,18 +18,14 @@ class MediaHandler:
67
18
  if extract_data.referer:
68
19
  self.headers["referer"] = extract_data.referer
69
20
 
21
+ # Özel Durumlar (RecTV vs. Googleusercontent)
22
+ if user_agent in ["googleusercontent", "Mozilla/5.0 (X11; Linux x86_64; rv:101.0) Gecko/20100101 Firefox/101.0"]:
23
+ return self.play_with_ytdlp(extract_data)
24
+
70
25
  # İşletim sistemine göre oynatıcı seç (Android durumu)
71
26
  if subprocess.check_output(['uname', '-o']).strip() == b'Android':
72
27
  return self.play_with_android_mxplayer(extract_data)
73
28
 
74
- # Akıllı yt-dlp tespiti
75
- if self.should_use_ytdlp(extract_data.url, user_agent):
76
- konsol.log("[green][✓] yt-dlp kullanılacak[/green]")
77
- success = self.play_with_ytdlp(extract_data)
78
- if success:
79
- return True
80
- konsol.log("[yellow][⚠] yt-dlp başarısız, standart oynatıcılar deneniyor...[/yellow]")
81
-
82
29
  # Oynatıcı öncelik sırası (fallback zincirleme)
83
30
  players = [
84
31
  ("MPV", self.play_with_mpv),
@@ -0,0 +1,172 @@
1
+ # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
+
3
+ from KekikStream.Core import ExtractorBase, ExtractResult, Subtitle
4
+ from urllib.parse import urlparse
5
+ from yt_dlp.extractor import gen_extractors
6
+ import yt_dlp, re, sys, os
7
+
8
+ class YTDLP(ExtractorBase):
9
+ name = "yt-dlp"
10
+ main_url = "" # Universal - tüm siteleri destekler
11
+
12
+ _FAST_DOMAIN_RE = None # compiled mega-regex (host üstünden)
13
+
14
+ @classmethod
15
+ def _init_fast_domain_regex(cls):
16
+ if cls._FAST_DOMAIN_RE is not None:
17
+ return
18
+
19
+ domains = set()
20
+
21
+ # yt-dlp extractor'larının _VALID_URL regex'lerinden domain yakala
22
+ # Regex metinlerinde domainler genelde "\." şeklinde geçer.
23
+ domain_pat = re.compile(r"(?:[a-z0-9-]+\\\.)+[a-z]{2,}", re.IGNORECASE)
24
+
25
+ for ie in gen_extractors():
26
+ # Generic'i fast-path'e dahil etmiyoruz
27
+ if getattr(ie, "IE_NAME", "").lower() == "generic":
28
+ continue
29
+
30
+ valid = getattr(ie, "_VALID_URL", None)
31
+ if not valid or not isinstance(valid, str):
32
+ continue
33
+
34
+ for m in domain_pat.findall(valid):
35
+ d = m.replace(r"\.", ".").lower()
36
+
37
+ # Çok agresif/şüpheli şeyleri elemek istersen burada filtre koyabilirsin
38
+ # (genelde gerek kalmıyor)
39
+ domains.add(d)
40
+
41
+ # Hiç domain çıkmazsa (çok uç durum) fallback: boş regex
42
+ if not domains:
43
+ cls._FAST_DOMAIN_RE = re.compile(r"$^") # hiçbir şeye match etmez
44
+ return
45
+
46
+ # Host eşleştirmesi: subdomain destekli (m.youtube.com, player.vimeo.com vs.)
47
+ # (?:^|.*\.) (domain1|domain2|...) $
48
+ joined = "|".join(sorted(re.escape(d) for d in domains))
49
+ pattern = rf"(?:^|.*\.)(?:{joined})$"
50
+ cls._FAST_DOMAIN_RE = re.compile(pattern, re.IGNORECASE)
51
+
52
+ def __init__(self):
53
+ self.__class__._init_fast_domain_regex()
54
+
55
+ def can_handle_url(self, url: str) -> bool:
56
+ """
57
+ Fast-path: URL host'unu tek mega-regex ile kontrol et (loop yok)
58
+ Slow-path: gerekirse mevcut extract_info tabanlı kontrolün
59
+ """
60
+ # URL parse + host al
61
+ try:
62
+ parsed = urlparse(url)
63
+ host = (parsed.hostname or "").lower()
64
+ except Exception:
65
+ host = ""
66
+
67
+ # Şemasız URL desteği: "youtube.com/..." gibi
68
+ if not host and "://" not in url:
69
+ try:
70
+ parsed = urlparse("https://" + url)
71
+ host = (parsed.hostname or "").lower()
72
+ except Exception:
73
+ host = ""
74
+
75
+ # Fast-path
76
+ if host and self.__class__._FAST_DOMAIN_RE.search(host):
77
+ return True
78
+
79
+ # SLOW PATH: Diğer siteler için yt-dlp'nin native kontrolü
80
+ try:
81
+ # stderr'ı geçici olarak kapat (hata mesajlarını gizle)
82
+ old_stderr = sys.stderr
83
+ sys.stderr = open(os.devnull, "w")
84
+
85
+ try:
86
+ ydl_opts = {
87
+ "simulate" : True, # Download yok, sadece tespit
88
+ "quiet" : True, # Log kirliliği yok
89
+ "no_warnings" : True, # Uyarı mesajları yok
90
+ "extract_flat" : True, # Minimal işlem
91
+ "no_check_certificates" : True,
92
+ "ignoreerrors" : True # Hataları yoksay
93
+ }
94
+
95
+ with yt_dlp.YoutubeDL(ydl_opts) as ydl:
96
+ # URL'yi işleyebiliyor mu kontrol et
97
+ info = ydl.extract_info(url, download=False, process=False)
98
+
99
+ # Generic extractor ise atla
100
+ if info and info.get("extractor_key") != "Generic":
101
+ return True
102
+
103
+ return False
104
+ finally:
105
+ # stderr'ı geri yükle
106
+ sys.stderr.close()
107
+ sys.stderr = old_stderr
108
+
109
+ except Exception:
110
+ # yt-dlp işleyemezse False döndür
111
+ return False
112
+
113
+ async def extract(self, url: str, referer: str | None = None) -> ExtractResult:
114
+ ydl_opts = {
115
+ "quiet" : True,
116
+ "no_warnings" : True,
117
+ "extract_flat" : False, # Tam bilgi al
118
+ "format" : "best", # En iyi kalite
119
+ "no_check_certificates" : True
120
+ }
121
+
122
+ # Referer varsa header olarak ekle
123
+ if referer:
124
+ ydl_opts["http_headers"] = {"Referer": referer}
125
+
126
+ with yt_dlp.YoutubeDL(ydl_opts) as ydl:
127
+ info = ydl.extract_info(url, download=False)
128
+
129
+ if not info:
130
+ raise ValueError("yt-dlp video bilgisi döndürmedi")
131
+
132
+ # Video URL'sini al
133
+ video_url = info.get("url")
134
+ if not video_url:
135
+ # Bazen formatlar listesinde olabilir
136
+ formats = info.get("formats", [])
137
+ if formats:
138
+ video_url = formats[-1].get("url") # Son format (genellikle en iyi)
139
+
140
+ if not video_url:
141
+ raise ValueError("Video URL bulunamadı")
142
+
143
+ # Altyazıları çıkar
144
+ subtitles = []
145
+ if subtitle_data := info.get("subtitles"):
146
+ for lang, subs in subtitle_data.items():
147
+ for sub in subs:
148
+ if sub_url := sub.get("url"):
149
+ subtitles.append(
150
+ Subtitle(
151
+ name=f"{lang} ({sub.get('ext', 'unknown')})",
152
+ url=sub_url
153
+ )
154
+ )
155
+
156
+ # User-Agent al
157
+ user_agent = None
158
+ http_headers = info.get("http_headers", {})
159
+ if http_headers:
160
+ user_agent = http_headers.get("User-Agent")
161
+
162
+ return ExtractResult(
163
+ name = self.name,
164
+ url = video_url,
165
+ referer = referer or info.get("webpage_url"),
166
+ user_agent = user_agent,
167
+ subtitles = subtitles
168
+ )
169
+
170
+ async def close(self):
171
+ """yt-dlp için cleanup gerekmez"""
172
+ pass
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: KekikStream
3
- Version: 1.8.9
3
+ Version: 1.9.4
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
@@ -92,13 +92,6 @@ pip install -U KekikStream
92
92
  KekikStream
93
93
  ```
94
94
 
95
- **Kütüphane (örnek arama):**
96
- ```python
97
- from KekikStream import Manager
98
- results = Manager().search("vikings")
99
- print(results[0].title)
100
- ```
101
-
102
95
  ---
103
96
 
104
97
  ## ✨ Özellikler
@@ -139,11 +132,11 @@ class MyPlugin(PluginBase):
139
132
 
140
133
  ### 🎬 Oynatıcı Desteği
141
134
 
142
- | Oynatıcı | Platform | Özellikler |
143
- |----------|----------|------------|
144
- | **VLC** | Desktop | Custom headers, subtitles, varsayılan |
145
- | **MPV** | Desktop | Custom headers, subtitles |
146
- | **MX Player** | Android | ADB üzerinden |
135
+ | Oynatıcı | Platform | Özellikler |
136
+ |---------------|----------|---------------------------|
137
+ | **MPV** | Desktop | Custom headers, subtitles |
138
+ | **VLC** | Desktop | Custom headers, subtitles |
139
+ | **MX Player** | Android | ADB üzerinden |
147
140
 
148
141
  > Özel durumlar için (Google Drive vb.) arka planda otomatik olarak yt-dlp devreye girer.
149
142
 
@@ -175,8 +168,8 @@ graph TB
175
168
  end
176
169
 
177
170
  subgraph Players
178
- VLC[🎥 VLC]
179
171
  MPV[🎥 MPV]
172
+ VLC[🎥 VLC]
180
173
  MX[🎥 MX Player]
181
174
  end
182
175
 
@@ -246,13 +239,13 @@ KekikStream/
246
239
 
247
240
  ## 📊 Performans
248
241
 
249
- | Metrik | Değer |
250
- |--------|-------|
251
- | Plugin Sayısı | 20+ |
252
- | Extractor Sayısı | 40+ |
242
+ | Metrik | Değer |
243
+ |----------------------|------------------|
244
+ | Plugin Sayısı | 20+ |
245
+ | Extractor Sayısı | 40+ |
253
246
  | Desteklenen Platform | Desktop, Android |
254
- | Async Arama | ✅ |
255
- | Cache Desteği | ✅ |
247
+ | Async Arama | ✅ |
248
+ | Cache Desteği | ✅ |
256
249
 
257
250
  ---
258
251
 
@@ -64,6 +64,7 @@ KekikStream/Extractors/VidMolyMe.py
64
64
  KekikStream/Extractors/VidMoxy.py
65
65
  KekikStream/Extractors/VidPapi.py
66
66
  KekikStream/Extractors/VideoSeyred.py
67
+ KekikStream/Extractors/YTDLP.py
67
68
  KekikStream/Extractors/YildizKisaFilm.py
68
69
  KekikStream/Plugins/DiziBox.py
69
70
  KekikStream/Plugins/DiziPal.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: KekikStream
3
- Version: 1.8.9
3
+ Version: 1.9.4
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
@@ -92,13 +92,6 @@ pip install -U KekikStream
92
92
  KekikStream
93
93
  ```
94
94
 
95
- **Kütüphane (örnek arama):**
96
- ```python
97
- from KekikStream import Manager
98
- results = Manager().search("vikings")
99
- print(results[0].title)
100
- ```
101
-
102
95
  ---
103
96
 
104
97
  ## ✨ Özellikler
@@ -139,11 +132,11 @@ class MyPlugin(PluginBase):
139
132
 
140
133
  ### 🎬 Oynatıcı Desteği
141
134
 
142
- | Oynatıcı | Platform | Özellikler |
143
- |----------|----------|------------|
144
- | **VLC** | Desktop | Custom headers, subtitles, varsayılan |
145
- | **MPV** | Desktop | Custom headers, subtitles |
146
- | **MX Player** | Android | ADB üzerinden |
135
+ | Oynatıcı | Platform | Özellikler |
136
+ |---------------|----------|---------------------------|
137
+ | **MPV** | Desktop | Custom headers, subtitles |
138
+ | **VLC** | Desktop | Custom headers, subtitles |
139
+ | **MX Player** | Android | ADB üzerinden |
147
140
 
148
141
  > Özel durumlar için (Google Drive vb.) arka planda otomatik olarak yt-dlp devreye girer.
149
142
 
@@ -175,8 +168,8 @@ graph TB
175
168
  end
176
169
 
177
170
  subgraph Players
178
- VLC[🎥 VLC]
179
171
  MPV[🎥 MPV]
172
+ VLC[🎥 VLC]
180
173
  MX[🎥 MX Player]
181
174
  end
182
175
 
@@ -246,13 +239,13 @@ KekikStream/
246
239
 
247
240
  ## 📊 Performans
248
241
 
249
- | Metrik | Değer |
250
- |--------|-------|
251
- | Plugin Sayısı | 20+ |
252
- | Extractor Sayısı | 40+ |
242
+ | Metrik | Değer |
243
+ |----------------------|------------------|
244
+ | Plugin Sayısı | 20+ |
245
+ | Extractor Sayısı | 40+ |
253
246
  | Desteklenen Platform | Desktop, Android |
254
- | Async Arama | ✅ |
255
- | Cache Desteği | ✅ |
247
+ | Async Arama | ✅ |
248
+ | Cache Desteği | ✅ |
256
249
 
257
250
  ---
258
251
 
@@ -55,13 +55,6 @@ pip install -U KekikStream
55
55
  KekikStream
56
56
  ```
57
57
 
58
- **Kütüphane (örnek arama):**
59
- ```python
60
- from KekikStream import Manager
61
- results = Manager().search("vikings")
62
- print(results[0].title)
63
- ```
64
-
65
58
  ---
66
59
 
67
60
  ## ✨ Özellikler
@@ -102,11 +95,11 @@ class MyPlugin(PluginBase):
102
95
 
103
96
  ### 🎬 Oynatıcı Desteği
104
97
 
105
- | Oynatıcı | Platform | Özellikler |
106
- |----------|----------|------------|
107
- | **VLC** | Desktop | Custom headers, subtitles, varsayılan |
108
- | **MPV** | Desktop | Custom headers, subtitles |
109
- | **MX Player** | Android | ADB üzerinden |
98
+ | Oynatıcı | Platform | Özellikler |
99
+ |---------------|----------|---------------------------|
100
+ | **MPV** | Desktop | Custom headers, subtitles |
101
+ | **VLC** | Desktop | Custom headers, subtitles |
102
+ | **MX Player** | Android | ADB üzerinden |
110
103
 
111
104
  > Özel durumlar için (Google Drive vb.) arka planda otomatik olarak yt-dlp devreye girer.
112
105
 
@@ -138,8 +131,8 @@ graph TB
138
131
  end
139
132
 
140
133
  subgraph Players
141
- VLC[🎥 VLC]
142
134
  MPV[🎥 MPV]
135
+ VLC[🎥 VLC]
143
136
  MX[🎥 MX Player]
144
137
  end
145
138
 
@@ -209,13 +202,13 @@ KekikStream/
209
202
 
210
203
  ## 📊 Performans
211
204
 
212
- | Metrik | Değer |
213
- |--------|-------|
214
- | Plugin Sayısı | 20+ |
215
- | Extractor Sayısı | 40+ |
205
+ | Metrik | Değer |
206
+ |----------------------|------------------|
207
+ | Plugin Sayısı | 20+ |
208
+ | Extractor Sayısı | 40+ |
216
209
  | Desteklenen Platform | Desktop, Android |
217
- | Async Arama | ✅ |
218
- | Cache Desteği | ✅ |
210
+ | Async Arama | ✅ |
211
+ | Cache Desteği | ✅ |
219
212
 
220
213
  ---
221
214
 
@@ -6,7 +6,7 @@ from io import open
6
6
  setup(
7
7
  # ? Genel Bilgiler
8
8
  name = "KekikStream",
9
- version = "1.8.9",
9
+ version = "1.9.4",
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"],
@@ -1,31 +0,0 @@
1
- # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
-
3
- from .ExtractorLoader import ExtractorLoader
4
- from .ExtractorBase import ExtractorBase
5
-
6
- class ExtractorManager:
7
- def __init__(self, extractor_dir="Extractors"):
8
- # Çıkarıcı yükleyiciyi başlat ve tüm çıkarıcıları yükle
9
- self.extractor_loader = ExtractorLoader(extractor_dir)
10
- self.extractors = self.extractor_loader.load_all()
11
-
12
- def find_extractor(self, link) -> ExtractorBase:
13
- # Verilen bağlantıyı işleyebilecek çıkarıcıyı bul
14
- for extractor_cls in self.extractors:
15
- extractor:ExtractorBase = extractor_cls()
16
- if extractor.can_handle_url(link):
17
- return extractor
18
-
19
- return None
20
-
21
- def map_links_to_extractors(self, links) -> dict:
22
- # Bağlantıları uygun çıkarıcılarla eşleştir
23
- mapping = {}
24
- for link in links:
25
- for extractor_cls in self.extractors:
26
- extractor:ExtractorBase = extractor_cls()
27
- if extractor.can_handle_url(link):
28
- mapping[link] = f"{extractor.name:<30} » {link.replace(extractor.main_url, '')}"
29
- break
30
-
31
- return mapping
File without changes
File without changes
File without changes