KekikStream 1.7.3__py3-none-any.whl → 1.7.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. KekikStream/Core/Extractor/ExtractorBase.py +23 -6
  2. KekikStream/Core/Plugin/PluginBase.py +29 -8
  3. KekikStream/Extractors/CloseLoad.py +2 -2
  4. KekikStream/Extractors/ContentX.py +4 -4
  5. KekikStream/Extractors/DzenRu.py +2 -2
  6. KekikStream/Extractors/ExPlay.py +2 -2
  7. KekikStream/Extractors/FirePlayer.py +1 -1
  8. KekikStream/Extractors/HDPlayerSystem.py +1 -1
  9. KekikStream/Extractors/JetTv.py +4 -5
  10. KekikStream/Extractors/MailRu.py +2 -2
  11. KekikStream/Extractors/MixPlayHD.py +2 -2
  12. KekikStream/Extractors/MixTiger.py +1 -1
  13. KekikStream/Extractors/Odnoklassniki.py +2 -2
  14. KekikStream/Extractors/PeaceMakerst.py +4 -4
  15. KekikStream/Extractors/PixelDrain.py +1 -1
  16. KekikStream/Extractors/PlayerFilmIzle.py +6 -7
  17. KekikStream/Extractors/RapidVid.py +2 -2
  18. KekikStream/Extractors/SetPlay.py +2 -2
  19. KekikStream/Extractors/SetPrime.py +1 -1
  20. KekikStream/Extractors/SibNet.py +2 -2
  21. KekikStream/Extractors/Sobreatsesuyp.py +4 -4
  22. KekikStream/Extractors/TRsTX.py +4 -4
  23. KekikStream/Extractors/TauVideo.py +2 -2
  24. KekikStream/Extractors/TurboImgz.py +2 -2
  25. KekikStream/Extractors/TurkeyPlayer.py +5 -6
  26. KekikStream/Extractors/VidHide.py +6 -7
  27. KekikStream/Extractors/VidMoly.py +4 -4
  28. KekikStream/Extractors/VidMoxy.py +2 -2
  29. KekikStream/Extractors/VidPapi.py +2 -2
  30. KekikStream/Extractors/VideoSeyred.py +3 -3
  31. KekikStream/Extractors/YildizKisaFilm.py +1 -1
  32. KekikStream/Plugins/DiziBox.py +15 -15
  33. KekikStream/Plugins/DiziPal.py +11 -11
  34. KekikStream/Plugins/DiziYou.py +4 -4
  35. KekikStream/Plugins/Dizilla.py +5 -5
  36. KekikStream/Plugins/FilmBip.py +4 -4
  37. KekikStream/Plugins/FilmMakinesi.py +3 -3
  38. KekikStream/Plugins/FilmModu.py +6 -6
  39. KekikStream/Plugins/FullHDFilm.py +7 -7
  40. KekikStream/Plugins/FullHDFilmizlesene.py +3 -3
  41. KekikStream/Plugins/HDFilmCehennemi.py +3 -0
  42. KekikStream/Plugins/JetFilmizle.py +6 -6
  43. KekikStream/Plugins/KultFilmler.py +6 -6
  44. KekikStream/Plugins/RecTV.py +6 -6
  45. KekikStream/Plugins/RoketDizi.py +6 -3
  46. KekikStream/Plugins/SelcukFlix.py +4 -4
  47. KekikStream/Plugins/SezonlukDizi.py +8 -8
  48. KekikStream/Plugins/SineWix.py +4 -4
  49. KekikStream/Plugins/Sinefy.py +6 -6
  50. KekikStream/Plugins/SinemaCX.py +9 -9
  51. KekikStream/Plugins/Sinezy.py +4 -4
  52. KekikStream/Plugins/SuperFilmGeldi.py +5 -5
  53. KekikStream/Plugins/UgurFilm.py +6 -6
  54. KekikStream/__init__.py +29 -16
  55. KekikStream/requirements.txt +2 -2
  56. {kekikstream-1.7.3.dist-info → kekikstream-1.7.6.dist-info}/METADATA +3 -2
  57. kekikstream-1.7.6.dist-info/RECORD +85 -0
  58. KekikStream/Extractors/VidStack.py +0 -75
  59. kekikstream-1.7.3.dist-info/RECORD +0 -86
  60. {kekikstream-1.7.3.dist-info → kekikstream-1.7.6.dist-info}/WHEEL +0 -0
  61. {kekikstream-1.7.3.dist-info → kekikstream-1.7.6.dist-info}/entry_points.txt +0 -0
  62. {kekikstream-1.7.3.dist-info → kekikstream-1.7.6.dist-info}/licenses/LICENSE +0 -0
  63. {kekikstream-1.7.3.dist-info → kekikstream-1.7.6.dist-info}/top_level.txt +0 -0
@@ -15,7 +15,7 @@ class SelcukFlix(PluginBase):
15
15
 
16
16
  async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
17
17
  full_url = f"{self.main_url}/{url}"
18
- resp = await self.cffi.get(full_url)
18
+ resp = await self.httpx.get(full_url)
19
19
  sel = Selector(resp.text)
20
20
 
21
21
  results = []
@@ -50,7 +50,7 @@ class SelcukFlix(PluginBase):
50
50
  "Referer": f"{self.main_url}/"
51
51
  }
52
52
 
53
- post_resp = await self.cffi.post(search_url, headers=headers)
53
+ post_resp = await self.httpx.post(search_url, headers=headers)
54
54
 
55
55
  try:
56
56
  resp_json = post_resp.json()
@@ -84,7 +84,7 @@ class SelcukFlix(PluginBase):
84
84
  return []
85
85
 
86
86
  async def load_item(self, url: str) -> SeriesInfo:
87
- resp = await self.cffi.get(url)
87
+ resp = await self.httpx.get(url)
88
88
  sel = Selector(resp.text)
89
89
 
90
90
  next_data = sel.css("script#__NEXT_DATA__::text").get()
@@ -143,7 +143,7 @@ class SelcukFlix(PluginBase):
143
143
  )
144
144
 
145
145
  async def load_links(self, url: str) -> list[dict]:
146
- resp = await self.cffi.get(url)
146
+ resp = await self.httpx.get(url)
147
147
  sel = Selector(resp.text)
148
148
 
149
149
  next_data = sel.css("script#__NEXT_DATA__::text").get()
@@ -23,7 +23,7 @@ class SezonlukDizi(PluginBase):
23
23
 
24
24
  #@kekik_cache(ttl=60*60)
25
25
  async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
26
- istek = await self.cffi.get(f"{url}{page}")
26
+ istek = await self.httpx.get(f"{url}{page}")
27
27
  secici = Selector(istek.text)
28
28
 
29
29
  return [
@@ -38,7 +38,7 @@ class SezonlukDizi(PluginBase):
38
38
 
39
39
  #@kekik_cache(ttl=60*60)
40
40
  async def search(self, query: str) -> list[SearchResult]:
41
- istek = await self.cffi.get(f"{self.main_url}/diziler.asp?adi={query}")
41
+ istek = await self.httpx.get(f"{self.main_url}/diziler.asp?adi={query}")
42
42
  secici = Selector(istek.text)
43
43
 
44
44
  return [
@@ -52,7 +52,7 @@ class SezonlukDizi(PluginBase):
52
52
 
53
53
  #@kekik_cache(ttl=60*60)
54
54
  async def load_item(self, url: str) -> SeriesInfo:
55
- istek = await self.cffi.get(url)
55
+ istek = await self.httpx.get(url)
56
56
  secici = Selector(istek.text)
57
57
 
58
58
  title = secici.css("div.header::text").get().strip()
@@ -63,14 +63,14 @@ class SezonlukDizi(PluginBase):
63
63
  rating = secici.css("div.dizipuani a div::text").re_first(r"[\d.,]+")
64
64
  actors = []
65
65
 
66
- actors_istek = await self.cffi.get(f"{self.main_url}/oyuncular/{url.split('/')[-1]}")
66
+ actors_istek = await self.httpx.get(f"{self.main_url}/oyuncular/{url.split('/')[-1]}")
67
67
  actors_secici = Selector(actors_istek.text)
68
68
  actors = [
69
69
  actor.css("div.header::text").get().strip()
70
70
  for actor in actors_secici.css("div.doubling div.ui")
71
71
  ]
72
72
 
73
- episodes_istek = await self.cffi.get(f"{self.main_url}/bolumler/{url.split('/')[-1]}")
73
+ episodes_istek = await self.httpx.get(f"{self.main_url}/bolumler/{url.split('/')[-1]}")
74
74
  episodes_secici = Selector(episodes_istek.text)
75
75
  episodes = []
76
76
 
@@ -104,7 +104,7 @@ class SezonlukDizi(PluginBase):
104
104
 
105
105
  #@kekik_cache(ttl=15*60)
106
106
  async def load_links(self, url: str) -> list[dict]:
107
- istek = await self.cffi.get(url)
107
+ istek = await self.httpx.get(url)
108
108
  secici = Selector(istek.text)
109
109
 
110
110
  bid = secici.css("div#dilsec::attr(data-id)").get()
@@ -113,7 +113,7 @@ class SezonlukDizi(PluginBase):
113
113
 
114
114
  results = []
115
115
  for dil, label in [("1", "Altyazı"), ("0", "Dublaj")]:
116
- dil_istek = await self.cffi.post(
116
+ dil_istek = await self.httpx.post(
117
117
  url = f"{self.main_url}/ajax/dataAlternatif22.asp",
118
118
  headers = {"X-Requested-With": "XMLHttpRequest"},
119
119
  data = {"bid": bid, "dil": dil},
@@ -126,7 +126,7 @@ class SezonlukDizi(PluginBase):
126
126
 
127
127
  if dil_json.get("status") == "success":
128
128
  for idx, veri in enumerate(dil_json.get("data", [])):
129
- veri_response = await self.cffi.post(
129
+ veri_response = await self.httpx.post(
130
130
  url = f"{self.main_url}/ajax/dataEmbed22.asp",
131
131
  headers = {"X-Requested-With": "XMLHttpRequest"},
132
132
  data = {"id": veri.get("id")},
@@ -37,7 +37,7 @@ class SineWix(PluginBase):
37
37
 
38
38
  #@kekik_cache(ttl=60*60)
39
39
  async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
40
- istek = await self.cffi.get(f"{url}/{page}")
40
+ istek = await self.httpx.get(f"{url}/{page}")
41
41
  veriler = istek.json()
42
42
 
43
43
  return [
@@ -52,7 +52,7 @@ class SineWix(PluginBase):
52
52
 
53
53
  #@kekik_cache(ttl=60*60)
54
54
  async def search(self, query: str) -> list[SearchResult]:
55
- istek = await self.cffi.get(f"{self.main_url}/sinewix/search/{query}")
55
+ istek = await self.httpx.get(f"{self.main_url}/sinewix/search/{query}")
56
56
 
57
57
  return [
58
58
  SearchResult(
@@ -68,7 +68,7 @@ class SineWix(PluginBase):
68
68
  item_type = url.split("?type=")[-1].split("&id=")[0]
69
69
  item_id = url.split("&id=")[-1]
70
70
 
71
- istek = await self.cffi.get(f"{self.main_url}/sinewix/{item_type}/{item_id}")
71
+ istek = await self.httpx.get(f"{self.main_url}/sinewix/{item_type}/{item_id}")
72
72
  veri = istek.json()
73
73
 
74
74
  match item_type:
@@ -143,7 +143,7 @@ class SineWix(PluginBase):
143
143
  if not url.startswith(self.main_url) and not url.startswith("{"):
144
144
  return [{"url": url, "name": "Video"}]
145
145
 
146
- istek = await self.cffi.get(url)
146
+ istek = await self.httpx.get(url)
147
147
  veri = istek.json()
148
148
 
149
149
  org_title = veri.get("title")
@@ -24,7 +24,7 @@ class Sinefy(PluginBase):
24
24
  else:
25
25
  full_url = f"{self.main_url}/{url}&page={page}"
26
26
 
27
- resp = await self.cffi.get(full_url)
27
+ resp = await self.httpx.get(full_url)
28
28
  sel = Selector(resp.text)
29
29
 
30
30
  results = []
@@ -51,7 +51,7 @@ class Sinefy(PluginBase):
51
51
  c_value = "MTc0NzI2OTAwMDU3ZTEwYmZjMDViNWFmOWIwZDViODg0MjU4MjA1ZmYxOThmZTYwMDdjMWQzMzliNzY5NzFlZmViMzRhMGVmNjgwODU3MGIyZA=="
52
52
 
53
53
  try:
54
- resp = await self.cffi.get(self.main_url)
54
+ resp = await self.httpx.get(self.main_url)
55
55
  sel = Selector(resp.text)
56
56
  cke = sel.css("input[name='cKey']::attr(value)").get()
57
57
  cval = sel.css("input[name='cValue']::attr(value)").get()
@@ -75,7 +75,7 @@ class Sinefy(PluginBase):
75
75
  "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8"
76
76
  }
77
77
 
78
- response = await self.cffi.post(post_url, data=data, headers=headers)
78
+ response = await self.httpx.post(post_url, data=data, headers=headers)
79
79
 
80
80
  try:
81
81
  # Extract JSON data from response (might contain garbage chars at start)
@@ -114,7 +114,7 @@ class Sinefy(PluginBase):
114
114
  return []
115
115
 
116
116
  async def load_item(self, url: str) -> SeriesInfo:
117
- resp = await self.cffi.get(url)
117
+ resp = await self.httpx.get(url)
118
118
  sel = Selector(resp.text)
119
119
 
120
120
  title = sel.css("h1::text").get()
@@ -149,7 +149,7 @@ class Sinefy(PluginBase):
149
149
  target_url = s_url if "/bolum-" in s_url else f"{s_url}/bolum-1"
150
150
 
151
151
  try:
152
- s_resp = await self.cffi.get(target_url)
152
+ s_resp = await self.httpx.get(target_url)
153
153
  s_sel = Selector(s_resp.text)
154
154
  ep_links = s_sel.css("div.ui.list.celled a.item")
155
155
 
@@ -200,7 +200,7 @@ class Sinefy(PluginBase):
200
200
  )
201
201
 
202
202
  async def load_links(self, url: str) -> list[dict]:
203
- resp = await self.cffi.get(url)
203
+ resp = await self.httpx.get(url)
204
204
  sel = Selector(resp.text)
205
205
 
206
206
  iframe = sel.css("iframe::attr(src)").get()
@@ -29,7 +29,7 @@ class SinemaCX(PluginBase):
29
29
  }
30
30
 
31
31
  async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
32
- istek = await self.cffi.get(url.replace("SAYFA", str(page)))
32
+ istek = await self.httpx.get(url.replace("SAYFA", str(page)))
33
33
  secici = Selector(istek.text)
34
34
 
35
35
  return [
@@ -44,7 +44,7 @@ class SinemaCX(PluginBase):
44
44
  ]
45
45
 
46
46
  async def search(self, query: str) -> list[SearchResult]:
47
- istek = await self.cffi.get(f"{self.main_url}/?s={query}")
47
+ istek = await self.httpx.get(f"{self.main_url}/?s={query}")
48
48
  secici = Selector(istek.text)
49
49
 
50
50
  return [
@@ -58,7 +58,7 @@ class SinemaCX(PluginBase):
58
58
  ]
59
59
 
60
60
  async def load_item(self, url: str) -> MovieInfo:
61
- istek = await self.cffi.get(url)
61
+ istek = await self.httpx.get(url)
62
62
  secici = Selector(istek.text)
63
63
 
64
64
  duration_match = re.search(r"Süre:.*?(\d+)\s*Dakika", istek.text)
@@ -76,7 +76,7 @@ class SinemaCX(PluginBase):
76
76
  )
77
77
 
78
78
  async def load_links(self, url: str) -> list[dict]:
79
- istek = await self.cffi.get(url)
79
+ istek = await self.httpx.get(url)
80
80
  secici = Selector(istek.text)
81
81
 
82
82
  iframe_list = [iframe.css("::attr(data-vsrc)").get() for iframe in secici.css("iframe")]
@@ -90,7 +90,7 @@ class SinemaCX(PluginBase):
90
90
 
91
91
  if has_only_trailer:
92
92
  alt_url = url.rstrip("/") + "/2/"
93
- alt_istek = await self.cffi.get(alt_url)
93
+ alt_istek = await self.httpx.get(alt_url)
94
94
  alt_sec = Selector(alt_istek.text)
95
95
  iframe_list = [iframe.css("::attr(data-vsrc)").get() for iframe in alt_sec.css("iframe")]
96
96
  iframe_list = [i for i in iframe_list if i]
@@ -105,8 +105,8 @@ class SinemaCX(PluginBase):
105
105
  results = []
106
106
 
107
107
  # Altyazı kontrolü
108
- self.cffi.headers.update({"Referer": f"{self.main_url}/"})
109
- iframe_istek = await self.cffi.get(iframe)
108
+ self.httpx.headers.update({"Referer": f"{self.main_url}/"})
109
+ iframe_istek = await self.httpx.get(iframe)
110
110
  iframe_text = iframe_istek.text
111
111
 
112
112
  subtitles = []
@@ -123,8 +123,8 @@ class SinemaCX(PluginBase):
123
123
  base_url = base_match[1]
124
124
  vid_id = iframe.split("/")[-1]
125
125
 
126
- self.cffi.headers.update({"X-Requested-With": "XMLHttpRequest"})
127
- vid_istek = await self.cffi.post(
126
+ self.httpx.headers.update({"X-Requested-With": "XMLHttpRequest"})
127
+ vid_istek = await self.httpx.post(
128
128
  f"https://{base_url}/player/index.php?data={vid_id}&do=getVideo",
129
129
  )
130
130
  vid_data = vid_istek.json()
@@ -16,7 +16,7 @@ class Sinezy(PluginBase):
16
16
 
17
17
  async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
18
18
  full_url = f"{self.main_url}/{url}page/{page}/"
19
- resp = await self.cffi.get(full_url)
19
+ resp = await self.httpx.get(full_url)
20
20
  sel = Selector(resp.text)
21
21
 
22
22
  results = []
@@ -36,7 +36,7 @@ class Sinezy(PluginBase):
36
36
 
37
37
  async def search(self, query: str) -> list[SearchResult]:
38
38
  url = f"{self.main_url}/arama/?s={query}"
39
- resp = await self.cffi.get(url)
39
+ resp = await self.httpx.get(url)
40
40
  sel = Selector(resp.text)
41
41
 
42
42
  results = []
@@ -54,7 +54,7 @@ class Sinezy(PluginBase):
54
54
  return results
55
55
 
56
56
  async def load_item(self, url: str) -> MovieInfo:
57
- resp = await self.cffi.get(url)
57
+ resp = await self.httpx.get(url)
58
58
  sel = Selector(resp.text)
59
59
 
60
60
  title = sel.css("div.detail::attr(title)").get()
@@ -76,7 +76,7 @@ class Sinezy(PluginBase):
76
76
  )
77
77
 
78
78
  async def load_links(self, url: str) -> list[dict]:
79
- resp = await self.cffi.get(url)
79
+ resp = await self.httpx.get(url)
80
80
 
81
81
  match = re.search(r"ilkpartkod\s*=\s*'([^']+)'", resp.text, re.IGNORECASE)
82
82
  if match:
@@ -26,7 +26,7 @@ class SuperFilmGeldi(PluginBase):
26
26
  }
27
27
 
28
28
  async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
29
- istek = await self.cffi.get(url.replace("SAYFA", str(page)))
29
+ istek = await self.httpx.get(url.replace("SAYFA", str(page)))
30
30
  secici = Selector(istek.text)
31
31
 
32
32
  return [
@@ -41,7 +41,7 @@ class SuperFilmGeldi(PluginBase):
41
41
  ]
42
42
 
43
43
  async def search(self, query: str) -> list[SearchResult]:
44
- istek = await self.cffi.get(f"{self.main_url}?s={query}")
44
+ istek = await self.httpx.get(f"{self.main_url}?s={query}")
45
45
  secici = Selector(istek.text)
46
46
 
47
47
  return [
@@ -55,7 +55,7 @@ class SuperFilmGeldi(PluginBase):
55
55
  ]
56
56
 
57
57
  async def load_item(self, url: str) -> MovieInfo:
58
- istek = await self.cffi.get(url)
58
+ istek = await self.httpx.get(url)
59
59
  secici = Selector(istek.text)
60
60
 
61
61
  title = secici.css("div.title h1::text").get()
@@ -77,7 +77,7 @@ class SuperFilmGeldi(PluginBase):
77
77
  )
78
78
 
79
79
  async def load_links(self, url: str) -> list[dict]:
80
- istek = await self.cffi.get(url)
80
+ istek = await self.httpx.get(url)
81
81
  secici = Selector(istek.text)
82
82
 
83
83
  iframe = self.fix_url(secici.css("div#vast iframe::attr(src)").get())
@@ -88,7 +88,7 @@ class SuperFilmGeldi(PluginBase):
88
88
 
89
89
  # Mix player özel işleme
90
90
  if "mix" in iframe and "index.php?data=" in iframe:
91
- iframe_istek = await self.cffi.get(iframe, headers={"Referer": f"{self.main_url}/"})
91
+ iframe_istek = await self.httpx.get(iframe, headers={"Referer": f"{self.main_url}/"})
92
92
  mix_point = re.search(r'videoUrl":"(.*)","videoServer', iframe_istek.text)
93
93
 
94
94
  if mix_point:
@@ -25,7 +25,7 @@ class UgurFilm(PluginBase):
25
25
 
26
26
  #@kekik_cache(ttl=60*60)
27
27
  async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
28
- istek = await self.cffi.get(f"{url}{page}", allow_redirects=True)
28
+ istek = await self.httpx.get(f"{url}{page}", allow_redirects=True)
29
29
  secici = Selector(istek.text)
30
30
 
31
31
  return [
@@ -40,7 +40,7 @@ class UgurFilm(PluginBase):
40
40
 
41
41
  #@kekik_cache(ttl=60*60)
42
42
  async def search(self, query: str) -> list[SearchResult]:
43
- istek = await self.cffi.get(f"{self.main_url}/?s={query}")
43
+ istek = await self.httpx.get(f"{self.main_url}/?s={query}")
44
44
  secici = Selector(istek.text)
45
45
 
46
46
  results = []
@@ -62,7 +62,7 @@ class UgurFilm(PluginBase):
62
62
 
63
63
  #@kekik_cache(ttl=60*60)
64
64
  async def load_item(self, url: str) -> MovieInfo:
65
- istek = await self.cffi.get(url)
65
+ istek = await self.httpx.get(url)
66
66
  secici = Selector(istek.text)
67
67
 
68
68
  title = secici.css("div.bilgi h2::text").get().strip()
@@ -84,12 +84,12 @@ class UgurFilm(PluginBase):
84
84
 
85
85
  #@kekik_cache(ttl=15*60)
86
86
  async def load_links(self, url: str) -> list[dict]:
87
- istek = await self.cffi.get(url)
87
+ istek = await self.httpx.get(url)
88
88
  secici = Selector(istek.text)
89
89
  results = []
90
90
 
91
91
  for idx, part_link in enumerate(secici.css("li.parttab a::attr(href)").getall()):
92
- sub_response = await self.cffi.get(part_link)
92
+ sub_response = await self.httpx.get(part_link)
93
93
  sub_selector = Selector(sub_response.text)
94
94
 
95
95
  iframe = sub_selector.css("div#vast iframe::attr(src)").get()
@@ -99,7 +99,7 @@ class UgurFilm(PluginBase):
99
99
  "alternative" : "vidmoly",
100
100
  "ord" : "0",
101
101
  }
102
- player_response = await self.cffi.post(
102
+ player_response = await self.httpx.post(
103
103
  url = f"{self.main_url}/player/ajax_sources.php",
104
104
  data = post_data
105
105
  )
KekikStream/__init__.py CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  from .CLI import konsol, cikis_yap, hata_yakala, pypi_kontrol_guncelle
4
4
  from .Core import PluginManager, ExtractorManager, UIManager, MediaManager, PluginBase, ExtractorBase, SeriesInfo
5
- from asyncio import run
5
+ from asyncio import run, TaskGroup, Semaphore
6
6
  from contextlib import suppress
7
7
 
8
8
  class KekikStream:
@@ -90,21 +90,34 @@ class KekikStream:
90
90
 
91
91
  query = await self.ui.prompt_text("Arama sorgusu:")
92
92
  all_results = []
93
-
94
- for name, plugin in self.plugin.plugins.items():
95
- if not isinstance(plugin, PluginBase) or name == "Shorten":
96
- continue
97
-
98
- konsol.log(f"[yellow][~] {name:<19} aranıyor...[/]")
99
- try:
100
- results = await plugin.search(query)
101
- if results:
102
- all_results.extend([
103
- {"plugin": name, "title": r.title, "url": r.url, "poster": r.poster}
104
- for r in results
105
- ])
106
- except Exception as e:
107
- konsol.print(f"[bold red]{name} hatası: {e}[/bold red]")
93
+
94
+ # Maksimum 5 eşzamanlı arama için semaphore
95
+ semaphore = Semaphore(5)
96
+
97
+ async def search_plugin(name: str, plugin: PluginBase):
98
+ """Tek bir plugin'de ara (semaphore ile sınırlandırılmış)"""
99
+ async with semaphore:
100
+ konsol.log(f"[yellow][~] {name:<19} aranıyor...[/]")
101
+ try:
102
+ results = await plugin.search(query)
103
+ if results:
104
+ return [
105
+ {"plugin": name, "title": r.title, "url": r.url, "poster": r.poster}
106
+ for r in results
107
+ ]
108
+ except Exception as e:
109
+ konsol.print(f"[bold red]{name} hatası: {e}[/bold red]")
110
+ return []
111
+
112
+ # Tüm plugin'leri paralel olarak ara
113
+ async with TaskGroup() as tg:
114
+ tasks = []
115
+ for name, plugin in self.plugin.plugins.items():
116
+ tasks.append(tg.create_task(search_plugin(name, plugin)))
117
+
118
+ # Sonuçları topla
119
+ for task in tasks:
120
+ all_results.extend(task.result())
108
121
 
109
122
  if not all_results:
110
123
  return await self.handle_no_results()
@@ -4,7 +4,7 @@ wheel
4
4
  Kekik
5
5
  curl-cffi
6
6
  cloudscraper
7
+ httpx
7
8
  parsel
8
-
9
9
  pydantic
10
- InquirerPy
10
+ InquirerPy
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: KekikStream
3
- Version: 1.7.3
3
+ Version: 1.7.6
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
@@ -10,12 +10,13 @@ Keywords: KekikStream,KekikAkademi,keyiflerolsun
10
10
  Classifier: Development Status :: 5 - Production/Stable
11
11
  Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
12
12
  Classifier: Programming Language :: Python :: 3
13
- Requires-Python: >=3.10
13
+ Requires-Python: >=3.11
14
14
  Description-Content-Type: text/markdown
15
15
  License-File: LICENSE
16
16
  Requires-Dist: setuptools
17
17
  Requires-Dist: wheel
18
18
  Requires-Dist: Kekik
19
+ Requires-Dist: httpx
19
20
  Requires-Dist: curl-cffi
20
21
  Requires-Dist: cloudscraper
21
22
  Requires-Dist: parsel
@@ -0,0 +1,85 @@
1
+ KekikStream/__init__.py,sha256=Qgb2Dq_10q_z1lSNcrU_M6e-iKwEwjvA_A6AGVgYDS4,13600
2
+ KekikStream/__main__.py,sha256=B81dQoeGEb-T5Sycs3eNAmW7unvx0Mef0syCjs4nPds,137
3
+ KekikStream/requirements.txt,sha256=ENISGfW7D7abbqEh-1Yp2BaQdFJyYIJ0p8zNTUscuwU,80
4
+ KekikStream/CLI/__init__.py,sha256=U6oLq_O7u5y2eHhBnmfhZNns_EqHHJXJmzl8jvZFUNY,230
5
+ KekikStream/CLI/pypi_kontrol.py,sha256=q6fNs6EKJDc5VuUFig9DBzLzNPp_kMD1vOVgLElcii8,1487
6
+ KekikStream/Core/__init__.py,sha256=ar2MZQF83ryfLfydEXcfjdwNe4Too_HT6bP-D_4TopA,710
7
+ KekikStream/Core/Extractor/ExtractorBase.py,sha256=0GO8u5YzsboYMLk6kmSJmzqLZAbX_HQq6so8-2lBuqQ,2177
8
+ KekikStream/Core/Extractor/ExtractorLoader.py,sha256=7uxUXTAuF65KKkmbI6iRiCiUhx-IqrronB7ixhchcTU,4289
9
+ KekikStream/Core/Extractor/ExtractorManager.py,sha256=4L1H3jiTnf0kTq4W6uS7n95bBYHlKJ8_hh0og8z4erQ,1244
10
+ KekikStream/Core/Extractor/ExtractorModels.py,sha256=vLxG99_cbWwTc-dbk8XzjCasvR0QkoKSX2R0FAY9gks,456
11
+ KekikStream/Core/Media/MediaHandler.py,sha256=OWYNhQfT9bcCs1qo4qGz0VXxMWCoi7CA4ZqfAUHUgFw,7084
12
+ KekikStream/Core/Media/MediaManager.py,sha256=9ItiUguOkk3wg3YY5uf3mrjfwLPCvggnP8QviX0uiuE,526
13
+ KekikStream/Core/Plugin/PluginBase.py,sha256=hlvErfJd_11wuhpIzI0Bfa0y3R4g5xM4VakSQJ-54mY,4425
14
+ KekikStream/Core/Plugin/PluginLoader.py,sha256=yZxMug-OcJ5RBm4fQkoquKrZxcBU7Pvt4IcY-d0WU8g,3393
15
+ KekikStream/Core/Plugin/PluginManager.py,sha256=CZVg1eegi8vfMfccx0DRV0Box8kXz-aoULTQLgbPbvM,893
16
+ KekikStream/Core/Plugin/PluginModels.py,sha256=Aty3V4B3nPStVVSjYO9EIBmbUhavChQwQjC3l5TsrQI,2583
17
+ KekikStream/Core/UI/UIManager.py,sha256=T4V_kdTTWa-UDamgLSKa__dWJuzcvRK9NuwBlzU9Bzc,1693
18
+ KekikStream/Extractors/CloseLoad.py,sha256=cas2l0vk3S8yt15xAoin_iz1dQhBvFPg4k6U_b8SF9w,911
19
+ KekikStream/Extractors/ContentX.py,sha256=HfQ3g5KlL7LxB-7lxE70kIwg17NvfEk6wEUtzo-7-nM,3044
20
+ KekikStream/Extractors/DzenRu.py,sha256=6QOXBdU5GoWvzDlfdrMk0vLXjzxYBOqYAKrgs70rPa8,1213
21
+ KekikStream/Extractors/ExPlay.py,sha256=yHXdE0lr6i_Dhv8TmuC5gBItU01T19mbTqglkWoG8Y0,1855
22
+ KekikStream/Extractors/FirePlayer.py,sha256=axp8TIrkvI224yhLphwf1AdtOH4eVcD8ZcRzMmds-hI,2163
23
+ KekikStream/Extractors/FourCX.py,sha256=4FrMj1IZBBpN_g1P6S3A-8eUu7QFwlt4fJXzJ7vfe0Q,221
24
+ KekikStream/Extractors/FourPichive.py,sha256=iq3BCUbih1UVF4y4BIWO--0hX5jP2nxqesNx3MGP3kQ,234
25
+ KekikStream/Extractors/FourPlayRu.py,sha256=wq1ylxKpsO_IBoYr_ALzB2dVrQpJ-jY9lf2zPhcAZX8,228
26
+ KekikStream/Extractors/HDPlayerSystem.py,sha256=Q7IYAfy1UMamy3aLWZA31-IjI4mQsKYpb3fiOiAM_GA,1340
27
+ KekikStream/Extractors/HDStreamAble.py,sha256=66n5EvIdX_or5cdnlJ_Uqmzi50n4rl9c5VCw8kBqhQk,245
28
+ KekikStream/Extractors/Hotlinger.py,sha256=NFMRgUmb6BCrJfa7Hi0VarDNYvCeVknBWEk24FKBBa0,224
29
+ KekikStream/Extractors/JetTv.py,sha256=kFw-_rgVxSuDGtOeYYvg0fa0P0kMcGLhexiD8y4BW5U,1625
30
+ KekikStream/Extractors/MailRu.py,sha256=9TfjtgqkbcRAvoWfSwDJK3zvtq1z5-_JCdPDdZj5UDI,1279
31
+ KekikStream/Extractors/MixPlayHD.py,sha256=810efcVXQ1OniIz7gGtrsjNpqFy5Z6HScxDsJNsubHA,1584
32
+ KekikStream/Extractors/MixTiger.py,sha256=nf5wq3Y_h2trE8bLbUWEza3BTgFK-Pfsb0OdQyar1VM,2238
33
+ KekikStream/Extractors/MolyStream.py,sha256=y1kB2Fuf0kEchl6mxcyFdaRWOKwt6zSwYy3ojPC135M,1171
34
+ KekikStream/Extractors/Odnoklassniki.py,sha256=YG_e3SbIUCwEkWXJHD1zihvbQiRByJEUPxBhI5e8hTs,3779
35
+ KekikStream/Extractors/OkRuHTTP.py,sha256=L-B0i_i_Vnm61GvUfd6cGIW-o_H4M-C7DO_cdw2rQPU,228
36
+ KekikStream/Extractors/OkRuSSL.py,sha256=FHJ5XZ1dO5ED3mIku3e3vnq8K0slrcr0jqhaUnHmfVk,227
37
+ KekikStream/Extractors/PeaceMakerst.py,sha256=NYrVJrh32iu1T5Lnv1cjpUdzFcPgxfgSt7JM4ZoejnE,2124
38
+ KekikStream/Extractors/Pichive.py,sha256=BSVYFwL3Ax6yGoS1WkpOWtngxNyuZLoKzpPwjibpu2s,221
39
+ KekikStream/Extractors/PixelDrain.py,sha256=ZpeNFnMTEgMggqdSeInJN7wkJ-7rEXZ6TfhVylQfkDM,992
40
+ KekikStream/Extractors/PlayRu.py,sha256=DQMZyCSJwLkrh-gfDD8T1DvUFNBAKUXpByeCAWuK6YY,215
41
+ KekikStream/Extractors/PlayerFilmIzle.py,sha256=eg3Yv7GDTHZxHyCNY8lpeZIqMHAbD-bLpzRifrvfGHI,2405
42
+ KekikStream/Extractors/RapidVid.py,sha256=reS-05xizyDP0HGYWlyVumvxtnBgpSDH95t5-Ii5R7M,2945
43
+ KekikStream/Extractors/SetPlay.py,sha256=lOk9v8YJAcFs6mL46RCxY2wJg1tXqgwlfpM6X_bEJEA,1934
44
+ KekikStream/Extractors/SetPrime.py,sha256=nLlPRUthnD6H4tLo4uONBXsGDZHEKpg8KTWAXDsTiq8,1564
45
+ KekikStream/Extractors/SibNet.py,sha256=j6hFTzUA0lJyruAq7rQuV9L7GJZMHfazzCmaLUU2uRE,877
46
+ KekikStream/Extractors/Sobreatsesuyp.py,sha256=JY3TjuKi95fNenKXustqmYa_9jFoW8Vo6OOMQfFhXEw,2036
47
+ KekikStream/Extractors/TRsTX.py,sha256=ui7EPM9S9z2nhNsy1S7KORSOsgaCpqP0tuGl1xN5f9E,2188
48
+ KekikStream/Extractors/TauVideo.py,sha256=9qF9N1a7bYkCAjMbUpso1JPw0m28Gq_gNSchpwgyUcU,1148
49
+ KekikStream/Extractors/TurboImgz.py,sha256=KYAtCQ33egsR1x6t08UFyF9ps6loCrRV5WZBFR5U-YA,856
50
+ KekikStream/Extractors/TurkeyPlayer.py,sha256=6gQ6Ht7gLd9_vBY81NqqsYbDIsEh5XQpGF19KWrqKH4,1226
51
+ KekikStream/Extractors/VidHide.py,sha256=3LHmRRurplnmlxKf5bnK2fgYQCQR2W9rB6-IcVubyvk,2517
52
+ KekikStream/Extractors/VidMoly.py,sha256=Rd_DIa1KUyBYpDFUfsCvtjwYCZ6ANjFkqxVOqH1Tq1E,3682
53
+ KekikStream/Extractors/VidMolyMe.py,sha256=ogLiFUJVqFbhtzQrZ1gSB9me85DiHvntjWtSvidYVS8,218
54
+ KekikStream/Extractors/VidMoxy.py,sha256=vwyw2MgC9EIdF4PYB_5O7gkUxF5JTkfbmlVudZewvNs,1799
55
+ KekikStream/Extractors/VidPapi.py,sha256=Y9wBhZi-uH5VlYJaREByjheAGuVKQ7gXqNkQ_dlwlVM,3287
56
+ KekikStream/Extractors/VideoSeyred.py,sha256=HHzS8Ew1yJgWmyzi64dJkPD5bGP6Ku00EoSdZ7ncgaA,2009
57
+ KekikStream/Extractors/YildizKisaFilm.py,sha256=TZp9y3TQBKs_6MLxrrnXV1RbqLuCxHXbEId63tiBPcg,1344
58
+ KekikStream/Plugins/DiziBox.py,sha256=P9DwqsI3XqNJtTymZWL2TPOZmprxP1BRAIc0lJFeLmw,10091
59
+ KekikStream/Plugins/DiziPal.py,sha256=u9hAB7y3mo7MtP_wOth-wUA_xov4d8ktYu6DpR4NLHI,10194
60
+ KekikStream/Plugins/DiziYou.py,sha256=f1rxPM_9Mut2Cws3-sKesq5Gn9p0gZL7zvbrGrawqhk,8004
61
+ KekikStream/Plugins/Dizilla.py,sha256=aaORb3ZfNZm5gXB940d3Q9FgRjuNiVtQoY64W0hYbOA,7450
62
+ KekikStream/Plugins/FilmBip.py,sha256=wBp8jmjYuxv5nnI76skD2R_oSuS7CWhGTyQpM1YujHg,6054
63
+ KekikStream/Plugins/FilmMakinesi.py,sha256=CdV4k44dw0Q4rO3x4GobSDT1KGrkgit0OfTPxZfmfJ8,5314
64
+ KekikStream/Plugins/FilmModu.py,sha256=11c6dSMMfu6SQsIbRLD9n84KxN2MnbZ00nH0Tnc2aGk,6792
65
+ KekikStream/Plugins/FullHDFilm.py,sha256=kkb-JtWf23uiEzP9f_uds0tROYiKOyxcX0D-jNtQFi0,7005
66
+ KekikStream/Plugins/FullHDFilmizlesene.py,sha256=UYOMLJqbH72gkXWizNV3gWLZHATWeC6h8YaqThgGduI,6281
67
+ KekikStream/Plugins/HDFilmCehennemi.py,sha256=w49XXVNyU9hyA5vU0pIkJbB4OzHaa15p8STtnkVa1Uc,9913
68
+ KekikStream/Plugins/JetFilmizle.py,sha256=7EpWvl2mUCRq8x72ZMluUSurAq9pJjWtVQNCtKXyG_Y,6091
69
+ KekikStream/Plugins/KultFilmler.py,sha256=VZET3RUoOVYKE-C2YbkMW8oNcxz6zE2pR7a3z-B4nD4,8987
70
+ KekikStream/Plugins/RecTV.py,sha256=000u2dwMVd9HgqFn1m74y97Yod6gOwVR2zEiIkJvno8,7713
71
+ KekikStream/Plugins/RoketDizi.py,sha256=lmdGNkv8QdmOsYcC3BQbviXHL94qVzz5onGNOXF8c9w,7813
72
+ KekikStream/Plugins/SelcukFlix.py,sha256=F3Rv2TRpfM-SZUAqjTPsQChS_Ejoh5q1Mo5fBFlsLy0,9013
73
+ KekikStream/Plugins/SezonlukDizi.py,sha256=IomeNsVlji1TCimv8JwdMquKLcxZwwJQOZYzJ5v0OdE,6455
74
+ KekikStream/Plugins/SineWix.py,sha256=NbILBaYMj-Mxei4xOg3Si0l7L44qb5aAA-M6L_KIZ_w,7579
75
+ KekikStream/Plugins/Sinefy.py,sha256=mRwtQYiH7I_1k4EZS0g4MhnRDEx0NXwY8sa5tI33dog,8368
76
+ KekikStream/Plugins/SinemaCX.py,sha256=-vCHGhycKOoynnfkhTQwmMrBl_c7IsTO43UuIQwf3Mk,7263
77
+ KekikStream/Plugins/Sinezy.py,sha256=t7InHEtKdIVyBQj8HJWwWcHhRP9AXKKXYE0O3YD8MYg,3647
78
+ KekikStream/Plugins/SuperFilmGeldi.py,sha256=Ohm21BPsJH_S1tx5i2APEgAOD25k2NiwRP7rSgAKvRs,5289
79
+ KekikStream/Plugins/UgurFilm.py,sha256=DSzQD9wQMFiUKn82VNJ2KTpRhwx3X8K9Aj-zBCbpZVc,4960
80
+ kekikstream-1.7.6.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
81
+ kekikstream-1.7.6.dist-info/METADATA,sha256=1ydcxLOOiPby9eMkv5BH0wARJjCiLkeXxcyYsN4F-1E,4983
82
+ kekikstream-1.7.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
83
+ kekikstream-1.7.6.dist-info/entry_points.txt,sha256=dFwdiTx8djyehI0Gsz-rZwjAfZzUzoBSrmzRu9ubjJc,50
84
+ kekikstream-1.7.6.dist-info/top_level.txt,sha256=DNmGJDXl27Drdfobrak8KYLmocW_uznVYFJOzcjUgmY,12
85
+ kekikstream-1.7.6.dist-info/RECORD,,
@@ -1,75 +0,0 @@
1
- # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
-
3
- from KekikStream.Core import ExtractorBase, ExtractResult, Subtitle
4
- from Crypto.Cipher import AES
5
- from urllib.parse import urlparse
6
- import re, binascii
7
-
8
- class VidStack(ExtractorBase):
9
- name = "VidStack"
10
- main_url = "https://vidstack.io"
11
- requires_referer = True
12
-
13
- def get_base_url(self, url: str) -> str:
14
- try:
15
- parsed = urlparse(url)
16
- return f"{parsed.scheme}://{parsed.netloc}"
17
- except Exception:
18
- return self.main_url
19
-
20
- def decrypt_aes(self, encrypted_hex: str, key: str, iv: str) -> str:
21
- try:
22
- key_bytes = key.encode('utf-8')
23
- iv_bytes = iv.encode('utf-8')
24
- cipher = AES.new(key_bytes, AES.MODE_CBC, iv_bytes)
25
-
26
- encrypted_bytes = binascii.unhexlify(encrypted_hex)
27
- decrypted_bytes = cipher.decrypt(encrypted_bytes)
28
-
29
- # Remove PKCS5 padding
30
- padding_len = decrypted_bytes[-1]
31
- return decrypted_bytes[:-padding_len].decode('utf-8')
32
- except Exception:
33
- return None
34
-
35
- async def extract(self, url: str, referer: str = None) -> ExtractResult:
36
- self.cffi.headers.update({
37
- "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:134.0) Gecko/20100101 Firefox/134.0"
38
- })
39
-
40
- if referer:
41
- self.cffi.headers.update({"Referer": referer})
42
-
43
- video_hash = url.split("#")[-1].split("/")[-1]
44
- base_url = self.get_base_url(url)
45
-
46
- api_url = f"{base_url}/api/v1/video?id={video_hash}"
47
- istek = await self.cffi.get(api_url)
48
- encoded = istek.text.strip()
49
-
50
- key = "kiemtienmua911ca"
51
- iv_list = ["1234567890oiuytr", "0123456789abcdef"]
52
-
53
- decrypted_text = None
54
- for iv in iv_list:
55
- if result := self.decrypt_aes(encoded, key, iv):
56
- decrypted_text = result
57
- break
58
-
59
- if not decrypted_text:
60
- raise ValueError(f"VidStack: Şifre çözülemedi. {url}")
61
-
62
- m3u8_url = ""
63
- if match := re.search(r'"source":"(.*?)"', decrypted_text):
64
- m3u8_url = match.group(1).replace("\\/", "/")
65
-
66
- if not m3u8_url:
67
- raise ValueError(f"VidStack: Source bulunamadı. {url}")
68
-
69
- return ExtractResult(
70
- name = self.name,
71
- url = m3u8_url,
72
- referer = url,
73
- headers = {},
74
- subtitles = []
75
- )