KekikStream 2.4.6__py3-none-any.whl → 2.4.8__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.

Potentially problematic release.


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

Files changed (38) hide show
  1. KekikStream/Core/HTMLHelper.py +2 -2
  2. KekikStream/Core/Plugin/PluginBase.py +15 -4
  3. KekikStream/Extractors/Odnoklassniki.py +14 -2
  4. KekikStream/Extractors/YTDLP.py +2 -2
  5. KekikStream/Plugins/BelgeselX.py +30 -23
  6. KekikStream/Plugins/DiziBox.py +14 -11
  7. KekikStream/Plugins/DiziMom.py +110 -86
  8. KekikStream/Plugins/DiziPal.py +37 -23
  9. KekikStream/Plugins/DiziYou.py +23 -11
  10. KekikStream/Plugins/Dizilla.py +35 -30
  11. KekikStream/Plugins/FilmBip.py +83 -18
  12. KekikStream/Plugins/FilmEkseni.py +100 -58
  13. KekikStream/Plugins/FilmMakinesi.py +71 -19
  14. KekikStream/Plugins/FilmModu.py +17 -20
  15. KekikStream/Plugins/Filmatek.py +103 -98
  16. KekikStream/Plugins/{Full4kizle.py → FilmciBaba.py} +61 -80
  17. KekikStream/Plugins/FullHDFilmizlesene.py +12 -14
  18. KekikStream/Plugins/HDFilm.py +243 -0
  19. KekikStream/Plugins/HDFilmCehennemi.py +194 -125
  20. KekikStream/Plugins/JetFilmizle.py +5 -5
  21. KekikStream/Plugins/KultFilmler.py +6 -6
  22. KekikStream/Plugins/RoketDizi.py +5 -5
  23. KekikStream/Plugins/SelcukFlix.py +2 -2
  24. KekikStream/Plugins/SetFilmIzle.py +5 -5
  25. KekikStream/Plugins/SezonlukDizi.py +4 -4
  26. KekikStream/Plugins/Sinefy.py +5 -5
  27. KekikStream/Plugins/SinemaCX.py +5 -5
  28. KekikStream/Plugins/Sinezy.py +5 -5
  29. KekikStream/Plugins/SuperFilmGeldi.py +5 -5
  30. KekikStream/Plugins/UgurFilm.py +4 -4
  31. KekikStream/Plugins/YabanciDizi.py +5 -5
  32. {kekikstream-2.4.6.dist-info → kekikstream-2.4.8.dist-info}/METADATA +1 -1
  33. {kekikstream-2.4.6.dist-info → kekikstream-2.4.8.dist-info}/RECORD +37 -37
  34. KekikStream/Plugins/FullHDFilm.py +0 -179
  35. {kekikstream-2.4.6.dist-info → kekikstream-2.4.8.dist-info}/WHEEL +0 -0
  36. {kekikstream-2.4.6.dist-info → kekikstream-2.4.8.dist-info}/entry_points.txt +0 -0
  37. {kekikstream-2.4.6.dist-info → kekikstream-2.4.8.dist-info}/licenses/LICENSE +0 -0
  38. {kekikstream-2.4.6.dist-info → kekikstream-2.4.8.dist-info}/top_level.txt +0 -0
@@ -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 PluginBase, MainPageResult, SearchResult, MovieInfo, SeriesInfo, ExtractResult, HTMLHelper
4
- from json import dumps, loads
5
- import re
3
+ from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, ExtractResult, HTMLHelper
4
+ import asyncio
6
5
 
7
6
  class FilmEkseni(PluginBase):
8
7
  name = "FilmEkseni"
@@ -32,29 +31,30 @@ class FilmEkseni(PluginBase):
32
31
 
33
32
  async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
34
33
  istek = await self.httpx.get(f"{url}/{page}/")
35
- helper = HTMLHelper(istek.text)
36
- posters = helper.select("div.poster")
34
+ secici = HTMLHelper(istek.text)
35
+ posters = secici.select("div.poster")
37
36
 
38
37
  return [
39
38
  MainPageResult(
40
39
  category = category,
41
- title = self.clean_title(helper.select_text("h2", veri)),
42
- url = helper.select_attr("a", "href", veri),
43
- poster = helper.select_attr("img", "data-src", veri)
40
+ title = self.clean_title(secici.select_text("h2", veri)),
41
+ url = secici.select_attr("a", "href", veri),
42
+ poster = secici.select_attr("img", "data-src", veri)
44
43
  )
45
- for veri in posters
44
+ for veri in posters
46
45
  ]
47
46
 
48
47
  async def search(self, query: str) -> list[SearchResult]:
49
- url = f"{self.main_url}/search/"
50
- headers = {
51
- "X-Requested-With" : "XMLHttpRequest",
52
- "Content-Type" : "application/x-www-form-urlencoded; charset=UTF-8",
53
- "Referer" : self.main_url,
54
- }
55
- data = {"query": query}
56
-
57
- istek = await self.httpx.post(url, headers=headers, data=data)
48
+ istek = await self.httpx.post(
49
+ url = f"{self.main_url}/search/",
50
+ headers = {
51
+ "X-Requested-With" : "XMLHttpRequest",
52
+ "Content-Type" : "application/x-www-form-urlencoded; charset=UTF-8",
53
+ "Referer" : self.main_url,
54
+ },
55
+ data = {"query": query}
56
+ )
57
+
58
58
  veriler = istek.json().get("result", [])
59
59
 
60
60
  return [
@@ -63,58 +63,100 @@ class FilmEkseni(PluginBase):
63
63
  url = f"{self.main_url}/{veri.get('slug')}",
64
64
  poster = f"{self.main_url}/uploads/poster/{veri.get('cover')}" if veri.get('cover') else None,
65
65
  )
66
- for veri in veriler
66
+ for veri in veriler
67
67
  ]
68
68
 
69
69
  async def load_item(self, url: str) -> MovieInfo:
70
70
  istek = await self.httpx.get(url)
71
- helper = HTMLHelper(istek.text)
71
+ secici = HTMLHelper(istek.text)
72
72
 
73
- title = self.clean_title(helper.select_text("div.page-title h1"))
74
- poster = helper.select_poster("picture.poster-auto img")
75
- description = helper.select_direct_text("article.text-white p")
76
- year = helper.extract_year("div.page-title", "strong a")
77
- tags = helper.select_texts("div.pb-2 a[href*='/tur/']")
78
- rating = helper.select_text("div.rate")
79
- duration = helper.regex_first(r"(\d+)", helper.select_text("div.d-flex.flex-column.text-nowrap"))
80
- actors = helper.select_texts("div.card-body.p-0.pt-2 .story-item .story-item-title")
73
+ title = self.clean_title(secici.select_text("div.page-title h1"))
74
+ poster = secici.select_poster("picture.poster-auto img")
75
+ description = secici.select_direct_text("article.text-white p")
76
+ year = secici.extract_year("div.page-title", "strong a")
77
+ tags = secici.select_texts("div.pb-2 a[href*='/tur/']")
78
+ rating = secici.select_text("div.rate")
79
+ duration = secici.regex_first(r"(\d+)", secici.select_text("div.d-flex.flex-column.text-nowrap"))
80
+ actors = secici.select_texts("div.card-body.p-0.pt-2 .story-item .story-item-title")
81
81
 
82
82
  return MovieInfo(
83
83
  url = url,
84
- poster = self.fix_url(poster) if poster else None,
85
- title = title or "Bilinmiyor",
84
+ poster = self.fix_url(poster),
85
+ title = title,
86
86
  description = description,
87
87
  tags = tags,
88
88
  rating = rating,
89
- year = str(year) if year else None,
90
- actors = actors if actors else None,
91
- duration = int(duration) if duration else None
89
+ year = year,
90
+ actors = actors,
91
+ duration = duration
92
92
  )
93
93
 
94
+ async def _get_source_links(self, name: str, url: str, is_active: bool, initial_helper: HTMLHelper | None = None) -> list[ExtractResult]:
95
+ try:
96
+ if is_active and initial_helper:
97
+ secici = initial_helper
98
+ else:
99
+ resp = await self.httpx.get(url)
100
+ secici = HTMLHelper(resp.text)
101
+
102
+ iframe = secici.select_first("div.card-video iframe")
103
+ if not iframe:
104
+ return []
105
+
106
+ iframe_url = iframe.attrs.get("data-src") or iframe.attrs.get("src")
107
+ if not iframe_url:
108
+ return []
109
+
110
+ iframe_url = self.fix_url(iframe_url)
111
+ results = []
112
+
113
+ # VIP / EksenLoad mantığı
114
+ if "eksenload" in iframe_url or name == "VIP":
115
+ video_id = iframe_url.split("/")[-1]
116
+ master_url = f"https://eksenload.site/uploads/encode/{video_id}/master.m3u8"
117
+ results.append(ExtractResult(
118
+ url = master_url,
119
+ name = name,
120
+ referer = self.main_url
121
+ ))
122
+ else:
123
+ # Diğerleri (Moly, vs.) için extract
124
+ # Name override: "Kaynak Adı | Player Adı" olacak şekilde
125
+ extracted = await self.extract(iframe_url, name_override=name)
126
+ if extracted:
127
+ if isinstance(extracted, list):
128
+ results.extend(extracted)
129
+ else:
130
+ results.append(extracted)
131
+
132
+ return results
133
+ except Exception:
134
+ return []
135
+
94
136
  async def load_links(self, url: str) -> list[ExtractResult]:
95
137
  istek = await self.httpx.get(url)
96
- helper = HTMLHelper(istek.text)
97
-
98
- iframe = helper.select_first("div.card-video iframe")
99
- if not iframe:
100
- return []
101
-
102
- iframe_url = iframe.attrs.get("data-src") or iframe.attrs.get("src")
103
- if not iframe_url:
104
- return []
105
-
106
- if iframe_url.startswith("//"):
107
- iframe_url = f"https:{iframe_url}"
108
-
109
- video_id = iframe_url.split("/")[-1]
110
- master_url = f"https://eksenload.site/uploads/encode/{video_id}/master.m3u8"
111
-
112
- results = [
113
- ExtractResult(
114
- url = master_url,
115
- name = f"{self.name} | 1080p",
116
- referer = self.main_url
117
- )
118
- ]
119
-
120
- return results
138
+ secici = HTMLHelper(istek.text)
139
+
140
+ sources = [] # (name, url, is_active)
141
+ if nav_links := secici.select("nav.card-nav a.nav-link"):
142
+ seen_urls = set()
143
+ for link in nav_links:
144
+ if link.attrs.get("href") == "#":
145
+ continue # Sinema Modu vb.
146
+
147
+ name = link.text(strip=True)
148
+ href = link.attrs.get("href")
149
+ is_active = "active" in link.attrs.get("class", "")
150
+
151
+ if href and href not in seen_urls:
152
+ seen_urls.add(href)
153
+ sources.append((name, href, is_active))
154
+ else:
155
+ # Nav yoksa mevcut sayfayı (Varsayılan/VIP) al
156
+ sources.append(("VIP", url, True))
157
+
158
+ tasks = []
159
+ for name, link_url, is_active in sources:
160
+ tasks.append(self._get_source_links(name, link_url, is_active, secici if is_active else None))
161
+
162
+ return [item for sublist in await asyncio.gather(*tasks) for item in sublist]
@@ -1,6 +1,6 @@
1
1
  # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
2
 
3
- from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, SeriesInfo, Episode, ExtractResult, HTMLHelper
3
+ from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, SeriesInfo, Episode, ExtractResult, HTMLHelper
4
4
 
5
5
  class FilmMakinesi(PluginBase):
6
6
  name = "FilmMakinesi"
@@ -39,8 +39,8 @@ class FilmMakinesi(PluginBase):
39
39
 
40
40
  results = []
41
41
  for veri in secici.select("div.item-relative"):
42
- title = secici.select_text("div.title", veri)
43
- href = secici.select_attr("a", "href", veri)
42
+ title = secici.select_text("div.title", veri)
43
+ href = secici.select_attr("a", "href", veri)
44
44
  poster = secici.select_poster("img", veri)
45
45
 
46
46
  if title and href:
@@ -48,7 +48,7 @@ class FilmMakinesi(PluginBase):
48
48
  category = category,
49
49
  title = title,
50
50
  url = self.fix_url(href),
51
- poster = self.fix_url(poster) if poster else None,
51
+ poster = self.fix_url(poster),
52
52
  ))
53
53
 
54
54
  return results
@@ -59,15 +59,15 @@ class FilmMakinesi(PluginBase):
59
59
 
60
60
  results = []
61
61
  for article in secici.select("div.item-relative"):
62
- title = secici.select_text("div.title", article)
63
- href = secici.select_attr("a", "href", article)
62
+ title = secici.select_text("div.title", article)
63
+ href = secici.select_attr("a", "href", article)
64
64
  poster = secici.select_poster("img", article)
65
65
 
66
66
  if title and href:
67
67
  results.append(SearchResult(
68
- title = title.strip(),
69
- url = self.fix_url(href.strip()),
70
- poster = self.fix_url(poster.strip()) if poster else None,
68
+ title = title,
69
+ url = self.fix_url(href),
70
+ poster = self.fix_url(poster),
71
71
  ))
72
72
 
73
73
  return results
@@ -79,7 +79,7 @@ class FilmMakinesi(PluginBase):
79
79
  title = self.clean_title(secici.select_text("h1.title"))
80
80
  poster = secici.select_poster("img.cover-img")
81
81
  description = secici.select_text("div.info-description p")
82
- rating = secici.regex_first(r"(\d+[\d.]*)", secici.select_text("div.score"))
82
+ rating = secici.select_text("div.info div.imdb b")
83
83
  year = secici.select_text("span.date a")
84
84
  actors = secici.select_texts("div.cast-name")
85
85
  tags = secici.select_texts("div.type a[href*='/tur/']")
@@ -91,8 +91,13 @@ class FilmMakinesi(PluginBase):
91
91
  s, e = secici.extract_season_episode(href)
92
92
  if s and e:
93
93
  name = link.text(strip=True).split("Bölüm")[-1].strip() if "Bölüm" in link.text() else ""
94
- episodes.append(Episode(season=s, episode=e, title=name, url=self.fix_url(href)))
95
-
94
+ episodes.append(Episode(
95
+ season = s,
96
+ episode = e,
97
+ title = name,
98
+ url = self.fix_url(href)
99
+ ))
100
+
96
101
  # Tekrar edenleri temizle ve sırala
97
102
  if episodes:
98
103
  seen = set()
@@ -104,20 +109,36 @@ class FilmMakinesi(PluginBase):
104
109
  unique.sort(key=lambda x: (x.season or 0, x.episode or 0))
105
110
 
106
111
  return SeriesInfo(
107
- url=url, poster=self.fix_url(poster) if poster else None, title=title, description=description,
108
- tags=tags, rating=rating, year=year, actors=actors, duration=duration, episodes=unique
112
+ url = url,
113
+ poster = self.fix_url(poster),
114
+ title = title,
115
+ description = description,
116
+ tags = tags,
117
+ rating = rating,
118
+ year = year,
119
+ actors = actors,
120
+ duration = duration,
121
+ episodes = unique
109
122
  )
110
123
 
111
124
  return MovieInfo(
112
- url=url, poster=self.fix_url(poster) if poster else None, title=title, description=description,
113
- tags=tags, rating=rating, year=year, actors=actors, duration=duration
125
+ url = url,
126
+ poster = self.fix_url(poster),
127
+ title = title,
128
+ description = description,
129
+ tags = tags,
130
+ rating = rating,
131
+ year = year,
132
+ actors = actors,
133
+ duration = duration
114
134
  )
115
135
 
116
136
  async def load_links(self, url: str) -> list[ExtractResult]:
117
137
  istek = await self.httpx.get(url)
118
138
  secici = HTMLHelper(istek.text)
119
139
 
120
- response = []
140
+ response = []
141
+ shared_subs = []
121
142
 
122
143
  # Video parts linklerini ve etiketlerini al
123
144
  for link in secici.select("div.video-parts a[data-video_url]"):
@@ -127,7 +148,15 @@ class FilmMakinesi(PluginBase):
127
148
  if video_url:
128
149
  data = await self.extract(video_url, prefix=label.split()[0] if label else None)
129
150
  if data:
130
- response.append(data)
151
+ if isinstance(data, list):
152
+ for d in data:
153
+ response.append(d)
154
+ if d.subtitles:
155
+ shared_subs.extend(d.subtitles)
156
+ else:
157
+ response.append(data)
158
+ if data.subtitles:
159
+ shared_subs.extend(data.subtitles)
131
160
 
132
161
  # Eğer video-parts yoksa iframe kullan
133
162
  if not response:
@@ -135,6 +164,29 @@ class FilmMakinesi(PluginBase):
135
164
  if iframe_src:
136
165
  data = await self.extract(iframe_src)
137
166
  if data:
138
- response.append(data)
167
+ if isinstance(data, list):
168
+ for d in data:
169
+ response.append(d)
170
+ if d.subtitles:
171
+ shared_subs.extend(d.subtitles)
172
+ else:
173
+ response.append(data)
174
+ if data.subtitles:
175
+ shared_subs.extend(data.subtitles)
176
+
177
+ # Altyazıları Dağıt
178
+ if shared_subs:
179
+ unique_subs = []
180
+ seen_urls = set()
181
+ for sub in shared_subs:
182
+ if sub.url not in seen_urls:
183
+ seen_urls.add(sub.url)
184
+ unique_subs.append(sub)
185
+
186
+ for res in response:
187
+ current_urls = {s.url for s in res.subtitles}
188
+ for sub in unique_subs:
189
+ if sub.url not in current_urls:
190
+ res.subtitles.append(sub)
139
191
 
140
192
  return response
@@ -1,6 +1,6 @@
1
1
  # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
2
 
3
- from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, Subtitle, ExtractResult, HTMLHelper
3
+ from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, Subtitle, ExtractResult, HTMLHelper
4
4
 
5
5
  class FilmModu(PluginBase):
6
6
  name = "FilmModu"
@@ -44,8 +44,8 @@ class FilmModu(PluginBase):
44
44
 
45
45
  results = []
46
46
  for veri in secici.select("div.movie"):
47
- title = secici.select_text("a", veri)
48
- href = secici.select_attr("a", "href", veri)
47
+ title = secici.select_text("a", veri)
48
+ href = secici.select_attr("a", "href", veri)
49
49
  poster = secici.select_attr("picture img", "data-src", veri)
50
50
 
51
51
  if title and href:
@@ -53,7 +53,7 @@ class FilmModu(PluginBase):
53
53
  category = category,
54
54
  title = title,
55
55
  url = self.fix_url(href),
56
- poster = self.fix_url(poster) if poster else None,
56
+ poster = self.fix_url(poster),
57
57
  ))
58
58
 
59
59
  return results
@@ -64,15 +64,15 @@ class FilmModu(PluginBase):
64
64
 
65
65
  results = []
66
66
  for veri in secici.select("div.movie"):
67
- title = secici.select_text("a", veri)
68
- href = secici.select_attr("a", "href", veri)
67
+ title = secici.select_text("a", veri)
68
+ href = secici.select_attr("a", "href", veri)
69
69
  poster = secici.select_attr("picture img", "data-src", veri)
70
70
 
71
71
  if title and href:
72
72
  results.append(SearchResult(
73
73
  title = title,
74
74
  url = self.fix_url(href),
75
- poster = self.fix_url(poster) if poster else None,
75
+ poster = self.fix_url(poster),
76
76
  ))
77
77
 
78
78
  return results
@@ -83,7 +83,7 @@ class FilmModu(PluginBase):
83
83
 
84
84
  org_title = secici.select_text("div.titles h1")
85
85
  alt_title = secici.select_text("div.titles h2")
86
- title = f"{org_title} - {alt_title}" if alt_title else (org_title or "")
86
+ title = f"{org_title} - {alt_title}" if alt_title else (org_title)
87
87
  poster = secici.select_poster("img.img-responsive")
88
88
  description = secici.select_text("p[itemprop='description']")
89
89
  tags = secici.select_texts("a[href*='film-tur/']")
@@ -93,13 +93,13 @@ class FilmModu(PluginBase):
93
93
 
94
94
  return MovieInfo(
95
95
  url = url,
96
- poster = self.fix_url(poster) if poster else None,
96
+ poster = self.fix_url(poster),
97
97
  title = title,
98
98
  description = description,
99
99
  tags = tags,
100
100
  rating = rating,
101
- year = str(year) if year else None,
102
- actors = actors,
101
+ year = year,
102
+ actors = actors
103
103
  )
104
104
 
105
105
  async def load_links(self, url: str) -> list[ExtractResult]:
@@ -111,7 +111,6 @@ class FilmModu(PluginBase):
111
111
  return []
112
112
 
113
113
  results = []
114
-
115
114
  for alternatif in alternates:
116
115
  alt_link = alternatif.attrs.get("href")
117
116
  alt_name = alternatif.text(strip=True)
@@ -119,20 +118,18 @@ class FilmModu(PluginBase):
119
118
  if alt_name == "Fragman" or not alt_link:
120
119
  continue
121
120
 
122
- alt_link = self.fix_url(alt_link)
121
+ alt_link = self.fix_url(alt_link)
123
122
  alt_istek = await self.httpx.get(alt_link)
124
- alt_text = alt_istek.text
123
+ secici = HTMLHelper(alt_istek.text)
125
124
 
126
- vid_id = HTMLHelper(alt_text).regex_first(r"var videoId = '([^']*)'")
127
- vid_type = HTMLHelper(alt_text).regex_first(r"var videoType = '([^']*)'")
125
+ vid_id = secici.regex_first(r"var videoId = '([^']*)'")
126
+ vid_type = secici.regex_first(r"var videoType = '([^']*)'")
128
127
 
129
128
  if not vid_id or not vid_type:
130
129
  continue
131
130
 
132
- source_istek = await self.httpx.get(
133
- f"{self.main_url}/get-source?movie_id={vid_id}&type={vid_type}"
134
- )
135
- source_data = source_istek.json()
131
+ source_istek = await self.httpx.get(f"{self.main_url}/get-source?movie_id={vid_id}&type={vid_type}")
132
+ source_data = source_istek.json()
136
133
 
137
134
  if source_data.get("subtitle"):
138
135
  subtitle_url = self.fix_url(source_data["subtitle"])