KekikStream 2.0.0__tar.gz → 2.0.2__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 (95) hide show
  1. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Core/Extractor/ExtractorLoader.py +13 -8
  2. kekikstream-2.0.2/KekikStream/Core/Extractor/YTDLPCache.py +35 -0
  3. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Core/__init__.py +1 -0
  4. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Extractors/CloseLoad.py +1 -1
  5. kekikstream-2.0.2/KekikStream/Extractors/ContentX_.py +40 -0
  6. kekikstream-2.0.0/KekikStream/Extractors/OkRuHTTP.py → kekikstream-2.0.2/KekikStream/Extractors/Odnoklassniki_.py +5 -1
  7. kekikstream-2.0.0/KekikStream/Extractors/HDStreamAble.py → kekikstream-2.0.2/KekikStream/Extractors/PeaceMakerst_.py +1 -1
  8. kekikstream-2.0.2/KekikStream/Extractors/RapidVid_.py +7 -0
  9. kekikstream-2.0.0/KekikStream/Extractors/VidMolyMe.py → kekikstream-2.0.2/KekikStream/Extractors/VidMoly_.py +1 -1
  10. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Extractors/YTDLP.py +14 -9
  11. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Plugins/Dizilla.py +1 -1
  12. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Plugins/FilmMakinesi.py +2 -0
  13. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Plugins/JetFilmizle.py +52 -37
  14. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Plugins/Sinefy.py +4 -1
  15. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Plugins/Sinezy.py +16 -1
  16. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream.egg-info/PKG-INFO +1 -1
  17. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream.egg-info/SOURCES.txt +6 -10
  18. {kekikstream-2.0.0 → kekikstream-2.0.2}/PKG-INFO +1 -1
  19. {kekikstream-2.0.0 → kekikstream-2.0.2}/setup.py +1 -1
  20. kekikstream-2.0.0/KekikStream/Extractors/FourCX.py +0 -7
  21. kekikstream-2.0.0/KekikStream/Extractors/FourPichive.py +0 -7
  22. kekikstream-2.0.0/KekikStream/Extractors/FourPlayRu.py +0 -7
  23. kekikstream-2.0.0/KekikStream/Extractors/Hotlinger.py +0 -7
  24. kekikstream-2.0.0/KekikStream/Extractors/OkRuSSL.py +0 -7
  25. kekikstream-2.0.0/KekikStream/Extractors/Pichive.py +0 -7
  26. kekikstream-2.0.0/KekikStream/Extractors/PlayRu.py +0 -7
  27. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/CLI/__init__.py +0 -0
  28. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/CLI/pypi_kontrol.py +0 -0
  29. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Core/Extractor/ExtractorBase.py +0 -0
  30. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Core/Extractor/ExtractorManager.py +0 -0
  31. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Core/Extractor/ExtractorModels.py +0 -0
  32. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Core/Media/MediaHandler.py +0 -0
  33. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Core/Media/MediaManager.py +0 -0
  34. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Core/Plugin/PluginBase.py +0 -0
  35. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Core/Plugin/PluginLoader.py +0 -0
  36. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Core/Plugin/PluginManager.py +0 -0
  37. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Core/Plugin/PluginModels.py +0 -0
  38. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Core/UI/UIManager.py +0 -0
  39. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Extractors/ContentX.py +0 -0
  40. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Extractors/DzenRu.py +0 -0
  41. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Extractors/ExPlay.py +0 -0
  42. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Extractors/FirePlayer.py +0 -0
  43. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Extractors/HDPlayerSystem.py +0 -0
  44. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Extractors/JetTv.py +0 -0
  45. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Extractors/MailRu.py +0 -0
  46. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Extractors/MixPlayHD.py +0 -0
  47. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Extractors/MixTiger.py +0 -0
  48. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Extractors/MolyStream.py +0 -0
  49. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Extractors/Odnoklassniki.py +0 -0
  50. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Extractors/PeaceMakerst.py +0 -0
  51. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Extractors/PixelDrain.py +0 -0
  52. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Extractors/PlayerFilmIzle.py +0 -0
  53. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Extractors/RapidVid.py +0 -0
  54. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Extractors/SetPlay.py +0 -0
  55. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Extractors/SetPrime.py +0 -0
  56. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Extractors/SibNet.py +0 -0
  57. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Extractors/Sobreatsesuyp.py +0 -0
  58. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Extractors/TRsTX.py +0 -0
  59. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Extractors/TauVideo.py +0 -0
  60. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Extractors/TurboImgz.py +0 -0
  61. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Extractors/TurkeyPlayer.py +0 -0
  62. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Extractors/VidHide.py +0 -0
  63. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Extractors/VidMoly.py +0 -0
  64. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Extractors/VidMoxy.py +0 -0
  65. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Extractors/VidPapi.py +0 -0
  66. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Extractors/VideoSeyred.py +0 -0
  67. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Extractors/YildizKisaFilm.py +0 -0
  68. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Plugins/DiziBox.py +0 -0
  69. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Plugins/DiziPal.py +0 -0
  70. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Plugins/DiziYou.py +0 -0
  71. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Plugins/FilmBip.py +0 -0
  72. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Plugins/FilmModu.py +0 -0
  73. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Plugins/FullHDFilm.py +0 -0
  74. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Plugins/FullHDFilmizlesene.py +0 -0
  75. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Plugins/HDFilmCehennemi.py +0 -0
  76. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Plugins/KultFilmler.py +0 -0
  77. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Plugins/RecTV.py +0 -0
  78. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Plugins/RoketDizi.py +0 -0
  79. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Plugins/SelcukFlix.py +0 -0
  80. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Plugins/SezonlukDizi.py +0 -0
  81. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Plugins/SineWix.py +0 -0
  82. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Plugins/SinemaCX.py +0 -0
  83. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Plugins/SuperFilmGeldi.py +0 -0
  84. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/Plugins/UgurFilm.py +0 -0
  85. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/__init__.py +0 -0
  86. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/__main__.py +0 -0
  87. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream/requirements.txt +0 -0
  88. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream.egg-info/dependency_links.txt +0 -0
  89. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream.egg-info/entry_points.txt +0 -0
  90. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream.egg-info/requires.txt +0 -0
  91. {kekikstream-2.0.0 → kekikstream-2.0.2}/KekikStream.egg-info/top_level.txt +0 -0
  92. {kekikstream-2.0.0 → kekikstream-2.0.2}/LICENSE +0 -0
  93. {kekikstream-2.0.0 → kekikstream-2.0.2}/MANIFEST.in +0 -0
  94. {kekikstream-2.0.0 → kekikstream-2.0.2}/README.md +0 -0
  95. {kekikstream-2.0.0 → kekikstream-2.0.2}/setup.cfg +0 -0
@@ -60,9 +60,10 @@ class ExtractorLoader:
60
60
  if file.endswith(".py") and not file.startswith("__"):
61
61
  module_name = file[:-3] # .py uzantısını kaldır
62
62
  # konsol.log(f"[cyan]Okunan Dosya\t\t: {module_name}[/cyan]")
63
- if extractor := self._load_extractor(directory, module_name):
64
- # konsol.log(f"[magenta]Extractor Yüklendi\t: {extractor.__name__}[/magenta]")
65
- 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)
66
67
 
67
68
  # konsol.log(f"[yellow]{directory} dizininden yüklenen Extractor'lar: {[e.__name__ for e in extractors]}[/yellow]")
68
69
  return extractors
@@ -73,21 +74,25 @@ class ExtractorLoader:
73
74
  path = directory / f"{module_name}.py"
74
75
  spec = importlib.util.spec_from_file_location(module_name, path)
75
76
  if not spec or not spec.loader:
76
- return None
77
+ return []
77
78
 
78
79
  # Modülü içe aktar
79
80
  module = importlib.util.module_from_spec(spec)
80
81
  spec.loader.exec_module(module)
81
82
 
82
- # 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 = []
83
85
  for attr in dir(module):
84
86
  obj = getattr(module, attr)
85
- 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:
86
89
  # konsol.log(f"[green]Yüklenen sınıf\t\t: {module_name}.{obj.__name__} ({obj.__module__}.{obj.__name__})[/green]")
87
- return obj
90
+ extractors.append(obj)
91
+
92
+ return extractors
88
93
 
89
94
  except Exception as hata:
90
95
  konsol.log(f"[red][!] Extractor yüklenirken hata oluştu: {module_name}\nHata: {hata}")
91
96
  konsol.print(f"[dim]{traceback.format_exc()}[/dim]")
92
97
 
93
- return None
98
+ return []
@@ -0,0 +1,35 @@
1
+ # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
+
3
+ from Kekik.cli import konsol
4
+ from yt_dlp.extractor import gen_extractors
5
+
6
+ # Global cache (module-level singleton)
7
+ _YTDLP_EXTRACTORS_CACHE = None
8
+ _CACHE_INITIALIZED = False
9
+
10
+ def get_ytdlp_extractors() -> list:
11
+ """
12
+ yt-dlp extractorlarını cache'le ve döndür
13
+
14
+ Returns:
15
+ list: yt-dlp extractor sınıfları
16
+ """
17
+ global _YTDLP_EXTRACTORS_CACHE, _CACHE_INITIALIZED
18
+
19
+ if _CACHE_INITIALIZED:
20
+ return _YTDLP_EXTRACTORS_CACHE
21
+
22
+ try:
23
+ extractors = list(gen_extractors())
24
+ extractors = [ie for ie in extractors if ie.ie_key() != 'Generic']
25
+
26
+ _YTDLP_EXTRACTORS_CACHE = extractors
27
+ _CACHE_INITIALIZED = True
28
+
29
+ return extractors
30
+
31
+ except Exception as e:
32
+ konsol.log(f"[red][⚠] yt-dlp extractor cache hatası: {e}[/red]")
33
+ _YTDLP_EXTRACTORS_CACHE = []
34
+ _CACHE_INITIALIZED = True
35
+ return []
@@ -13,6 +13,7 @@ from .Extractor.ExtractorManager import ExtractorManager
13
13
  from .Extractor.ExtractorBase import ExtractorBase
14
14
  from .Extractor.ExtractorLoader import ExtractorLoader
15
15
  from .Extractor.ExtractorModels import ExtractResult, Subtitle
16
+ from .Extractor.YTDLPCache import get_ytdlp_extractors
16
17
 
17
18
  from .Media.MediaManager import MediaManager
18
19
  from .Media.MediaHandler import MediaHandler
@@ -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"
@@ -1,8 +1,7 @@
1
1
  # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
2
 
3
- from KekikStream.Core import ExtractorBase, ExtractResult, Subtitle
3
+ from KekikStream.Core import ExtractorBase, ExtractResult, Subtitle, get_ytdlp_extractors
4
4
  from urllib.parse import urlparse
5
- from yt_dlp.extractor import gen_extractors
6
5
  import yt_dlp, re, sys, os
7
6
 
8
7
  class YTDLP(ExtractorBase):
@@ -13,20 +12,22 @@ class YTDLP(ExtractorBase):
13
12
 
14
13
  @classmethod
15
14
  def _init_fast_domain_regex(cls):
15
+ """
16
+ Fast domain regex'i initialize et
17
+ """
16
18
  if cls._FAST_DOMAIN_RE is not None:
17
19
  return
18
20
 
19
21
  domains = set()
20
22
 
23
+ # Merkezi cache'den extractorları al
24
+ extractors = get_ytdlp_extractors()
25
+
21
26
  # yt-dlp extractor'larının _VALID_URL regex'lerinden domain yakala
22
27
  # Regex metinlerinde domainler genelde "\." şeklinde geçer.
23
28
  domain_pat = re.compile(r"(?:[a-z0-9-]+\\\.)+[a-z]{2,}", re.IGNORECASE)
24
29
 
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
+ for ie in extractors:
30
31
  valid = getattr(ie, "_VALID_URL", None)
31
32
  if not valid or not isinstance(valid, str):
32
33
  continue
@@ -89,7 +90,9 @@ class YTDLP(ExtractorBase):
89
90
  "no_warnings" : True, # Uyarı mesajları yok
90
91
  "extract_flat" : True, # Minimal işlem
91
92
  "no_check_certificates" : True,
92
- "ignoreerrors" : True # Hataları yoksay
93
+ "ignoreerrors" : True, # Hataları yoksay
94
+ "socket_timeout" : 3,
95
+ "retries" : 1
93
96
  }
94
97
 
95
98
  with yt_dlp.YoutubeDL(ydl_opts) as ydl:
@@ -116,7 +119,9 @@ class YTDLP(ExtractorBase):
116
119
  "no_warnings" : True,
117
120
  "extract_flat" : False, # Tam bilgi al
118
121
  "format" : "best", # En iyi kalite
119
- "no_check_certificates" : True
122
+ "no_check_certificates" : True,
123
+ "socket_timeout" : 3,
124
+ "retries" : 1
120
125
  }
121
126
 
122
127
  # Referer varsa header olarak ekle
@@ -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: 2.0.0
3
+ Version: 2.0.2
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
@@ -18,6 +18,7 @@ KekikStream/Core/Extractor/ExtractorBase.py
18
18
  KekikStream/Core/Extractor/ExtractorLoader.py
19
19
  KekikStream/Core/Extractor/ExtractorManager.py
20
20
  KekikStream/Core/Extractor/ExtractorModels.py
21
+ KekikStream/Core/Extractor/YTDLPCache.py
21
22
  KekikStream/Core/Media/MediaHandler.py
22
23
  KekikStream/Core/Media/MediaManager.py
23
24
  KekikStream/Core/Plugin/PluginBase.py
@@ -27,29 +28,24 @@ KekikStream/Core/Plugin/PluginModels.py
27
28
  KekikStream/Core/UI/UIManager.py
28
29
  KekikStream/Extractors/CloseLoad.py
29
30
  KekikStream/Extractors/ContentX.py
31
+ KekikStream/Extractors/ContentX_.py
30
32
  KekikStream/Extractors/DzenRu.py
31
33
  KekikStream/Extractors/ExPlay.py
32
34
  KekikStream/Extractors/FirePlayer.py
33
- KekikStream/Extractors/FourCX.py
34
- KekikStream/Extractors/FourPichive.py
35
- KekikStream/Extractors/FourPlayRu.py
36
35
  KekikStream/Extractors/HDPlayerSystem.py
37
- KekikStream/Extractors/HDStreamAble.py
38
- KekikStream/Extractors/Hotlinger.py
39
36
  KekikStream/Extractors/JetTv.py
40
37
  KekikStream/Extractors/MailRu.py
41
38
  KekikStream/Extractors/MixPlayHD.py
42
39
  KekikStream/Extractors/MixTiger.py
43
40
  KekikStream/Extractors/MolyStream.py
44
41
  KekikStream/Extractors/Odnoklassniki.py
45
- KekikStream/Extractors/OkRuHTTP.py
46
- KekikStream/Extractors/OkRuSSL.py
42
+ KekikStream/Extractors/Odnoklassniki_.py
47
43
  KekikStream/Extractors/PeaceMakerst.py
48
- KekikStream/Extractors/Pichive.py
44
+ KekikStream/Extractors/PeaceMakerst_.py
49
45
  KekikStream/Extractors/PixelDrain.py
50
- KekikStream/Extractors/PlayRu.py
51
46
  KekikStream/Extractors/PlayerFilmIzle.py
52
47
  KekikStream/Extractors/RapidVid.py
48
+ KekikStream/Extractors/RapidVid_.py
53
49
  KekikStream/Extractors/SetPlay.py
54
50
  KekikStream/Extractors/SetPrime.py
55
51
  KekikStream/Extractors/SibNet.py
@@ -60,7 +56,7 @@ KekikStream/Extractors/TurboImgz.py
60
56
  KekikStream/Extractors/TurkeyPlayer.py
61
57
  KekikStream/Extractors/VidHide.py
62
58
  KekikStream/Extractors/VidMoly.py
63
- KekikStream/Extractors/VidMolyMe.py
59
+ KekikStream/Extractors/VidMoly_.py
64
60
  KekikStream/Extractors/VidMoxy.py
65
61
  KekikStream/Extractors/VidPapi.py
66
62
  KekikStream/Extractors/VideoSeyred.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: KekikStream
3
- Version: 2.0.0
3
+ Version: 2.0.2
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 = "2.0.0",
9
+ version = "2.0.2",
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,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"
File without changes
File without changes
File without changes
File without changes