KekikStream 2.4.2__py3-none-any.whl → 2.4.3__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 +26 -75
- 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.3.dist-info}/METADATA +1 -1
- kekikstream-2.4.3.dist-info/RECORD +93 -0
- kekikstream-2.4.2.dist-info/RECORD +0 -93
- {kekikstream-2.4.2.dist-info → kekikstream-2.4.3.dist-info}/WHEEL +0 -0
- {kekikstream-2.4.2.dist-info → kekikstream-2.4.3.dist-info}/entry_points.txt +0 -0
- {kekikstream-2.4.2.dist-info → kekikstream-2.4.3.dist-info}/licenses/LICENSE +0 -0
- {kekikstream-2.4.2.dist-info → kekikstream-2.4.3.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,7 +5,7 @@ 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
|
|
|
@@ -116,94 +116,45 @@ class DiziPal(PluginBase):
|
|
|
116
116
|
|
|
117
117
|
async def load_item(self, url: str) -> MovieInfo | SeriesInfo:
|
|
118
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
|
-
})
|
|
119
|
+
self.httpx.headers.update({"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"})
|
|
122
120
|
self.httpx.headers.pop("X-Requested-With", None)
|
|
123
121
|
|
|
124
122
|
istek = await self.httpx.get(url)
|
|
125
123
|
secici = HTMLHelper(istek.text)
|
|
126
|
-
html_text = istek.text
|
|
127
|
-
|
|
128
|
-
poster = self.fix_url(secici.select_attr("meta[property='og:image']", "content")) if secici.select_attr("meta[property='og:image']", "content") else None
|
|
129
|
-
|
|
130
|
-
# Sidebar bilgilerini topla
|
|
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ı")
|
|
140
|
-
|
|
141
|
-
tags_raw = info.get("Türler", "")
|
|
142
|
-
tags = [t.strip() for t in tags_raw.split() if t.strip()] if tags_raw else None
|
|
143
|
-
|
|
144
|
-
actors_raw = info.get("Oyuncular")
|
|
145
|
-
actors = [a.strip() for a in actors_raw.split(",") if a.strip()] if actors_raw else None
|
|
146
124
|
|
|
125
|
+
poster = self.fix_url(secici.select_attr("meta[property='og:image']", "content"))
|
|
147
126
|
description = secici.select_text("div.summary p")
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
duration
|
|
127
|
+
year = secici.meta_value("Yapım Yılı", container_selector="div.sidebar")
|
|
128
|
+
rating = secici.meta_value("IMDB Puanı", container_selector="div.sidebar")
|
|
129
|
+
duration = secici.meta_value("Ortalama Süre", container_selector="div.sidebar")
|
|
130
|
+
duration = int(secici.regex_first(r"(\d+)", duration)) if duration else None
|
|
131
|
+
tags = secici.meta_list("Türler", sep=" ", container_selector="div.sidebar")
|
|
132
|
+
actors = secici.meta_list("Oyuncular", container_selector="div.sidebar")
|
|
151
133
|
|
|
152
134
|
if "/dizi/" in url:
|
|
153
135
|
title = secici.select_text("div.cover h5")
|
|
154
|
-
|
|
155
136
|
episodes = []
|
|
156
137
|
for ep in secici.select("div.episode-item"):
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
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
|
|
170
|
-
|
|
171
|
-
if ep_name and ep_href:
|
|
172
|
-
episodes.append(Episode(
|
|
173
|
-
season = ep_season,
|
|
174
|
-
episode = ep_episode,
|
|
175
|
-
title = ep_name,
|
|
176
|
-
url = self.fix_url(ep_href),
|
|
177
|
-
))
|
|
138
|
+
name = secici.select_text("div.name", ep)
|
|
139
|
+
href = secici.select_attr("a", "href", ep)
|
|
140
|
+
text = secici.select_text("div.episode", ep)
|
|
141
|
+
if name and href:
|
|
142
|
+
s, e = secici.extract_season_episode(text or "")
|
|
143
|
+
episodes.append(Episode(season=s, episode=e, title=name, url=self.fix_url(href)))
|
|
178
144
|
|
|
179
145
|
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,
|
|
146
|
+
url=url, poster=poster, title=title, description=description, tags=tags,
|
|
147
|
+
rating=rating, year=year, duration=duration, episodes=episodes or None, actors=actors
|
|
206
148
|
)
|
|
149
|
+
|
|
150
|
+
# Film için title - g-title div'lerinin 2. olanı
|
|
151
|
+
g_titles = secici.select("div.g-title div")
|
|
152
|
+
title = secici.select_text(element=g_titles[1]) if len(g_titles) >= 2 else None
|
|
153
|
+
|
|
154
|
+
return MovieInfo(
|
|
155
|
+
url=url, poster=poster, title=title, description=description, tags=tags,
|
|
156
|
+
rating=rating, year=year, duration=duration, actors=actors
|
|
157
|
+
)
|
|
207
158
|
|
|
208
159
|
async def load_links(self, url: str) -> list[ExtractResult]:
|
|
209
160
|
# Reset headers to get HTML response
|
KekikStream/Plugins/DiziYou.py
CHANGED
|
@@ -69,173 +69,65 @@ class DiziYou(PluginBase):
|
|
|
69
69
|
async def load_item(self, url: str) -> SeriesInfo:
|
|
70
70
|
istek = await self.httpx.get(url)
|
|
71
71
|
secici = HTMLHelper(istek.text)
|
|
72
|
-
html_text = istek.text
|
|
73
72
|
|
|
74
|
-
|
|
75
|
-
title
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
# Poster
|
|
84
|
-
poster_src = secici.select_attr("div.category_image img", "src") or secici.select_attr("meta[property='og:image']", "content")
|
|
85
|
-
poster = self.fix_url(poster_src) if poster_src else ""
|
|
86
|
-
|
|
87
|
-
# Year - regex ile çıkarma (xpath yerine)
|
|
88
|
-
year = secici.regex_first(r"(?is)Yapım Yılı.*?(\d{4})", secici.html)
|
|
89
|
-
|
|
90
|
-
description_el = secici.select("div.diziyou_desc") or secici.select("div#icerikcat")
|
|
91
|
-
description = ""
|
|
92
|
-
if description_el:
|
|
93
|
-
# Scriptleri temizle
|
|
94
|
-
for script in secici.select("script", description_el[0]):
|
|
95
|
-
script.decompose()
|
|
96
|
-
description = secici.select_text(None, description_el[0])
|
|
97
|
-
|
|
98
|
-
tags = [secici.select_text(None, a) for a in secici.select("div.genres a") if secici.select_text(None, a)]
|
|
99
|
-
|
|
100
|
-
# Rating - daha spesifik regex ile
|
|
101
|
-
rating = secici.regex_first(r"(?is)IMDB\s*:\s*</span>([0-9.]+)", secici.html)
|
|
102
|
-
|
|
103
|
-
# Actors - regex ile
|
|
104
|
-
actors_raw = secici.regex_first(r"(?is)Oyuncular.*?</span>([^<]+)", secici.html)
|
|
105
|
-
actors = [actor.strip() for actor in actors_raw.split(",") if actor.strip()] if actors_raw else []
|
|
73
|
+
poster = secici.select_poster("div.category_image img")
|
|
74
|
+
title = secici.select_text("h1.title-border")
|
|
75
|
+
description = secici.select_direct_text("div#icerikcatright")
|
|
76
|
+
tags = secici.select_texts("div.genres a")
|
|
77
|
+
rating = secici.regex_first(r"(?is)IMDB\s*:\s*</span>([0-9.]+)", secici.html)
|
|
78
|
+
year = secici.extract_year("div#icerikcat2")
|
|
79
|
+
actors = secici.meta_value("Oyuncular", container_selector="div#icerikcat2")
|
|
80
|
+
actors = [a.strip() for a in actors.split(",")] if actors else []
|
|
106
81
|
|
|
107
82
|
episodes = []
|
|
108
|
-
# Episodes - div#scrollbar-container a (kısıtlı alan)
|
|
109
83
|
for link in secici.select("div#scrollbar-container a"):
|
|
110
|
-
|
|
111
|
-
if
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
title_child = secici.select_text("div.baslik", link) or secici.select_text("div.bolumismi", link)
|
|
117
|
-
if title_child:
|
|
118
|
-
ep_name = title_child
|
|
119
|
-
|
|
120
|
-
# Önce metin üzerinden sezon/bölüm çıkart
|
|
121
|
-
s_val, e_val = HTMLHelper.extract_season_episode(ep_name)
|
|
122
|
-
|
|
123
|
-
# URL bazlı kalıplar: -1-sezon-2-bolum gibi
|
|
124
|
-
if not (s_val or e_val):
|
|
125
|
-
pairs = HTMLHelper(ep_href).regex_all(r"-(\d+)-sezon-(\d+)-bolum")
|
|
126
|
-
if pairs:
|
|
127
|
-
s_val, e_val = int(pairs[0][0]), int(pairs[0][1])
|
|
128
|
-
else:
|
|
129
|
-
pairs = HTMLHelper(ep_href).regex_all(r"(\d+)-sezon-(\d+)-bolum")
|
|
130
|
-
if pairs:
|
|
131
|
-
s_val, e_val = int(pairs[0][0]), int(pairs[0][1])
|
|
132
|
-
else:
|
|
133
|
-
e_val_str = HTMLHelper(ep_href).regex_first(r"(\d+)-bolum")
|
|
134
|
-
if e_val_str:
|
|
135
|
-
e_val = int(e_val_str)
|
|
136
|
-
# Metin üzerinden son bir deneme
|
|
137
|
-
if not e_val:
|
|
138
|
-
e_str = HTMLHelper(ep_name).regex_first(r"(\d+)\s*\.\s*[Bb]ölüm")
|
|
139
|
-
if e_str:
|
|
140
|
-
e_val = int(e_str)
|
|
141
|
-
if not s_val:
|
|
142
|
-
s_str = HTMLHelper(ep_name).regex_first(r"(\d+)\s*\.\s*[Ss]ezon")
|
|
143
|
-
if s_str:
|
|
144
|
-
s_val = int(s_str)
|
|
145
|
-
|
|
146
|
-
if e_val or HTMLHelper(ep_href).regex_first(r"-\d+-sezon-\d+-bolum"):
|
|
147
|
-
episodes.append(Episode(
|
|
148
|
-
season = s_val,
|
|
149
|
-
episode = e_val,
|
|
150
|
-
title = ep_name if ep_name else None,
|
|
151
|
-
url = self.fix_url(ep_href),
|
|
152
|
-
))
|
|
84
|
+
href = secici.select_attr(None, "href", link)
|
|
85
|
+
if href:
|
|
86
|
+
name = secici.select_text("div.bolumismi", link).strip("()")
|
|
87
|
+
s, e = secici.extract_season_episode(f"{name} {href}")
|
|
88
|
+
if e:
|
|
89
|
+
episodes.append(Episode(season=s or 1, episode=e, title=name, url=self.fix_url(href)))
|
|
153
90
|
|
|
154
91
|
return SeriesInfo(
|
|
155
|
-
url
|
|
156
|
-
|
|
157
|
-
title = title,
|
|
158
|
-
description = description,
|
|
159
|
-
tags = tags,
|
|
160
|
-
rating = rating,
|
|
161
|
-
year = year,
|
|
162
|
-
episodes = episodes,
|
|
163
|
-
actors = actors
|
|
92
|
+
url=url, poster=poster, title=title or "Bilinmiyor", description=description,
|
|
93
|
+
tags=tags, rating=rating, year=str(year) if year else None, episodes=episodes, actors=actors
|
|
164
94
|
)
|
|
165
95
|
|
|
166
96
|
async def load_links(self, url: str) -> list[ExtractResult]:
|
|
167
97
|
istek = await self.httpx.get(url)
|
|
168
98
|
secici = HTMLHelper(istek.text)
|
|
169
|
-
|
|
170
|
-
# Title ve episode name - None kontrolü ekle
|
|
171
|
-
item_title = secici.select_text("div.title h1")
|
|
172
|
-
ep_name = secici.select_text("div#bolum-ismi")
|
|
173
99
|
|
|
174
|
-
# Player
|
|
175
|
-
#
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
continue
|
|
190
|
-
if HTMLHelper(href).regex_first(r"(-\d+-sezon-\d+-bolum|/bolum|/episode|/episodes|/play)"):
|
|
191
|
-
break
|
|
192
|
-
|
|
193
|
-
if not player_src:
|
|
194
|
-
return [] # Player bulunamadıysa boş liste döndür
|
|
195
|
-
|
|
196
|
-
item_id = player_src.split("/")[-1].replace(".html", "")
|
|
197
|
-
|
|
198
|
-
subtitles = []
|
|
199
|
-
stream_urls = []
|
|
200
|
-
|
|
201
|
-
for secenek in secici.select("span.diziyouOption"):
|
|
202
|
-
opt_id = secici.select_attr("span.diziyouOption", "id", secenek)
|
|
203
|
-
op_name = secici.select_text("span.diziyouOption", secenek)
|
|
204
|
-
|
|
205
|
-
match opt_id:
|
|
206
|
-
case "turkceAltyazili":
|
|
207
|
-
subtitles.append(Subtitle(
|
|
208
|
-
name = op_name,
|
|
209
|
-
url = self.fix_url(f"{self.main_url.replace('www', 'storage')}/subtitles/{item_id}/tr.vtt"),
|
|
210
|
-
))
|
|
211
|
-
veri = {
|
|
212
|
-
"dil": "Orjinal Dil (TR Altyazı)",
|
|
213
|
-
"url": f"{self.main_url.replace('www', 'storage')}/episodes/{item_id}/play.m3u8"
|
|
214
|
-
}
|
|
215
|
-
if veri not in stream_urls:
|
|
216
|
-
stream_urls.append(veri)
|
|
217
|
-
case "ingilizceAltyazili":
|
|
218
|
-
subtitles.append(Subtitle(
|
|
219
|
-
name = op_name,
|
|
220
|
-
url = self.fix_url(f"{self.main_url.replace('www', 'storage')}/subtitles/{item_id}/en.vtt"),
|
|
221
|
-
))
|
|
222
|
-
veri = {
|
|
223
|
-
"dil": "Orjinal Dil (EN Altyazı)",
|
|
224
|
-
"url": f"{self.main_url.replace('www', 'storage')}/episodes/{item_id}/play.m3u8"
|
|
225
|
-
}
|
|
226
|
-
if veri not in stream_urls:
|
|
227
|
-
stream_urls.append(veri)
|
|
228
|
-
case "turkceDublaj":
|
|
229
|
-
stream_urls.append({
|
|
230
|
-
"dil": "Türkçe Dublaj",
|
|
231
|
-
"url": f"{self.main_url.replace('www', 'storage')}/episodes/{item_id}_tr/play.m3u8"
|
|
232
|
-
})
|
|
100
|
+
# Player iframe'inden ID'yi yakala
|
|
101
|
+
iframe_src = secici.select_attr("iframe#diziyouPlayer", "src") or secici.select_attr("iframe[src*='/player/']", "src")
|
|
102
|
+
if not iframe_src:
|
|
103
|
+
return []
|
|
104
|
+
|
|
105
|
+
item_id = iframe_src.split("/")[-1].replace(".html", "")
|
|
106
|
+
base_storage = self.main_url.replace("www", "storage")
|
|
107
|
+
|
|
108
|
+
subtitles = []
|
|
109
|
+
for sub in [("turkceAltyazili", "tr", "Türkçe"), ("ingilizceAltyazili", "en", "İngilizce")]:
|
|
110
|
+
if secici.select_first(f"span#{sub[0]}"):
|
|
111
|
+
subtitles.append(Subtitle(
|
|
112
|
+
name = f"{sub[2]} Altyazı",
|
|
113
|
+
url = f"{base_storage}/subtitles/{item_id}/{sub[1]}.vtt"
|
|
114
|
+
))
|
|
233
115
|
|
|
234
116
|
results = []
|
|
235
|
-
|
|
117
|
+
# Altyazılı Seçenek (Eğer varsa)
|
|
118
|
+
if secici.select_first("span#turkceAltyazili") or secici.select_first("span#ingilizceAltyazili"):
|
|
119
|
+
results.append(ExtractResult(
|
|
120
|
+
name = "Altyazılı",
|
|
121
|
+
url = f"{base_storage}/episodes/{item_id}/play.m3u8",
|
|
122
|
+
referer = url,
|
|
123
|
+
subtitles = subtitles
|
|
124
|
+
))
|
|
125
|
+
|
|
126
|
+
# Dublaj Seçeneği (Eğer varsa)
|
|
127
|
+
if secici.select_first("span#turkceDublaj"):
|
|
236
128
|
results.append(ExtractResult(
|
|
237
|
-
|
|
238
|
-
|
|
129
|
+
name = "Türkçe Dublaj",
|
|
130
|
+
url = f"{base_storage}/episodes/{item_id}_tr/play.m3u8",
|
|
239
131
|
referer = url,
|
|
240
132
|
subtitles = subtitles
|
|
241
133
|
))
|