KekikStream 2.4.3__tar.gz → 2.4.5__tar.gz
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.
- kekikstream-2.4.5/KekikStream/Plugins/DiziPal.py +180 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream.egg-info/PKG-INFO +1 -1
- {kekikstream-2.4.3 → kekikstream-2.4.5}/PKG-INFO +1 -1
- {kekikstream-2.4.3 → kekikstream-2.4.5}/setup.py +1 -1
- kekikstream-2.4.3/KekikStream/Plugins/DiziPal.py +0 -211
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/CLI/__init__.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/CLI/pypi_kontrol.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Core/Extractor/ExtractorBase.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Core/Extractor/ExtractorLoader.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Core/Extractor/ExtractorManager.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Core/Extractor/ExtractorModels.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Core/Extractor/YTDLPCache.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Core/HTMLHelper.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Core/Media/MediaHandler.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Core/Media/MediaManager.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Core/Plugin/PluginBase.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Core/Plugin/PluginLoader.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Core/Plugin/PluginManager.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Core/Plugin/PluginModels.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Core/UI/UIManager.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Core/__init__.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/CloseLoad.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/ContentX.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/DonilasPlay.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/DzenRu.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/ExPlay.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/Filemoon.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/HDMomPlayer.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/HDPlayerSystem.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/HotStream.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/JFVid.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/JetTv.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/MailRu.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/MixPlayHD.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/MixTiger.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/MolyStream.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/Odnoklassniki.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/PeaceMakerst.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/PixelDrain.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/PlayerFilmIzle.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/RapidVid.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/SetPlay.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/SetPrime.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/SibNet.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/Sobreatsesuyp.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/TRsTX.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/TauVideo.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/TurboImgz.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/TurkeyPlayer.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/VCTPlay.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/VidHide.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/VidMoly.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/VidMoxy.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/VidPapi.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/VideoSeyred.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/Videostr.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/Vidoza.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/YTDLP.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Extractors/YildizKisaFilm.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Plugins/BelgeselX.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Plugins/DiziBox.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Plugins/DiziMom.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Plugins/DiziYou.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Plugins/Dizilla.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Plugins/FilmBip.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Plugins/FilmEkseni.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Plugins/FilmMakinesi.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Plugins/FilmModu.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Plugins/Filmatek.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Plugins/Full4kizle.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Plugins/FullHDFilm.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Plugins/FullHDFilmizlesene.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Plugins/HDFilmCehennemi.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Plugins/JetFilmizle.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Plugins/KultFilmler.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Plugins/RecTV.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Plugins/RoketDizi.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Plugins/SelcukFlix.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Plugins/SetFilmIzle.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Plugins/SezonlukDizi.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Plugins/SineWix.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Plugins/Sinefy.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Plugins/SinemaCX.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Plugins/Sinezy.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Plugins/SuperFilmGeldi.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Plugins/UgurFilm.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Plugins/Watch32.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/Plugins/YabanciDizi.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/__init__.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/__main__.py +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream/requirements.txt +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream.egg-info/SOURCES.txt +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream.egg-info/dependency_links.txt +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream.egg-info/entry_points.txt +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream.egg-info/requires.txt +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/KekikStream.egg-info/top_level.txt +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/LICENSE +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/MANIFEST.in +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/README.md +0 -0
- {kekikstream-2.4.3 → kekikstream-2.4.5}/setup.cfg +0 -0
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
|
+
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, SeriesInfo, Episode, Subtitle, ExtractResult, HTMLHelper
|
|
4
|
+
|
|
5
|
+
class DiziPal(PluginBase):
|
|
6
|
+
name = "DiziPal"
|
|
7
|
+
language = "tr"
|
|
8
|
+
main_url = "https://dizipal.cc"
|
|
9
|
+
favicon = f"https://www.google.com/s2/favicons?domain={main_url}&sz=64"
|
|
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
|
+
|
|
12
|
+
main_page = {
|
|
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",
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
35
|
+
istek = await self.httpx.get(f"{url}{page}/")
|
|
36
|
+
secici = HTMLHelper(istek.text)
|
|
37
|
+
|
|
38
|
+
results = []
|
|
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
|
+
))
|
|
51
|
+
|
|
52
|
+
return results
|
|
53
|
+
|
|
54
|
+
async def search(self, query: str) -> list[SearchResult]:
|
|
55
|
+
istek = await self.httpx.get(f"{self.main_url}/?s={query}")
|
|
56
|
+
secici = HTMLHelper(istek.text)
|
|
57
|
+
|
|
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)
|
|
63
|
+
|
|
64
|
+
if title and href:
|
|
65
|
+
results.append(SearchResult(
|
|
66
|
+
title = title,
|
|
67
|
+
url = self.fix_url(href),
|
|
68
|
+
poster = self.fix_url(poster) if poster else None,
|
|
69
|
+
))
|
|
70
|
+
|
|
71
|
+
return results
|
|
72
|
+
|
|
73
|
+
async def load_item(self, url: str) -> MovieInfo | SeriesInfo:
|
|
74
|
+
istek = await self.httpx.get(url)
|
|
75
|
+
secici = HTMLHelper(istek.text)
|
|
76
|
+
|
|
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")
|
|
80
|
+
|
|
81
|
+
year = secici.meta_value("Yapım Yılı")
|
|
82
|
+
rating = secici.meta_value("IMDB Puanı")
|
|
83
|
+
duration_raw = secici.meta_value("Süre")
|
|
84
|
+
if duration_raw:
|
|
85
|
+
parts = duration_raw.split()
|
|
86
|
+
saat = 0
|
|
87
|
+
dakika = 0
|
|
88
|
+
|
|
89
|
+
for p in parts:
|
|
90
|
+
if "s" in p:
|
|
91
|
+
saat = int(p.replace("s", ""))
|
|
92
|
+
elif "dk" in p:
|
|
93
|
+
dakika = int(p.replace("dk", ""))
|
|
94
|
+
|
|
95
|
+
duration = saat * 60 + dakika
|
|
96
|
+
else:
|
|
97
|
+
duration = None
|
|
98
|
+
|
|
99
|
+
tags = secici.meta_list("Tür")
|
|
100
|
+
actors = secici.meta_list("Oyuncular")
|
|
101
|
+
if not actors:
|
|
102
|
+
actors = secici.select_attrs("div.swiper-slide a", "title")
|
|
103
|
+
|
|
104
|
+
if "/dizi/" in url:
|
|
105
|
+
episodes = []
|
|
106
|
+
for ep in secici.select("div.episode-item"):
|
|
107
|
+
name = secici.select_text("h4 a", ep)
|
|
108
|
+
href = secici.select_attr("a", "href", ep)
|
|
109
|
+
link_title = secici.select_attr("a", "title", ep)
|
|
110
|
+
|
|
111
|
+
h4_texts = secici.select_texts("h4", ep)
|
|
112
|
+
text = h4_texts[1] if len(h4_texts) > 1 else (h4_texts[0] if h4_texts else "")
|
|
113
|
+
|
|
114
|
+
full_text = f"{text} {link_title}" if link_title else text
|
|
115
|
+
|
|
116
|
+
if name and href:
|
|
117
|
+
s, e = secici.extract_season_episode(full_text or "")
|
|
118
|
+
episodes.append(Episode(season=s, episode=e, title=name, url=self.fix_url(href)))
|
|
119
|
+
|
|
120
|
+
return SeriesInfo(
|
|
121
|
+
url=url, poster=poster.replace("https://test4test.online", self.main_url), title=title, description=description, tags=tags,
|
|
122
|
+
rating=rating, year=year, duration=duration, episodes=episodes or None, actors=actors
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
return MovieInfo(
|
|
126
|
+
url=url, poster=poster.replace("https://test4test.online", self.main_url), title=title, description=description, tags=tags,
|
|
127
|
+
rating=rating, year=year, duration=duration, actors=actors
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
async def load_links(self, url: str) -> list[ExtractResult]:
|
|
131
|
+
# Reset headers to get HTML response
|
|
132
|
+
self.httpx.headers.update({
|
|
133
|
+
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
|
|
134
|
+
})
|
|
135
|
+
self.httpx.headers.pop("X-Requested-With", None)
|
|
136
|
+
|
|
137
|
+
istek = await self.httpx.get(url)
|
|
138
|
+
secici = HTMLHelper(istek.text)
|
|
139
|
+
|
|
140
|
+
iframe = secici.select_attr("div.video-player-area iframe", "src") or secici.select_attr("div.responsive-player iframe", "src")
|
|
141
|
+
if not iframe:
|
|
142
|
+
return []
|
|
143
|
+
|
|
144
|
+
results = []
|
|
145
|
+
|
|
146
|
+
self.httpx.headers.update({"Referer": f"{self.main_url}/"})
|
|
147
|
+
i_istek = await self.httpx.get(iframe)
|
|
148
|
+
i_text = i_istek.text
|
|
149
|
+
|
|
150
|
+
# m3u link çıkar
|
|
151
|
+
m3u_link = secici.regex_first(r'file:"([^"]+)"', target=i_text)
|
|
152
|
+
if m3u_link:
|
|
153
|
+
|
|
154
|
+
# Altyazıları çıkar
|
|
155
|
+
sub_text = secici.regex_first(r'"subtitle":"([^"]+)"', target=i_text)
|
|
156
|
+
subtitles = []
|
|
157
|
+
if sub_text:
|
|
158
|
+
if "," in sub_text:
|
|
159
|
+
for sub in sub_text.split(","):
|
|
160
|
+
lang = sub.split("[")[1].split("]")[0] if "[" in sub else "Türkçe"
|
|
161
|
+
sub_url = sub.replace(f"[{lang}]", "")
|
|
162
|
+
subtitles.append(Subtitle(name=lang, url=self.fix_url(sub_url)))
|
|
163
|
+
else:
|
|
164
|
+
lang = sub_text.split("[")[1].split("]")[0] if "[" in sub_text else "Türkçe"
|
|
165
|
+
sub_url = sub_text.replace(f"[{lang}]", "")
|
|
166
|
+
subtitles.append(Subtitle(name=lang, url=self.fix_url(sub_url)))
|
|
167
|
+
|
|
168
|
+
results.append(ExtractResult(
|
|
169
|
+
name = self.name,
|
|
170
|
+
url = m3u_link,
|
|
171
|
+
referer = f"{self.main_url}/",
|
|
172
|
+
subtitles = subtitles
|
|
173
|
+
))
|
|
174
|
+
else:
|
|
175
|
+
# Extractor'a yönlendir
|
|
176
|
+
data = await self.extract(iframe)
|
|
177
|
+
if data:
|
|
178
|
+
results.append(data)
|
|
179
|
+
|
|
180
|
+
return results
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: KekikStream
|
|
3
|
-
Version: 2.4.
|
|
3
|
+
Version: 2.4.5
|
|
4
4
|
Summary: terminal üzerinden medya içeriği aramanızı ve VLC/MPV gibi popüler medya oynatıcılar aracılığıyla doğrudan izlemenizi sağlayan modüler ve genişletilebilir bir bıdı bıdı
|
|
5
5
|
Home-page: https://github.com/keyiflerolsun/KekikStream
|
|
6
6
|
Author: keyiflerolsun
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: KekikStream
|
|
3
|
-
Version: 2.4.
|
|
3
|
+
Version: 2.4.5
|
|
4
4
|
Summary: terminal üzerinden medya içeriği aramanızı ve VLC/MPV gibi popüler medya oynatıcılar aracılığıyla doğrudan izlemenizi sağlayan modüler ve genişletilebilir bir bıdı bıdı
|
|
5
5
|
Home-page: https://github.com/keyiflerolsun/KekikStream
|
|
6
6
|
Author: keyiflerolsun
|
|
@@ -6,7 +6,7 @@ from io import open
|
|
|
6
6
|
setup(
|
|
7
7
|
# ? Genel Bilgiler
|
|
8
8
|
name = "KekikStream",
|
|
9
|
-
version = "2.4.
|
|
9
|
+
version = "2.4.5",
|
|
10
10
|
url = "https://github.com/keyiflerolsun/KekikStream",
|
|
11
11
|
description = "terminal üzerinden medya içeriği aramanızı ve VLC/MPV gibi popüler medya oynatıcılar aracılığıyla doğrudan izlemenizi sağlayan modüler ve genişletilebilir bir bıdı bıdı",
|
|
12
12
|
keywords = ["KekikStream", "KekikAkademi", "keyiflerolsun"],
|
|
@@ -1,211 +0,0 @@
|
|
|
1
|
-
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
|
-
|
|
3
|
-
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, SeriesInfo, Episode, Subtitle, ExtractResult, HTMLHelper
|
|
4
|
-
|
|
5
|
-
class DiziPal(PluginBase):
|
|
6
|
-
name = "DiziPal"
|
|
7
|
-
language = "tr"
|
|
8
|
-
main_url = "https://dizipal.cc"
|
|
9
|
-
favicon = f"https://www.google.com/s2/favicons?domain={main_url}&sz=64"
|
|
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
|
-
|
|
12
|
-
main_page = {
|
|
13
|
-
f"{main_url}/diziler/son-bolumler" : "Son Bölümler",
|
|
14
|
-
f"{main_url}/diziler" : "Yeni Diziler",
|
|
15
|
-
f"{main_url}/filmler" : "Yeni Filmler",
|
|
16
|
-
f"{main_url}/koleksiyon/netflix" : "Netflix",
|
|
17
|
-
f"{main_url}/koleksiyon/exxen" : "Exxen",
|
|
18
|
-
f"{main_url}/koleksiyon/blutv" : "BluTV",
|
|
19
|
-
f"{main_url}/koleksiyon/disney" : "Disney+",
|
|
20
|
-
f"{main_url}/koleksiyon/amazon-prime" : "Amazon Prime",
|
|
21
|
-
f"{main_url}/koleksiyon/tod-bein" : "TOD (beIN)",
|
|
22
|
-
f"{main_url}/koleksiyon/gain" : "Gain",
|
|
23
|
-
f"{main_url}/tur/mubi" : "Mubi",
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
27
|
-
istek = await self.httpx.get(url)
|
|
28
|
-
secici = HTMLHelper(istek.text)
|
|
29
|
-
|
|
30
|
-
results = []
|
|
31
|
-
|
|
32
|
-
if "/son-bolumler" in url:
|
|
33
|
-
for veri in secici.select("div.episode-item"):
|
|
34
|
-
name = secici.select_text("div.name", veri)
|
|
35
|
-
episode = secici.select_text("div.episode", veri)
|
|
36
|
-
href = secici.select_attr("a", "href", veri)
|
|
37
|
-
poster = secici.select_attr("img", "src", veri)
|
|
38
|
-
|
|
39
|
-
if name and href:
|
|
40
|
-
ep_text = episode.replace(". Sezon ", "x").replace(". Bölüm", "") if episode else ""
|
|
41
|
-
title = f"{name} {ep_text}"
|
|
42
|
-
# Son bölümler linkini dizi sayfasına çevir
|
|
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
|
-
))
|
|
64
|
-
|
|
65
|
-
return results
|
|
66
|
-
|
|
67
|
-
async def search(self, query: str) -> list[SearchResult]:
|
|
68
|
-
self.httpx.headers.update({
|
|
69
|
-
"Accept" : "application/json, text/javascript, */*; q=0.01",
|
|
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 []
|
|
82
|
-
|
|
83
|
-
results = []
|
|
84
|
-
|
|
85
|
-
# API bazen dict, bazen list döner
|
|
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:
|
|
97
|
-
results.append(SearchResult(
|
|
98
|
-
title = title,
|
|
99
|
-
url = f"{self.main_url}{url}",
|
|
100
|
-
poster = self.fix_url(poster) if poster else None,
|
|
101
|
-
))
|
|
102
|
-
|
|
103
|
-
return results
|
|
104
|
-
|
|
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
|
-
async def load_item(self, url: str) -> MovieInfo | SeriesInfo:
|
|
118
|
-
# Reset headers to get HTML response
|
|
119
|
-
self.httpx.headers.update({"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"})
|
|
120
|
-
self.httpx.headers.pop("X-Requested-With", None)
|
|
121
|
-
|
|
122
|
-
istek = await self.httpx.get(url)
|
|
123
|
-
secici = HTMLHelper(istek.text)
|
|
124
|
-
|
|
125
|
-
poster = self.fix_url(secici.select_attr("meta[property='og:image']", "content"))
|
|
126
|
-
description = secici.select_text("div.summary p")
|
|
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")
|
|
133
|
-
|
|
134
|
-
if "/dizi/" in url:
|
|
135
|
-
title = secici.select_text("div.cover h5")
|
|
136
|
-
episodes = []
|
|
137
|
-
for ep in secici.select("div.episode-item"):
|
|
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)))
|
|
144
|
-
|
|
145
|
-
return SeriesInfo(
|
|
146
|
-
url=url, poster=poster, title=title, description=description, tags=tags,
|
|
147
|
-
rating=rating, year=year, duration=duration, episodes=episodes or None, actors=actors
|
|
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
|
-
)
|
|
158
|
-
|
|
159
|
-
async def load_links(self, url: str) -> list[ExtractResult]:
|
|
160
|
-
# Reset headers to get HTML response
|
|
161
|
-
self.httpx.headers.update({
|
|
162
|
-
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
|
|
163
|
-
})
|
|
164
|
-
self.httpx.headers.pop("X-Requested-With", None)
|
|
165
|
-
|
|
166
|
-
istek = await self.httpx.get(url)
|
|
167
|
-
secici = HTMLHelper(istek.text)
|
|
168
|
-
|
|
169
|
-
# iframe presence checked via select_attr below
|
|
170
|
-
|
|
171
|
-
iframe = secici.select_attr(".series-player-container iframe", "src") or secici.select_attr("div#vast_new iframe", "src")
|
|
172
|
-
if not iframe:
|
|
173
|
-
return []
|
|
174
|
-
|
|
175
|
-
results = []
|
|
176
|
-
|
|
177
|
-
self.httpx.headers.update({"Referer": f"{self.main_url}/"})
|
|
178
|
-
i_istek = await self.httpx.get(iframe)
|
|
179
|
-
i_text = i_istek.text
|
|
180
|
-
|
|
181
|
-
# m3u link çıkar
|
|
182
|
-
m3u_link = secici.regex_first(r'file:"([^"]+)"', target=i_text)
|
|
183
|
-
if m3u_link:
|
|
184
|
-
|
|
185
|
-
# Altyazıları çıkar
|
|
186
|
-
sub_text = secici.regex_first(r'"subtitle":"([^"]+)"', target=i_text)
|
|
187
|
-
subtitles = []
|
|
188
|
-
if sub_text:
|
|
189
|
-
if "," in sub_text:
|
|
190
|
-
for sub in sub_text.split(","):
|
|
191
|
-
lang = sub.split("[")[1].split("]")[0] if "[" in sub else "Türkçe"
|
|
192
|
-
sub_url = sub.replace(f"[{lang}]", "")
|
|
193
|
-
subtitles.append(Subtitle(name=lang, url=self.fix_url(sub_url)))
|
|
194
|
-
else:
|
|
195
|
-
lang = sub_text.split("[")[1].split("]")[0] if "[" in sub_text else "Türkçe"
|
|
196
|
-
sub_url = sub_text.replace(f"[{lang}]", "")
|
|
197
|
-
subtitles.append(Subtitle(name=lang, url=self.fix_url(sub_url)))
|
|
198
|
-
|
|
199
|
-
results.append(ExtractResult(
|
|
200
|
-
name = self.name,
|
|
201
|
-
url = m3u_link,
|
|
202
|
-
referer = f"{self.main_url}/",
|
|
203
|
-
subtitles = subtitles
|
|
204
|
-
))
|
|
205
|
-
else:
|
|
206
|
-
# Extractor'a yönlendir
|
|
207
|
-
data = await self.extract(iframe)
|
|
208
|
-
if data:
|
|
209
|
-
results.append(data)
|
|
210
|
-
|
|
211
|
-
return results
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|