KekikStream 2.4.2__py3-none-any.whl → 2.4.4__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.
- KekikStream/Core/Extractor/ExtractorBase.py +3 -2
- KekikStream/Core/HTMLHelper.py +134 -40
- KekikStream/Core/Plugin/PluginBase.py +3 -2
- KekikStream/Extractors/CloseLoad.py +30 -54
- KekikStream/Extractors/ContentX.py +27 -72
- KekikStream/Extractors/DonilasPlay.py +33 -77
- KekikStream/Extractors/DzenRu.py +10 -24
- KekikStream/Extractors/ExPlay.py +20 -38
- KekikStream/Extractors/Filemoon.py +19 -45
- KekikStream/Extractors/HDMomPlayer.py +24 -56
- KekikStream/Extractors/HDPlayerSystem.py +13 -31
- KekikStream/Extractors/HotStream.py +14 -32
- KekikStream/Extractors/JFVid.py +3 -24
- KekikStream/Extractors/JetTv.py +21 -34
- KekikStream/Extractors/MailRu.py +11 -29
- KekikStream/Extractors/MixPlayHD.py +15 -28
- KekikStream/Extractors/MixTiger.py +17 -40
- KekikStream/Extractors/MolyStream.py +17 -21
- KekikStream/Extractors/Odnoklassniki.py +28 -104
- KekikStream/Extractors/PeaceMakerst.py +18 -45
- KekikStream/Extractors/PixelDrain.py +8 -16
- KekikStream/Extractors/PlayerFilmIzle.py +22 -41
- KekikStream/Extractors/RapidVid.py +21 -35
- KekikStream/Extractors/SetPlay.py +18 -43
- KekikStream/Extractors/SibNet.py +7 -17
- KekikStream/Extractors/Sobreatsesuyp.py +23 -45
- KekikStream/Extractors/TRsTX.py +23 -53
- KekikStream/Extractors/TurboImgz.py +7 -14
- KekikStream/Extractors/VCTPlay.py +10 -28
- KekikStream/Extractors/VidHide.py +10 -31
- KekikStream/Extractors/VidMoly.py +65 -99
- KekikStream/Extractors/VidMoxy.py +16 -27
- KekikStream/Extractors/VidPapi.py +24 -54
- KekikStream/Extractors/VideoSeyred.py +19 -40
- KekikStream/Extractors/Videostr.py +42 -99
- KekikStream/Extractors/Vidoza.py +8 -15
- KekikStream/Extractors/YildizKisaFilm.py +13 -31
- KekikStream/Plugins/BelgeselX.py +63 -69
- KekikStream/Plugins/DiziBox.py +16 -36
- KekikStream/Plugins/DiziMom.py +37 -129
- KekikStream/Plugins/DiziPal.py +71 -164
- KekikStream/Plugins/DiziYou.py +44 -152
- KekikStream/Plugins/Dizilla.py +18 -44
- KekikStream/Plugins/FilmBip.py +10 -24
- KekikStream/Plugins/FilmEkseni.py +12 -32
- KekikStream/Plugins/FilmMakinesi.py +24 -77
- KekikStream/Plugins/FilmModu.py +11 -18
- KekikStream/Plugins/Filmatek.py +13 -39
- KekikStream/Plugins/Full4kizle.py +33 -133
- KekikStream/Plugins/FullHDFilm.py +23 -93
- KekikStream/Plugins/FullHDFilmizlesene.py +10 -29
- KekikStream/Plugins/HDFilmCehennemi.py +27 -66
- KekikStream/Plugins/JetFilmizle.py +19 -20
- KekikStream/Plugins/KultFilmler.py +16 -50
- KekikStream/Plugins/RecTV.py +47 -85
- KekikStream/Plugins/SelcukFlix.py +29 -47
- KekikStream/Plugins/SetFilmIzle.py +28 -84
- KekikStream/Plugins/SezonlukDizi.py +27 -59
- KekikStream/Plugins/Sinefy.py +37 -100
- KekikStream/Plugins/SinemaCX.py +12 -18
- KekikStream/Plugins/Sinezy.py +11 -12
- KekikStream/Plugins/SuperFilmGeldi.py +8 -13
- KekikStream/Plugins/UgurFilm.py +14 -14
- KekikStream/Plugins/Watch32.py +42 -74
- KekikStream/Plugins/YabanciDizi.py +33 -87
- {kekikstream-2.4.2.dist-info → kekikstream-2.4.4.dist-info}/METADATA +1 -1
- kekikstream-2.4.4.dist-info/RECORD +93 -0
- kekikstream-2.4.2.dist-info/RECORD +0 -93
- {kekikstream-2.4.2.dist-info → kekikstream-2.4.4.dist-info}/WHEEL +0 -0
- {kekikstream-2.4.2.dist-info → kekikstream-2.4.4.dist-info}/entry_points.txt +0 -0
- {kekikstream-2.4.2.dist-info → kekikstream-2.4.4.dist-info}/licenses/LICENSE +0 -0
- {kekikstream-2.4.2.dist-info → kekikstream-2.4.4.dist-info}/top_level.txt +0 -0
KekikStream/Plugins/DiziBox.py
CHANGED
|
@@ -93,44 +93,24 @@ class DiziBox(PluginBase):
|
|
|
93
93
|
istek = await self.httpx.get(url)
|
|
94
94
|
secici = HTMLHelper(istek.text)
|
|
95
95
|
|
|
96
|
-
title
|
|
97
|
-
|
|
98
|
-
poster = secici.select_attr("div.tv-overview figure img", "src")
|
|
99
|
-
|
|
96
|
+
title = secici.select_text("div.tv-overview h1 a")
|
|
97
|
+
poster = secici.select_poster("div.tv-overview figure img")
|
|
100
98
|
description = secici.select_text("div.tv-story p")
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
tags = secici.select_all_text("a[href*='/tur/']")
|
|
107
|
-
|
|
108
|
-
# rating
|
|
109
|
-
rating_text = secici.select_text("span.label-imdb b")
|
|
110
|
-
rating = secici.regex_first(r"[\d.,]+", rating_text)
|
|
111
|
-
|
|
112
|
-
actors = secici.select_all_text("a[href*='/oyuncu/']")
|
|
99
|
+
year = secici.extract_year("a[href*='/yil/']")
|
|
100
|
+
tags = secici.select_texts("a[href*='/tur/']")
|
|
101
|
+
rating = secici.regex_first(r"[\d.,]+", secici.select_text("span.label-imdb b"))
|
|
102
|
+
actors = secici.select_texts("a[href*='/oyuncu/']")
|
|
113
103
|
|
|
114
104
|
episodes = []
|
|
115
|
-
for
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
ep_season = sezon_secici.regex_first(r"(\d+)\. ?Sezon", ep_title)
|
|
125
|
-
ep_episode = sezon_secici.regex_first(r"(\d+)\. ?Bölüm", ep_title)
|
|
126
|
-
|
|
127
|
-
if ep_title and ep_href:
|
|
128
|
-
episodes.append(Episode(
|
|
129
|
-
season = ep_season,
|
|
130
|
-
episode = ep_episode,
|
|
131
|
-
title = ep_title,
|
|
132
|
-
url = self.fix_url(ep_href),
|
|
133
|
-
))
|
|
105
|
+
for link in secici.select_attrs("div#seasons-list a", "href"):
|
|
106
|
+
r = await self.httpx.get(self.fix_url(link))
|
|
107
|
+
s_secici = HTMLHelper(r.text)
|
|
108
|
+
for bolum in s_secici.select("article.grid-box"):
|
|
109
|
+
name = s_secici.select_text("div.post-title a", bolum)
|
|
110
|
+
href = s_secici.select_attr("div.post-title a", "href", bolum)
|
|
111
|
+
if name and href:
|
|
112
|
+
s, e = s_secici.extract_season_episode(name)
|
|
113
|
+
episodes.append(Episode(season=s, episode=e, title=name, url=self.fix_url(href)))
|
|
134
114
|
|
|
135
115
|
return SeriesInfo(
|
|
136
116
|
url = url,
|
|
@@ -139,7 +119,7 @@ class DiziBox(PluginBase):
|
|
|
139
119
|
description = description,
|
|
140
120
|
tags = tags,
|
|
141
121
|
rating = rating,
|
|
142
|
-
year = year,
|
|
122
|
+
year = str(year) if year else None,
|
|
143
123
|
episodes = episodes,
|
|
144
124
|
actors = actors,
|
|
145
125
|
)
|
KekikStream/Plugins/DiziMom.py
CHANGED
|
@@ -19,34 +19,28 @@ class DiziMom(PluginBase):
|
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
full_url = f"{url}/{page}/"
|
|
23
|
+
istek = await self.httpx.get(full_url)
|
|
24
|
+
helper = HTMLHelper(istek.text)
|
|
24
25
|
|
|
26
|
+
results = []
|
|
27
|
+
# Eğer "tum-bolumler" ise Episode kutularını, değilse Dizi kutularını tara
|
|
25
28
|
if "/tum-bolumler/" in url:
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
if
|
|
31
|
-
|
|
32
|
-
title = name.replace(".Sezon ", "x").replace(".Bölüm", "")
|
|
33
|
-
|
|
34
|
-
ep_href = self.fix_url(name_el.attrs.get("href"))
|
|
35
|
-
pass
|
|
36
|
-
|
|
37
|
-
# Revert to standard categories if "tum-bolumler" is complex
|
|
38
|
-
return []
|
|
29
|
+
for item in helper.select("div.episode-box"):
|
|
30
|
+
title = helper.select_text("div.episode-name a", item)
|
|
31
|
+
href = helper.select_attr("div.episode-name a", "href", item)
|
|
32
|
+
img = helper.select_poster("div.cat-img img", item)
|
|
33
|
+
if title and href:
|
|
34
|
+
results.append(MainPageResult(category=category, title=title.split(" izle")[0], url=self.fix_url(href), poster=self.fix_url(img)))
|
|
39
35
|
else:
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
for item in items
|
|
49
|
-
]
|
|
36
|
+
for item in helper.select("div.single-item"):
|
|
37
|
+
title = helper.select_text("div.categorytitle a", item)
|
|
38
|
+
href = helper.select_attr("div.categorytitle a", "href", item)
|
|
39
|
+
img = helper.select_poster("div.cat-img img", item)
|
|
40
|
+
if title and href:
|
|
41
|
+
results.append(MainPageResult(category=category, title=title.split(" izle")[0], url=self.fix_url(href), poster=self.fix_url(img)))
|
|
42
|
+
|
|
43
|
+
return results
|
|
50
44
|
|
|
51
45
|
async def search(self, query: str) -> list[SearchResult]:
|
|
52
46
|
url = f"{self.main_url}/?s={query}"
|
|
@@ -67,117 +61,31 @@ class DiziMom(PluginBase):
|
|
|
67
61
|
istek = await self.httpx.get(url)
|
|
68
62
|
helper = HTMLHelper(istek.text)
|
|
69
63
|
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
rating = None
|
|
78
|
-
actors = None
|
|
79
|
-
|
|
80
|
-
# Regex approach based on debug output (multiline support)
|
|
81
|
-
# Context: <span class="dizimeta"><i class="fas fa-globe"></i> Yapım Yılı : </span>\n 2022
|
|
82
|
-
year_val_all = helper.regex_all(r"Yapım Yılı\s*:\s*(?:</span>)?\s*(\d{4})", flags=re.DOTALL)
|
|
83
|
-
if year_val_all:
|
|
84
|
-
year = int(year_val_all[0])
|
|
85
|
-
|
|
86
|
-
# Context: <span class="dizimeta"><i class="fas fa-star"></i> IMDB : </span>\n 4.5
|
|
87
|
-
rating_val_all = helper.regex_all(r"IMDB\s*:\s*(?:</span>)?\s*([\d\.]+)", flags=re.DOTALL)
|
|
88
|
-
if rating_val_all:
|
|
89
|
-
rating = rating_val_all[0]
|
|
90
|
-
|
|
91
|
-
actors_val = helper.regex_first(r"Oyuncular\s*:\s*(.+?)(?:</div>|<br|$)")
|
|
92
|
-
if not actors_val:
|
|
93
|
-
# Try selecting the div text directly if regex fails due to HTML tags
|
|
94
|
-
# Find div containing "Oyuncular :"
|
|
95
|
-
all_divs = helper.select("div")
|
|
96
|
-
for div in all_divs:
|
|
97
|
-
txt = div.text()
|
|
98
|
-
if "Oyuncular :" in txt:
|
|
99
|
-
actors_val = txt.split("Oyuncular :")[1].strip()
|
|
100
|
-
break
|
|
101
|
-
|
|
102
|
-
if actors_val:
|
|
103
|
-
# Remove footer / junk from actors
|
|
104
|
-
if "IMDB :" in actors_val:
|
|
105
|
-
actors_val = actors_val.split("IMDB :")[0].strip()
|
|
106
|
-
|
|
107
|
-
if "IMDB :" in actors_val:
|
|
108
|
-
actors_val = actors_val.split("IMDB :")[0].strip()
|
|
109
|
-
|
|
110
|
-
# Remove '×' and other junk if present at end
|
|
111
|
-
if "×" in actors_val:
|
|
112
|
-
actors_val = actors_val.split("×")[0].strip()
|
|
113
|
-
|
|
114
|
-
# Remove simple tags if any remaining
|
|
115
|
-
clean_actors = [a.strip() for a in actors_val.split(",")]
|
|
116
|
-
# Filter empty
|
|
117
|
-
clean_actors = [a for a in clean_actors if a]
|
|
118
|
-
|
|
119
|
-
actors = ", ".join(clean_actors)
|
|
120
|
-
|
|
121
|
-
description_raw = helper.select_text("div.category_desc")
|
|
122
|
-
description = None
|
|
123
|
-
if description_raw:
|
|
124
|
-
# Clean header "The Librarians izle..." etc. if present, usually it is fine.
|
|
125
|
-
# Clean "IMDB :" if attached
|
|
126
|
-
if "IMDB :" in description_raw:
|
|
127
|
-
description_raw = description_raw.split("IMDB :")[0].strip()
|
|
128
|
-
|
|
129
|
-
# Clean footer text start
|
|
130
|
-
# The footer block usually starts with "Dizimom, dizi ve film..."
|
|
131
|
-
if "Dizimom," in description_raw:
|
|
132
|
-
description = description_raw.split("Dizimom,")[0].strip()
|
|
133
|
-
elif "dizi izle film izle" in description_raw:
|
|
134
|
-
description = description_raw.split("dizi izle film izle")[0].strip()
|
|
135
|
-
else:
|
|
136
|
-
description = description_raw
|
|
137
|
-
|
|
138
|
-
# Fallback cleanup for JSON
|
|
139
|
-
if description and "{" in description:
|
|
140
|
-
description = description.split("{")[0].strip()
|
|
141
|
-
|
|
142
|
-
tags = helper.select_all_text("div.genres a")
|
|
143
|
-
|
|
144
|
-
# Improved year regex
|
|
145
|
-
if not year:
|
|
146
|
-
# Look for "Yapım Yılı : 2014" pattern in ANY text
|
|
147
|
-
# Get all text from category_text which usually contains it
|
|
148
|
-
meta_text = helper.select_text("div.category_text")
|
|
149
|
-
if meta_text:
|
|
150
|
-
match = re.search(r"Yapım Yılı\s*:\s*(\d{4})", meta_text)
|
|
151
|
-
if match:
|
|
152
|
-
year = int(match.group(1))
|
|
64
|
+
title = self.clean_title(helper.select_text("div.title h1"))
|
|
65
|
+
poster = helper.select_poster("div.category_image img")
|
|
66
|
+
description = helper.select_direct_text("div.category_desc")
|
|
67
|
+
tags = helper.select_texts("div.genres a")
|
|
68
|
+
rating = helper.regex_first(r"IMDB\s*:\s*(?:</span>)?\s*([\d\.]+)", helper.html, flags=re.DOTALL)
|
|
69
|
+
year = helper.extract_year("div.category_text")
|
|
70
|
+
actors = helper.meta_list("Oyuncular", container_selector="div#icerikcat2")
|
|
153
71
|
|
|
154
72
|
episodes = []
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
if ep_name_raw:
|
|
161
|
-
# 1.Sezon 1.Bölüm
|
|
162
|
-
s_m = re.search(r"(\d+)\.Sezon", ep_name_raw)
|
|
163
|
-
e_m = re.search(r"(\d+)\.Bölüm", ep_name_raw)
|
|
164
|
-
|
|
165
|
-
season = int(s_m.group(1)) if s_m else 1
|
|
166
|
-
episode = int(e_m.group(1)) if e_m else 1
|
|
167
|
-
|
|
168
|
-
name = ep_name_raw.split(" izle")[0].replace(title, "").strip()
|
|
169
|
-
|
|
73
|
+
for item in helper.select("div.bolumust"):
|
|
74
|
+
name = helper.select_text("div.baslik", item)
|
|
75
|
+
href = helper.select_attr("a", "href", item)
|
|
76
|
+
if name and href:
|
|
77
|
+
s, e = helper.extract_season_episode(name)
|
|
170
78
|
episodes.append(Episode(
|
|
171
|
-
season =
|
|
172
|
-
episode =
|
|
173
|
-
title = name,
|
|
174
|
-
url =
|
|
79
|
+
season = s or 1,
|
|
80
|
+
episode = e or 1,
|
|
81
|
+
title = self.clean_title(name.replace(title or "", "").strip()),
|
|
82
|
+
url = self.fix_url(href)
|
|
175
83
|
))
|
|
176
84
|
|
|
177
85
|
return SeriesInfo(
|
|
178
86
|
url = url,
|
|
179
|
-
poster = poster,
|
|
180
|
-
title = title,
|
|
87
|
+
poster = self.fix_url(poster) if poster else None,
|
|
88
|
+
title = title or "Bilinmiyor",
|
|
181
89
|
description = description,
|
|
182
90
|
tags = tags,
|
|
183
91
|
rating = rating,
|
KekikStream/Plugins/DiziPal.py
CHANGED
|
@@ -5,205 +5,114 @@ from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInf
|
|
|
5
5
|
class DiziPal(PluginBase):
|
|
6
6
|
name = "DiziPal"
|
|
7
7
|
language = "tr"
|
|
8
|
-
main_url = "https://
|
|
8
|
+
main_url = "https://dizipal.cc"
|
|
9
9
|
favicon = f"https://www.google.com/s2/favicons?domain={main_url}&sz=64"
|
|
10
10
|
description = "dizipal güncel, dizipal yeni ve gerçek adresi. dizipal en yeni dizi ve filmleri güvenli ve hızlı şekilde sunar."
|
|
11
11
|
|
|
12
12
|
main_page = {
|
|
13
|
-
f"{main_url}/
|
|
14
|
-
f"{main_url}/
|
|
15
|
-
f"{main_url}/
|
|
16
|
-
f"{main_url}/
|
|
17
|
-
f"{main_url}/
|
|
18
|
-
f"{main_url}/
|
|
19
|
-
f"{main_url}/
|
|
20
|
-
f"{main_url}/
|
|
21
|
-
f"{main_url}/
|
|
22
|
-
f"{main_url}/
|
|
23
|
-
f"{main_url}/
|
|
13
|
+
f"{main_url}/kategori/aile/page/" : "Aile",
|
|
14
|
+
f"{main_url}/kategori/aksiyon/page/" : "Aksiyon",
|
|
15
|
+
f"{main_url}/kategori/animasyon/page/" : "Animasyon",
|
|
16
|
+
f"{main_url}/kategori/belgesel/page/" : "Belgesel",
|
|
17
|
+
f"{main_url}/kategori/bilim-kurgu/page/" : "Bilim Kurgu",
|
|
18
|
+
f"{main_url}/kategori/dram/page/" : "Dram",
|
|
19
|
+
f"{main_url}/kategori/fantastik/page/" : "Fantastik",
|
|
20
|
+
f"{main_url}/kategori/gerilim/page/" : "Gerilim",
|
|
21
|
+
f"{main_url}/kategori/gizem/page/" : "Gizem",
|
|
22
|
+
f"{main_url}/kategori/komedi/page/" : "Komedi",
|
|
23
|
+
f"{main_url}/kategori/korku/page/" : "Korku",
|
|
24
|
+
f"{main_url}/kategori/macera/page/" : "Macera",
|
|
25
|
+
f"{main_url}/kategori/muzik/page/" : "Müzik",
|
|
26
|
+
f"{main_url}/kategori/romantik/page/" : "Romantik",
|
|
27
|
+
f"{main_url}/kategori/savas/page/" : "Savaş",
|
|
28
|
+
f"{main_url}/kategori/suc/page/" : "Suç",
|
|
29
|
+
f"{main_url}/kategori/tarih/page/" : "Tarih",
|
|
30
|
+
f"{main_url}/kategori/vahsi-bati/page/" : "Vahşi Batı",
|
|
31
|
+
f"{main_url}/kategori/yerli/page/" : "Yerli",
|
|
24
32
|
}
|
|
25
33
|
|
|
26
34
|
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
27
|
-
istek = await self.httpx.get(url)
|
|
35
|
+
istek = await self.httpx.get(f"{url}{page}/")
|
|
28
36
|
secici = HTMLHelper(istek.text)
|
|
29
37
|
|
|
30
38
|
results = []
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
dizi_url = href.split("/sezon")[0] if "/sezon" in href else href
|
|
44
|
-
|
|
45
|
-
results.append(MainPageResult(
|
|
46
|
-
category = category,
|
|
47
|
-
title = title,
|
|
48
|
-
url = self.fix_url(dizi_url),
|
|
49
|
-
poster = self.fix_url(poster) if poster else None,
|
|
50
|
-
))
|
|
51
|
-
else:
|
|
52
|
-
for veri in secici.select("article.type2 ul li"):
|
|
53
|
-
title = secici.select_text("span.title", veri)
|
|
54
|
-
href = secici.select_attr("a", "href", veri)
|
|
55
|
-
poster = secici.select_attr("img", "src", veri)
|
|
56
|
-
|
|
57
|
-
if title and href:
|
|
58
|
-
results.append(MainPageResult(
|
|
59
|
-
category = category,
|
|
60
|
-
title = title,
|
|
61
|
-
url = self.fix_url(href),
|
|
62
|
-
poster = self.fix_url(poster) if poster else None,
|
|
63
|
-
))
|
|
39
|
+
for veri in secici.select("div.grid div.post-item"):
|
|
40
|
+
title = secici.select_attr("a", "title", veri)
|
|
41
|
+
href = secici.select_attr("a", "href", veri)
|
|
42
|
+
poster = secici.select_poster("div.poster img", veri)
|
|
43
|
+
|
|
44
|
+
if title and href:
|
|
45
|
+
results.append(MainPageResult(
|
|
46
|
+
category = category,
|
|
47
|
+
title = title,
|
|
48
|
+
url = self.fix_url(href),
|
|
49
|
+
poster = self.fix_url(poster) if poster else None,
|
|
50
|
+
))
|
|
64
51
|
|
|
65
52
|
return results
|
|
66
53
|
|
|
67
54
|
async def search(self, query: str) -> list[SearchResult]:
|
|
68
|
-
self.httpx.
|
|
69
|
-
|
|
70
|
-
"X-Requested-With" : "XMLHttpRequest"
|
|
71
|
-
})
|
|
72
|
-
|
|
73
|
-
istek = await self.httpx.post(
|
|
74
|
-
url = f"{self.main_url}/api/search-autocomplete",
|
|
75
|
-
data = {"query": query}
|
|
76
|
-
)
|
|
77
|
-
|
|
78
|
-
try:
|
|
79
|
-
data = istek.json()
|
|
80
|
-
except Exception:
|
|
81
|
-
return []
|
|
55
|
+
istek = await self.httpx.get(f"{self.main_url}/?s={query}")
|
|
56
|
+
secici = HTMLHelper(istek.text)
|
|
82
57
|
|
|
83
58
|
results = []
|
|
59
|
+
for veri in secici.select("div.grid div.post-item"):
|
|
60
|
+
title = secici.select_attr("a", "title", veri)
|
|
61
|
+
href = secici.select_attr("a", "href", veri)
|
|
62
|
+
poster = secici.select_poster("div.poster img", veri)
|
|
84
63
|
|
|
85
|
-
|
|
86
|
-
items = data.values() if isinstance(data, dict) else data
|
|
87
|
-
|
|
88
|
-
for item in items:
|
|
89
|
-
if not isinstance(item, dict):
|
|
90
|
-
continue
|
|
91
|
-
|
|
92
|
-
title = item.get("title")
|
|
93
|
-
url = item.get("url")
|
|
94
|
-
poster = item.get("poster")
|
|
95
|
-
|
|
96
|
-
if title and url:
|
|
64
|
+
if title and href:
|
|
97
65
|
results.append(SearchResult(
|
|
98
66
|
title = title,
|
|
99
|
-
url =
|
|
67
|
+
url = self.fix_url(href),
|
|
100
68
|
poster = self.fix_url(poster) if poster else None,
|
|
101
69
|
))
|
|
102
70
|
|
|
103
71
|
return results
|
|
104
72
|
|
|
105
|
-
def _find_sibling_text(self, secici: HTMLHelper, label_text: str) -> str | None:
|
|
106
|
-
"""Bir label'ın kardeş div'inden text çıkarır (xpath yerine)"""
|
|
107
|
-
for div in secici.select("div"):
|
|
108
|
-
if secici.select_text(element=div) == label_text:
|
|
109
|
-
# Sonraki kardeş elementi bul
|
|
110
|
-
next_sibling = div.next
|
|
111
|
-
while next_sibling:
|
|
112
|
-
if hasattr(next_sibling, 'text') and next_sibling.text(strip=True):
|
|
113
|
-
return next_sibling.text(strip=True)
|
|
114
|
-
next_sibling = next_sibling.next if hasattr(next_sibling, 'next') else None
|
|
115
|
-
return None
|
|
116
|
-
|
|
117
73
|
async def load_item(self, url: str) -> MovieInfo | SeriesInfo:
|
|
118
|
-
# Reset headers to get HTML response
|
|
119
|
-
self.httpx.headers.update({
|
|
120
|
-
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
|
|
121
|
-
})
|
|
122
|
-
self.httpx.headers.pop("X-Requested-With", None)
|
|
123
|
-
|
|
124
74
|
istek = await self.httpx.get(url)
|
|
125
75
|
secici = HTMLHelper(istek.text)
|
|
126
|
-
html_text = istek.text
|
|
127
76
|
|
|
128
|
-
poster
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
info = {}
|
|
132
|
-
for li in secici.select("li"):
|
|
133
|
-
key = secici.select_text("div.key", li)
|
|
134
|
-
val = secici.select_text("div.value", li)
|
|
135
|
-
if key and val:
|
|
136
|
-
info[key.strip(":")] = val.strip()
|
|
137
|
-
|
|
138
|
-
year = info.get("Yapım Yılı")
|
|
139
|
-
rating = info.get("IMDB Puanı")
|
|
77
|
+
poster = self.fix_url(secici.select_attr("meta[property='og:image']", "content"))
|
|
78
|
+
description = secici.select_attr("meta[property='og:description']", "content")
|
|
79
|
+
title = secici.select_text("h1")
|
|
140
80
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
duration = int(secici.regex_first(r"(\d+)", duration_raw)) if duration_raw else None
|
|
81
|
+
year = secici.meta_value("Yapım Yılı")
|
|
82
|
+
rating = secici.meta_value("IMDB Puanı")
|
|
83
|
+
duration = secici.meta_value("Süre")
|
|
84
|
+
duration = int(secici.regex_first(r"(\d+)", duration)) if duration else None
|
|
85
|
+
tags = secici.meta_list("Tür")
|
|
86
|
+
|
|
87
|
+
actors = secici.meta_list("Oyuncular")
|
|
88
|
+
if not actors:
|
|
89
|
+
actors = secici.select_attrs("div.swiper-slide a", "title")
|
|
151
90
|
|
|
152
91
|
if "/dizi/" in url:
|
|
153
|
-
title = secici.select_text("div.cover h5")
|
|
154
|
-
|
|
155
92
|
episodes = []
|
|
156
93
|
for ep in secici.select("div.episode-item"):
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
94
|
+
name = secici.select_text("h4 a", ep)
|
|
95
|
+
href = secici.select_attr("a", "href", ep)
|
|
96
|
+
link_title = secici.select_attr("a", "title", ep)
|
|
97
|
+
|
|
98
|
+
h4_texts = secici.select_texts("h4", ep)
|
|
99
|
+
text = h4_texts[1] if len(h4_texts) > 1 else (h4_texts[0] if h4_texts else "")
|
|
161
100
|
|
|
162
|
-
|
|
163
|
-
ep_episode = None
|
|
164
|
-
if len(ep_parts) >= 4:
|
|
165
|
-
try:
|
|
166
|
-
ep_season = int(ep_parts[0].replace(".", ""))
|
|
167
|
-
ep_episode = int(ep_parts[2].replace(".", ""))
|
|
168
|
-
except ValueError:
|
|
169
|
-
pass
|
|
101
|
+
full_text = f"{text} {link_title}" if link_title else text
|
|
170
102
|
|
|
171
|
-
if
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
episode = ep_episode,
|
|
175
|
-
title = ep_name,
|
|
176
|
-
url = self.fix_url(ep_href),
|
|
177
|
-
))
|
|
103
|
+
if name and href:
|
|
104
|
+
s, e = secici.extract_season_episode(full_text or "")
|
|
105
|
+
episodes.append(Episode(season=s, episode=e, title=name, url=self.fix_url(href)))
|
|
178
106
|
|
|
179
107
|
return SeriesInfo(
|
|
180
|
-
url
|
|
181
|
-
|
|
182
|
-
title = title,
|
|
183
|
-
description = description,
|
|
184
|
-
tags = tags,
|
|
185
|
-
rating = rating,
|
|
186
|
-
year = year,
|
|
187
|
-
duration = duration,
|
|
188
|
-
episodes = episodes if episodes else None,
|
|
189
|
-
actors = actors,
|
|
190
|
-
)
|
|
191
|
-
else:
|
|
192
|
-
# Film için title - g-title div'lerinin 2. olanı
|
|
193
|
-
g_titles = secici.select("div.g-title div")
|
|
194
|
-
title = secici.select_text(element=g_titles[1]) if len(g_titles) >= 2 else None
|
|
195
|
-
|
|
196
|
-
return MovieInfo(
|
|
197
|
-
url = url,
|
|
198
|
-
poster = poster,
|
|
199
|
-
title = title,
|
|
200
|
-
description = description,
|
|
201
|
-
tags = tags,
|
|
202
|
-
rating = rating,
|
|
203
|
-
year = year,
|
|
204
|
-
duration = duration,
|
|
205
|
-
actors = actors,
|
|
108
|
+
url=url, poster=poster, title=title, description=description, tags=tags,
|
|
109
|
+
rating=rating, year=year, duration=duration, episodes=episodes or None, actors=actors
|
|
206
110
|
)
|
|
111
|
+
|
|
112
|
+
return MovieInfo(
|
|
113
|
+
url=url, poster=poster, title=title, description=description, tags=tags,
|
|
114
|
+
rating=rating, year=year, duration=duration, actors=actors
|
|
115
|
+
)
|
|
207
116
|
|
|
208
117
|
async def load_links(self, url: str) -> list[ExtractResult]:
|
|
209
118
|
# Reset headers to get HTML response
|
|
@@ -215,9 +124,7 @@ class DiziPal(PluginBase):
|
|
|
215
124
|
istek = await self.httpx.get(url)
|
|
216
125
|
secici = HTMLHelper(istek.text)
|
|
217
126
|
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
iframe = secici.select_attr(".series-player-container iframe", "src") or secici.select_attr("div#vast_new iframe", "src")
|
|
127
|
+
iframe = secici.select_attr("div.video-player-area iframe", "src") or secici.select_attr("div.responsive-player iframe", "src")
|
|
221
128
|
if not iframe:
|
|
222
129
|
return []
|
|
223
130
|
|