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,9 +1,8 @@
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
4
- import re
5
- from json import loads
6
- from urllib.parse import unquote
3
+ from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, ExtractResult, HTMLHelper
4
+ from urllib.parse import unquote
5
+ from contextlib import suppress
7
6
 
8
7
  class Filmatek(PluginBase):
9
8
  name = "Filmatek"
@@ -12,7 +11,6 @@ class Filmatek(PluginBase):
12
11
  favicon = f"https://www.google.com/s2/favicons?domain={main_url}&sz=64"
13
12
  description = "Sosyalizmin Sineması Veritabanı"
14
13
 
15
- # Main page categories
16
14
  main_page = {
17
15
  f"{main_url}/tur/aile/page" : "Aile",
18
16
  f"{main_url}/tur/aksiyon/page" : "Aksiyon",
@@ -28,22 +26,18 @@ class Filmatek(PluginBase):
28
26
  }
29
27
 
30
28
  async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
31
- target_url = f"{url}/{page}/"
32
- istek = await self.httpx.get(target_url)
33
- helper = HTMLHelper(istek.text)
29
+ istek = await self.httpx.get(f"{url}/{page}/")
30
+ secici = HTMLHelper(istek.text)
34
31
 
35
- items = helper.select("div.items article, #archive-content article")
36
32
  results = []
33
+ for item in secici.select("div.items article, #archive-content article"):
34
+ title_el = secici.select_first("div.data h3 a, h3 a", item)
35
+ if not title_el:
36
+ continue
37
37
 
38
- for item in items:
39
- title_el = helper.select_first("div.data h3 a, h3 a", item)
40
- if not title_el: continue
41
-
42
- title = title_el.text(strip=True)
43
- href = self.fix_url(title_el.attrs.get("href"))
44
-
45
- img_el = helper.select_first("img", item)
46
- poster = self.fix_url(img_el.attrs.get("data-src") or img_el.attrs.get("src")) if img_el else None
38
+ title = title_el.text(strip=True)
39
+ href = self.fix_url(title_el.attrs.get("href"))
40
+ poster = self.fix_url(secici.select_poster("img", item))
47
41
 
48
42
  results.append(MainPageResult(
49
43
  category = category,
@@ -51,26 +45,22 @@ class Filmatek(PluginBase):
51
45
  url = href,
52
46
  poster = poster
53
47
  ))
54
-
48
+
55
49
  return results
56
50
 
57
51
  async def search(self, query: str) -> list[SearchResult]:
58
- url = f"{self.main_url}/?s={query}"
59
- istek = await self.httpx.get(url)
60
- helper = HTMLHelper(istek.text)
52
+ istek = await self.httpx.get(f"{self.main_url}/?s={query}")
53
+ secici = HTMLHelper(istek.text)
61
54
 
62
- items = helper.select("div.result-item")
63
55
  results = []
56
+ for item in secici.select("div.result-item"):
57
+ title_el = secici.select_first("div.title a", item)
58
+ if not title_el:
59
+ continue
64
60
 
65
- for item in items:
66
- title_el = helper.select_first("div.title a", item)
67
- if not title_el: continue
68
-
69
- title = title_el.text(strip=True)
70
- href = self.fix_url(title_el.attrs.get("href"))
71
-
72
- img_el = helper.select_first("div.image img", item)
73
- poster = self.fix_url(img_el.attrs.get("src")) if img_el else None
61
+ title = title_el.text(strip=True)
62
+ href = self.fix_url(title_el.attrs.get("href"))
63
+ poster = self.fix_url(secici.select_poster("div.image img", item))
74
64
 
75
65
  results.append(SearchResult(
76
66
  title = title,
@@ -82,96 +72,111 @@ class Filmatek(PluginBase):
82
72
 
83
73
  async def load_item(self, url: str) -> MovieInfo:
84
74
  istek = await self.httpx.get(url)
85
- helper = HTMLHelper(istek.text)
75
+ secici = HTMLHelper(istek.text)
86
76
 
87
- title = self.clean_title(helper.select_text("div.data h1, h1"))
88
- poster = helper.select_poster("div.poster img") or helper.select_attr("meta[property='og:image']", "content")
89
- description = helper.select_text("div.wp-content p") or helper.select_attr("meta[property='og:description']", "content")
90
- year = helper.extract_year("span.date")
91
- rating = helper.select_text("span.dt_rating_vgs") or helper.select_text("span.dt_rating_vmanual")
92
- duration = helper.regex_first(r"(\d+)", helper.select_text("span.runtime"))
93
- tags = helper.select_texts("div.sgeneros a")
94
- actors = helper.select_texts("div.person div.name a")
77
+ title = self.clean_title(secici.select_text("div.data h1, h1"))
78
+ poster = secici.select_poster("div.poster img") or secici.select_attr("meta[property='og:image']", "content")
79
+ description = secici.select_text("div.wp-content p") or secici.select_attr("meta[property='og:description']", "content")
80
+ year = secici.extract_year("span.date")
81
+ rating = secici.select_text("span.dt_rating_vgs") or secici.select_text("span.dt_rating_vmanual")
82
+ duration = secici.regex_first(r"(\d+)", secici.select_text("span.runtime"))
83
+ tags = secici.select_texts("div.sgeneros a")
84
+ actors = secici.select_texts("div.person div.name a")
95
85
 
96
86
  return MovieInfo(
97
87
  url = url,
98
- title = title or "Bilinmiyor",
88
+ title = title,
99
89
  description = description,
100
- poster = self.fix_url(poster) if poster else None,
101
- year = str(year) if year else None,
90
+ poster = self.fix_url(poster),
91
+ year = year,
102
92
  rating = rating,
103
- duration = int(duration) if duration else None,
93
+ duration = duration,
104
94
  tags = tags,
105
95
  actors = actors
106
96
  )
107
97
 
108
98
  async def load_links(self, url: str) -> list[ExtractResult]:
109
- istek = await self.httpx.get(url)
110
- html = istek.text
111
- helper = HTMLHelper(html)
112
-
113
- # Get Post ID from body class usually "postid-123"
114
- body_class = helper.select_attr("body", "class") or ""
115
- post_id_match = re.search(r"postid-(\d+)", body_class)
116
-
99
+ istek = await self.httpx.get(url)
100
+ secici = HTMLHelper(istek.text)
101
+
102
+ # Player seçeneklerini bul
103
+ options = secici.select("div#playeroptions ul.ajax_mode li.dooplay_player_option")
104
+ if not options:
105
+ # Fallback: Body class'tan post_id
106
+ body_class = secici.select_attr("body", "class") or ""
107
+ if pid := secici.regex_first(r"postid-(\d+)", body_class):
108
+ options = [{"data-post": pid, "data-nume": "1", "data-type": "movie", "title": "Varsayılan"}]
109
+ else:
110
+ options = []
111
+
117
112
  results = []
118
-
119
- if post_id_match:
120
- post_id = post_id_match.group(1)
121
-
122
- # AJAX request for player
123
- ajax_url = f"{self.main_url}/wp-admin/admin-ajax.php"
124
- data = {
125
- "action": "doo_player_ajax",
126
- "post": post_id,
127
- "nume": "1", # Usually implies source number 1? Kotlin uses "1" hardcoded.
128
- "type": "movie"
129
- }
130
-
131
- headers = {
132
- "X-Requested-With": "XMLHttpRequest",
133
- "Referer": url,
134
- "Content-Type": "application/x-www-form-urlencoded"
135
- }
136
-
113
+ for opt in options:
114
+ if isinstance(opt, dict):
115
+ post_id = opt.get("data-post")
116
+ nume = opt.get("data-nume")
117
+ type_ = opt.get("data-type")
118
+ title = opt.get("title")
119
+ else:
120
+ post_id = opt.attrs.get("data-post")
121
+ nume = opt.attrs.get("data-nume")
122
+ type_ = opt.attrs.get("data-type")
123
+ title = secici.select_text("span.title", opt)
124
+
125
+ if not post_id or not nume:
126
+ continue
127
+
137
128
  try:
138
129
  # Need to use post with data
139
- player_resp = await self.httpx.post(ajax_url, data=data, headers=headers)
140
-
141
- # Kotlin parses it as text and cleans slashes
142
- content = player_resp.text.replace(r"\/", "/")
143
-
144
- # Regex for URL
145
- # Kotlin: (?:src|url)["']?\s*[:=]\s*["']([^"']+)["']
146
- src_match = re.search(r'(?:src|url)["\']?\s*[:=]\s*["\']([^"\']+)["\']', content)
147
-
148
- if src_match:
149
- iframe_url = src_match.group(1)
130
+ player_resp = await self.httpx.post(
131
+ url = f"{self.main_url}/wp-admin/admin-ajax.php",
132
+ headers = {
133
+ "X-Requested-With" : "XMLHttpRequest",
134
+ "Referer" : url,
135
+ "Content-Type" : "application/x-www-form-urlencoded"
136
+ },
137
+ data = {
138
+ "action" : "doo_player_ajax",
139
+ "post" : post_id,
140
+ "nume" : nume,
141
+ "type" : type_
142
+ }
143
+ )
144
+
145
+ content = player_resp.text.replace(r"\/", "/")
146
+ iframe_url = secici.regex_first(r'(?:src|url)["\']?\s*[:=]\s*["\']([^"\']+)["\']', content)
147
+
148
+ if iframe_url:
150
149
  if iframe_url.startswith("/"):
151
150
  iframe_url = self.main_url + iframe_url
152
-
151
+
153
152
  iframe_url = self.fix_url(iframe_url)
154
-
153
+
155
154
  # Unwrap internal JWPlayer
156
155
  if "jwplayer/?source=" in iframe_url:
157
- try:
156
+ with suppress(Exception):
158
157
  raw_source = iframe_url.split("source=")[1].split("&")[0]
159
158
  iframe_url = unquote(raw_source)
160
- except:
161
- pass
162
-
163
- extracted = await self.extract(iframe_url)
164
- if extracted:
165
- if isinstance(extracted, list):
166
- results.extend(extracted)
167
- else:
168
- results.append(extracted)
169
- else:
159
+
160
+ # Direct media files
161
+ if ".m3u8" in iframe_url or ".mp4" in iframe_url:
170
162
  results.append(ExtractResult(
171
- name = "Filmatek | External",
172
- url = iframe_url,
163
+ name = f"{title} | Direct",
164
+ url = iframe_url,
173
165
  referer = url
174
166
  ))
167
+ else:
168
+ extracted = await self.extract(iframe_url, prefix=title)
169
+ if extracted:
170
+ if isinstance(extracted, list):
171
+ results.extend(extracted)
172
+ else:
173
+ results.append(extracted)
174
+ else:
175
+ results.append(ExtractResult(
176
+ name = f"{title} | External",
177
+ url = iframe_url,
178
+ referer = url
179
+ ))
175
180
  except Exception as e:
176
181
  # print(f"Filmatek Error: {e}")
177
182
  pass
@@ -1,10 +1,9 @@
1
1
  # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
2
 
3
3
  from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, SeriesInfo, Episode, ExtractResult, HTMLHelper
4
- import re
5
4
 
6
- class Full4kizle(PluginBase):
7
- name = "Full4kizle"
5
+ class FilmciBaba(PluginBase):
6
+ name = "FilmciBaba"
8
7
  language = "tr"
9
8
  main_url = "https://izlehdfilm.cc"
10
9
  favicon = f"https://www.google.com/s2/favicons?domain={main_url}&sz=64"
@@ -35,128 +34,110 @@ class Full4kizle(PluginBase):
35
34
  f"{main_url}/Kategori/tur/18-erotik-filmler/page" : "+18 Erotik Filmler",
36
35
  }
37
36
 
38
-
39
37
  async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
40
- target_url = f"{url}/{page}/"
41
- istek = await self.httpx.get(target_url)
42
- helper = HTMLHelper(istek.text)
43
-
44
- items = helper.select("div.movie-preview")
45
- results = []
46
-
47
- for item in items:
48
- title_el = helper.select_first(".movie-title a", item)
49
- if not title_el: continue
50
-
51
- title = title_el.text(strip=True)
52
- # Remove " izle" case insensitive
53
- title = re.sub(r"(?i) izle", "", title).strip()
54
-
55
- href = self.fix_url(title_el.attrs.get("href"))
56
-
57
- poster_el = helper.select_first(".movie-poster img", item)
58
- poster = self.fix_url(poster_el.attrs.get("src")) if poster_el else None
59
-
38
+ istek = await self.httpx.get(f"{url}/{page}/")
39
+ secici = HTMLHelper(istek.text)
40
+
41
+ results = []
42
+ for item in secici.select("div.movie-preview"):
43
+ title_el = secici.select_first(".movie-title a", item)
44
+ if not title_el:
45
+ continue
46
+
47
+ title = self.clean_title(title_el.text(strip=True))
48
+ href = self.fix_url(title_el.attrs.get("href"))
49
+ poster = self.fix_url(secici.select_poster(".movie-poster img", item))
50
+
60
51
  results.append(MainPageResult(
61
52
  category = category,
62
53
  title = title,
63
54
  url = href,
64
55
  poster = poster
65
56
  ))
66
-
57
+
67
58
  return results
68
59
 
69
60
  async def search(self, query: str) -> list[SearchResult]:
70
- url = f"{self.main_url}/?s={query}"
71
- istek = await self.httpx.get(url)
72
- helper = HTMLHelper(istek.text)
73
-
74
- items = helper.select("div.movie-preview")
61
+ istek = await self.httpx.get(f"{self.main_url}/?s={query}")
62
+ secici = HTMLHelper(istek.text)
63
+
75
64
  results = []
76
-
77
- for item in items:
78
- title_el = helper.select_first(".movie-title a", item)
79
- if not title_el: continue
80
-
81
- title = title_el.text(strip=True)
82
- # Remove " izle" case insensitive
83
- title = re.sub(r"(?i) izle", "", title).strip()
84
-
85
- href = self.fix_url(title_el.attrs.get("href"))
86
-
87
- poster_el = helper.select_first(".movie-poster img", item)
88
- poster = self.fix_url(poster_el.attrs.get("src")) if poster_el else None
89
-
65
+ for item in secici.select("div.movie-preview"):
66
+ title_el = secici.select_first(".movie-title a", item)
67
+ if not title_el:
68
+ continue
69
+
70
+ title = self.clean_title(title_el.text(strip=True))
71
+ href = self.fix_url(title_el.attrs.get("href"))
72
+ poster = self.fix_url(secici.select_poster(".movie-poster img", item))
73
+
90
74
  results.append(SearchResult(
91
75
  title = title,
92
76
  url = href,
93
77
  poster = poster
94
78
  ))
95
-
79
+
96
80
  return results
97
81
 
98
82
  async def load_item(self, url: str) -> MovieInfo | SeriesInfo:
99
- istek = await self.httpx.get(url)
100
- helper = HTMLHelper(istek.text)
101
-
102
- title = self.clean_title(helper.select_text("h1"))
103
- poster = helper.select_poster(".poster img")
104
- description = helper.select_text(".excerpt p")
105
- year = helper.extract_year(".release", ".movie-info")
106
- rating = helper.regex_first(r"([\d\.]+)", helper.select_text(".imdb-rating"))
107
- duration = int(helper.regex_first(r"(\d+)", helper.select_text(".movie-info")) or 0)
108
- tags = helper.select_texts("a[href*='/tur/'], a[href*='/Kategori/tur/']")
109
- actors = helper.select_texts("a[href*='/oyuncular/']") or helper.select_texts(".cast-list .actor-name, .cast-list a")
83
+ istek = await self.httpx.get(url)
84
+ secici = HTMLHelper(istek.text)
85
+
86
+ title = self.clean_title(secici.select_text("h1"))
87
+ poster = secici.select_poster(".poster img")
88
+ description = secici.select_text(".excerpt p")
89
+ year = secici.extract_year(".release", ".movie-info")
90
+ rating = secici.regex_first(r"([\d\.]+)", secici.select_text(".imdb-rating"))
91
+ tags = secici.select_texts("div.categories a[href*='/Kategori/tur/']")
92
+ actors = secici.select_texts("a[href*='/oyuncular/']") or secici.select_texts(".cast-list .actor-name, .cast-list a")
110
93
 
111
94
  # Bölüm linklerini kontrol et
112
- ep_elements = helper.select(".parts-middle a, .parts-middle .part.active")
95
+ ep_elements = secici.select(".parts-middle a, .parts-middle .part.active")
113
96
 
114
97
  if not ep_elements:
115
98
  return MovieInfo(
116
99
  url = url,
117
- title = title or "Bilinmiyor",
100
+ title = title,
118
101
  description = description,
119
- poster = self.fix_url(poster) if poster else None,
120
- year = str(year) if year else None,
121
- rating = rating,
122
- duration = duration,
102
+ poster = self.fix_url(poster),
103
+ year = year,
104
+ rating = rating if rating != "." else None,
123
105
  tags = tags,
124
106
  actors = actors
125
107
  )
126
-
108
+
127
109
  episodes = []
128
110
  for i, el in enumerate(ep_elements):
129
- name = helper.select_text(".part-name", el) or f"Bölüm {i+1}"
111
+ name = secici.select_text(".part-name", el) or f"Bölüm {i+1}"
130
112
  href = el.attrs.get("href") or url
131
- s, e = helper.extract_season_episode(name)
113
+ s, e = secici.extract_season_episode(name)
132
114
  episodes.append(Episode(season=s or 1, episode=e or (i + 1), title=name, url=self.fix_url(href)))
133
115
 
134
116
  return SeriesInfo(
135
117
  url = url,
136
- title = title or "Bilinmiyor",
118
+ title = title,
137
119
  description = description,
138
- poster = self.fix_url(poster) if poster else None,
139
- year = str(year) if year else None,
120
+ poster = self.fix_url(poster),
121
+ year = year,
140
122
  rating = rating,
141
- duration = duration,
142
123
  tags = tags,
143
124
  actors = actors,
144
125
  episodes = episodes
145
126
  )
146
127
 
147
128
  async def load_links(self, url: str) -> list[ExtractResult]:
148
- istek = await self.httpx.get(url)
149
- helper = HTMLHelper(istek.text)
150
-
151
- iframe = helper.select_attr(".center-container iframe", "src")
129
+ istek = await self.httpx.get(url)
130
+ secici = HTMLHelper(istek.text)
131
+
132
+ iframe = secici.select_attr(".center-container iframe", "src")
152
133
  if not iframe:
153
- iframe = helper.select_attr("iframe[src*='hotstream.club']", "src")
154
-
134
+ iframe = secici.select_attr("iframe[src*='hotstream.club']", "src")
135
+
155
136
  results = []
156
-
137
+
157
138
  if iframe:
158
139
  iframe = self.fix_url(iframe)
159
-
140
+
160
141
  # Use general extract method
161
142
  extracted = await self.extract(iframe)
162
143
  if extracted:
@@ -166,9 +147,9 @@ class Full4kizle(PluginBase):
166
147
  results.append(extracted)
167
148
  else:
168
149
  results.append(ExtractResult(
169
- name = "Full4kizle | External",
170
- url = iframe,
150
+ name = "FilmciBaba | External",
151
+ url = iframe,
171
152
  referer = url
172
153
  ))
173
-
154
+
174
155
  return results
@@ -54,7 +54,7 @@ class FullHDFilmizlesene(PluginBase):
54
54
  category = category,
55
55
  title = title,
56
56
  url = self.fix_url(href),
57
- poster = self.fix_url(poster) if poster else None,
57
+ poster = self.fix_url(poster),
58
58
  ))
59
59
 
60
60
  return results
@@ -65,15 +65,15 @@ class FullHDFilmizlesene(PluginBase):
65
65
 
66
66
  results = []
67
67
  for film in secici.select("li.film"):
68
- title = secici.select_text("span.film-title", film)
69
- href = secici.select_attr("a", "href", film)
68
+ title = secici.select_text("span.film-title", film)
69
+ href = secici.select_attr("a", "href", film)
70
70
  poster = secici.select_attr("img", "data-src", film)
71
71
 
72
72
  if title and href:
73
73
  results.append(SearchResult(
74
74
  title = title,
75
75
  url = self.fix_url(href),
76
- poster = self.fix_url(poster) if poster else None,
76
+ poster = self.fix_url(poster),
77
77
  ))
78
78
 
79
79
  return results
@@ -84,21 +84,21 @@ class FullHDFilmizlesene(PluginBase):
84
84
 
85
85
  title = self.clean_title(secici.select_text("div.izle-titles"))
86
86
  poster = secici.select_poster("div img[data-src]")
87
- description = secici.select_text("div.ozet-ic p")
87
+ description = secici.select_text("div.ozet-ic")
88
88
  tags = secici.select_texts("a[rel='category tag']")
89
89
  rating = secici.regex_first(r"(\d+\.\d+|\d+)", secici.select_text("div.puanx-puan"))
90
90
  year = secici.extract_year("div.dd a.category")
91
91
  actors = secici.select_texts("a > span", secici.select_first("div.film-info ul li:nth-child(2)"))
92
- duration = int(secici.regex_first(r"(\d+)", secici.select_text("div.film-info ul li:nth-child(4)")) or 0)
92
+ duration = secici.regex_first(r"Süre: (\d+)\s*dk", secici.select_text("div.ozet-ic"))
93
93
 
94
94
  return MovieInfo(
95
95
  url = url,
96
- poster = self.fix_url(poster) if poster else None,
97
- title = title or "Bilinmiyor",
96
+ poster = self.fix_url(poster),
97
+ title = title,
98
98
  description = description,
99
99
  tags = tags,
100
100
  rating = rating,
101
- year = str(year) if year else None,
101
+ year = year,
102
102
  actors = actors,
103
103
  duration = duration
104
104
  )
@@ -106,10 +106,9 @@ class FullHDFilmizlesene(PluginBase):
106
106
  async def load_links(self, url: str) -> list[ExtractResult]:
107
107
  istek = await self.httpx.get(url)
108
108
  secici = HTMLHelper(istek.text)
109
- html_text = istek.text
110
109
 
111
110
  # İlk script'i al (xpath (//script)[1] yerine)
112
- scripts = secici.select("script")
111
+ scripts = secici.select("script")
113
112
  script_content = scripts[0].text() if scripts else ""
114
113
 
115
114
  scx_json = HTMLHelper(script_content).regex_first(r"scx = (.*?);")
@@ -129,9 +128,8 @@ class FullHDFilmizlesene(PluginBase):
129
128
 
130
129
  response = []
131
130
  for link in link_list:
132
- link = f"https:{link}" if link.startswith("//") else link
133
- data = await self.extract(link)
131
+ data = await self.extract(self.fix_url(link))
134
132
  if data:
135
133
  response.append(data)
136
134
 
137
- return response
135
+ return response