KekikStream 2.0.4__tar.gz → 2.0.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.
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Extractors/ContentX.py +13 -0
- kekikstream-2.0.5/KekikStream/Extractors/DonilasPlay.py +86 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Extractors/Odnoklassniki.py +6 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Extractors/PeaceMakerst.py +6 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Extractors/RapidVid.py +6 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Extractors/SetPlay.py +7 -1
- kekikstream-2.0.5/KekikStream/Extractors/VCTPlay.py +41 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Extractors/VidMoly.py +6 -0
- kekikstream-2.0.5/KekikStream/Plugins/BelgeselX.py +204 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Plugins/RecTV.py +1 -1
- kekikstream-2.0.5/KekikStream/Plugins/SetFilmIzle.py +243 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream.egg-info/PKG-INFO +1 -1
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream.egg-info/SOURCES.txt +4 -5
- {kekikstream-2.0.4 → kekikstream-2.0.5}/PKG-INFO +1 -1
- {kekikstream-2.0.4 → kekikstream-2.0.5}/setup.py +1 -1
- kekikstream-2.0.4/KekikStream/Extractors/ContentX_.py +0 -55
- kekikstream-2.0.4/KekikStream/Extractors/Odnoklassniki_.py +0 -11
- kekikstream-2.0.4/KekikStream/Extractors/PeaceMakerst_.py +0 -7
- kekikstream-2.0.4/KekikStream/Extractors/RapidVid_.py +0 -7
- kekikstream-2.0.4/KekikStream/Extractors/VidMoly_.py +0 -7
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/CLI/__init__.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/CLI/pypi_kontrol.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Core/Extractor/ExtractorBase.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Core/Extractor/ExtractorLoader.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Core/Extractor/ExtractorManager.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Core/Extractor/ExtractorModels.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Core/Extractor/YTDLPCache.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Core/Media/MediaHandler.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Core/Media/MediaManager.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Core/Plugin/PluginBase.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Core/Plugin/PluginLoader.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Core/Plugin/PluginManager.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Core/Plugin/PluginModels.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Core/UI/UIManager.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Core/__init__.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Extractors/CloseLoad.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Extractors/DzenRu.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Extractors/ExPlay.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Extractors/FirePlayer.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Extractors/HDPlayerSystem.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Extractors/JetTv.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Extractors/MailRu.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Extractors/MixPlayHD.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Extractors/MixTiger.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Extractors/MolyStream.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Extractors/PixelDrain.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Extractors/PlayerFilmIzle.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Extractors/SetPrime.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Extractors/SibNet.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Extractors/Sobreatsesuyp.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Extractors/TRsTX.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Extractors/TauVideo.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Extractors/TurboImgz.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Extractors/TurkeyPlayer.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Extractors/VidHide.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Extractors/VidMoxy.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Extractors/VidPapi.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Extractors/VideoSeyred.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Extractors/YTDLP.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Extractors/YildizKisaFilm.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Plugins/DiziBox.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Plugins/DiziPal.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Plugins/DiziYou.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Plugins/Dizilla.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Plugins/FilmBip.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Plugins/FilmMakinesi.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Plugins/FilmModu.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Plugins/FullHDFilm.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Plugins/FullHDFilmizlesene.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Plugins/HDFilmCehennemi.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Plugins/JetFilmizle.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Plugins/KultFilmler.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Plugins/RoketDizi.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Plugins/SelcukFlix.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Plugins/SezonlukDizi.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Plugins/SineWix.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Plugins/Sinefy.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Plugins/SinemaCX.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Plugins/Sinezy.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Plugins/SuperFilmGeldi.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/Plugins/UgurFilm.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/__init__.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/__main__.py +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream/requirements.txt +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream.egg-info/dependency_links.txt +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream.egg-info/entry_points.txt +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream.egg-info/requires.txt +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/KekikStream.egg-info/top_level.txt +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/LICENSE +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/MANIFEST.in +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/README.md +0 -0
- {kekikstream-2.0.4 → kekikstream-2.0.5}/setup.cfg +0 -0
|
@@ -7,6 +7,19 @@ class ContentX(ExtractorBase):
|
|
|
7
7
|
name = "ContentX"
|
|
8
8
|
main_url = "https://contentx.me"
|
|
9
9
|
|
|
10
|
+
# Birden fazla domain destekle
|
|
11
|
+
supported_domains = [
|
|
12
|
+
"contentx.me", "four.contentx.me",
|
|
13
|
+
"dplayer82.site", "sn.dplayer82.site", "four.dplayer82.site", "org.dplayer82.site",
|
|
14
|
+
"dplayer74.site", "sn.dplayer74.site",
|
|
15
|
+
"hotlinger.com", "sn.hotlinger.com",
|
|
16
|
+
"playru.net", "four.playru.net",
|
|
17
|
+
"pichive.online", "four.pichive.online", "pichive.me", "four.pichive.me"
|
|
18
|
+
]
|
|
19
|
+
|
|
20
|
+
def can_handle_url(self, url: str) -> bool:
|
|
21
|
+
return any(domain in url for domain in self.supported_domains)
|
|
22
|
+
|
|
10
23
|
async def extract(self, url, referer=None) -> list[ExtractResult]:
|
|
11
24
|
if referer:
|
|
12
25
|
self.httpx.headers.update({"Referer": referer})
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
|
+
|
|
3
|
+
from KekikStream.Core import ExtractorBase, ExtractResult, Subtitle
|
|
4
|
+
from Kekik.Sifreleme import AESManager
|
|
5
|
+
import re, json
|
|
6
|
+
|
|
7
|
+
class DonilasPlay(ExtractorBase):
|
|
8
|
+
name = "DonilasPlay"
|
|
9
|
+
main_url = "https://donilasplay.com"
|
|
10
|
+
|
|
11
|
+
async def extract(self, url, referer=None) -> ExtractResult:
|
|
12
|
+
if referer:
|
|
13
|
+
self.httpx.headers.update({"Referer": referer})
|
|
14
|
+
|
|
15
|
+
istek = await self.httpx.get(url)
|
|
16
|
+
istek.raise_for_status()
|
|
17
|
+
i_source = istek.text
|
|
18
|
+
|
|
19
|
+
m3u_link = None
|
|
20
|
+
subtitles = []
|
|
21
|
+
|
|
22
|
+
# bePlayer pattern
|
|
23
|
+
be_player_match = re.search(r"bePlayer\('([^']+)',\s*'(\{[^}]+\})'\);", i_source)
|
|
24
|
+
if be_player_match:
|
|
25
|
+
be_player_pass = be_player_match.group(1)
|
|
26
|
+
be_player_data = be_player_match.group(2)
|
|
27
|
+
|
|
28
|
+
try:
|
|
29
|
+
# AES decrypt
|
|
30
|
+
decrypted = AESManager.decrypt(be_player_data, be_player_pass)
|
|
31
|
+
data = json.loads(decrypted)
|
|
32
|
+
|
|
33
|
+
m3u_link = data.get("video_location")
|
|
34
|
+
|
|
35
|
+
# Altyazıları işle
|
|
36
|
+
str_subtitles = data.get("strSubtitles", [])
|
|
37
|
+
if str_subtitles:
|
|
38
|
+
for sub in str_subtitles:
|
|
39
|
+
label = sub.get("label", "")
|
|
40
|
+
file = sub.get("file", "")
|
|
41
|
+
# Forced altyazıları hariç tut
|
|
42
|
+
if "Forced" in label:
|
|
43
|
+
continue
|
|
44
|
+
if file:
|
|
45
|
+
# Türkçe kontrolü
|
|
46
|
+
keywords = ["tur", "tr", "türkçe", "turkce"]
|
|
47
|
+
language = "Turkish" if any(k in label.lower() for k in keywords) else label
|
|
48
|
+
subtitles.append(Subtitle(
|
|
49
|
+
name = language,
|
|
50
|
+
url = self.fix_url(file)
|
|
51
|
+
))
|
|
52
|
+
except Exception:
|
|
53
|
+
pass
|
|
54
|
+
|
|
55
|
+
# Fallback: file pattern
|
|
56
|
+
if not m3u_link:
|
|
57
|
+
file_match = re.search(r'file:"([^"]+)"', i_source)
|
|
58
|
+
if file_match:
|
|
59
|
+
m3u_link = file_match.group(1)
|
|
60
|
+
|
|
61
|
+
# tracks pattern for subtitles
|
|
62
|
+
tracks_match = re.search(r'tracks:\[([^\]]+)', i_source)
|
|
63
|
+
if tracks_match:
|
|
64
|
+
try:
|
|
65
|
+
tracks_str = f"[{tracks_match.group(1)}]"
|
|
66
|
+
tracks = json.loads(tracks_str)
|
|
67
|
+
for track in tracks:
|
|
68
|
+
file_url = track.get("file")
|
|
69
|
+
label = track.get("label", "")
|
|
70
|
+
if file_url and "Forced" not in label:
|
|
71
|
+
subtitles.append(Subtitle(
|
|
72
|
+
name = label,
|
|
73
|
+
url = self.fix_url(file_url)
|
|
74
|
+
))
|
|
75
|
+
except Exception:
|
|
76
|
+
pass
|
|
77
|
+
|
|
78
|
+
if not m3u_link:
|
|
79
|
+
raise ValueError("m3u link not found")
|
|
80
|
+
|
|
81
|
+
return ExtractResult(
|
|
82
|
+
name = self.name,
|
|
83
|
+
url = m3u_link,
|
|
84
|
+
referer = url,
|
|
85
|
+
subtitles = subtitles
|
|
86
|
+
)
|
|
@@ -7,6 +7,12 @@ class Odnoklassniki(ExtractorBase):
|
|
|
7
7
|
name = "Odnoklassniki"
|
|
8
8
|
main_url = "https://odnoklassniki.ru"
|
|
9
9
|
|
|
10
|
+
# Birden fazla domain destekle
|
|
11
|
+
supported_domains = ["odnoklassniki.ru", "ok.ru"]
|
|
12
|
+
|
|
13
|
+
def can_handle_url(self, url: str) -> bool:
|
|
14
|
+
return any(domain in url for domain in self.supported_domains)
|
|
15
|
+
|
|
10
16
|
async def extract(self, url, referer=None) -> ExtractResult:
|
|
11
17
|
if "/video/" in url:
|
|
12
18
|
url = url.replace("/video/", "/videoembed/")
|
|
@@ -7,6 +7,12 @@ class PeaceMakerst(ExtractorBase):
|
|
|
7
7
|
name = "PeaceMakerst"
|
|
8
8
|
main_url = "https://peacemakerst.com"
|
|
9
9
|
|
|
10
|
+
# Birden fazla domain destekle
|
|
11
|
+
supported_domains = ["peacemakerst.com", "hdstreamable.com"]
|
|
12
|
+
|
|
13
|
+
def can_handle_url(self, url: str) -> bool:
|
|
14
|
+
return any(domain in url for domain in self.supported_domains)
|
|
15
|
+
|
|
10
16
|
async def extract(self, url, referer=None) -> ExtractResult:
|
|
11
17
|
if referer:
|
|
12
18
|
self.httpx.headers.update({"Referer": referer})
|
|
@@ -8,6 +8,12 @@ class RapidVid(ExtractorBase):
|
|
|
8
8
|
name = "RapidVid"
|
|
9
9
|
main_url = "https://rapidvid.net"
|
|
10
10
|
|
|
11
|
+
# Birden fazla domain destekle
|
|
12
|
+
supported_domains = ["rapidvid.net", "rapid.filmmakinesi.to"]
|
|
13
|
+
|
|
14
|
+
def can_handle_url(self, url: str) -> bool:
|
|
15
|
+
return any(domain in url for domain in self.supported_domains)
|
|
16
|
+
|
|
11
17
|
async def extract(self, url, referer=None) -> ExtractResult:
|
|
12
18
|
if referer:
|
|
13
19
|
self.httpx.headers.update({"Referer": referer})
|
|
@@ -5,7 +5,13 @@ import re
|
|
|
5
5
|
|
|
6
6
|
class SetPlay(ExtractorBase):
|
|
7
7
|
name = "SetPlay"
|
|
8
|
-
main_url = "https://setplay.
|
|
8
|
+
main_url = "https://setplay.shop"
|
|
9
|
+
|
|
10
|
+
# Birden fazla domain destekle
|
|
11
|
+
supported_domains = ["setplay.cfd", "setplay.shop", "setplay.site"]
|
|
12
|
+
|
|
13
|
+
def can_handle_url(self, url: str) -> bool:
|
|
14
|
+
return any(domain in url for domain in self.supported_domains)
|
|
9
15
|
|
|
10
16
|
async def extract(self, url, referer=None) -> ExtractResult:
|
|
11
17
|
ext_ref = referer or ""
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
|
+
|
|
3
|
+
from KekikStream.Core import ExtractorBase, ExtractResult
|
|
4
|
+
from urllib.parse import urlparse, parse_qs
|
|
5
|
+
|
|
6
|
+
class VCTPlay(ExtractorBase):
|
|
7
|
+
name = "VCTPlay"
|
|
8
|
+
main_url = "https://vctplay.site"
|
|
9
|
+
|
|
10
|
+
async def extract(self, url, referer=None) -> ExtractResult:
|
|
11
|
+
if referer:
|
|
12
|
+
self.httpx.headers.update({"Referer": referer})
|
|
13
|
+
|
|
14
|
+
# URL'den video ID'sini çıkar
|
|
15
|
+
# https://vctplay.site/video/2hjDGco5exdv -> 2hjDGco5exdv
|
|
16
|
+
video_id = url.split("/")[-1]
|
|
17
|
+
if "?" in video_id:
|
|
18
|
+
video_id = video_id.split("?")[0]
|
|
19
|
+
|
|
20
|
+
# Manifests URL oluştur
|
|
21
|
+
master_url = f"{self.main_url}/manifests/{video_id}/master.txt"
|
|
22
|
+
|
|
23
|
+
# partKey'den isim belirle
|
|
24
|
+
parsed = urlparse(url)
|
|
25
|
+
params = parse_qs(parsed.query)
|
|
26
|
+
part_key = params.get("partKey", [""])[0]
|
|
27
|
+
|
|
28
|
+
name_suffix = ""
|
|
29
|
+
if "turkcedublaj" in part_key.lower():
|
|
30
|
+
name_suffix = "Dublaj"
|
|
31
|
+
elif "turkcealtyazi" in part_key.lower():
|
|
32
|
+
name_suffix = "Altyazı"
|
|
33
|
+
|
|
34
|
+
display_name = f"{self.name} - {name_suffix}" if name_suffix else self.name
|
|
35
|
+
|
|
36
|
+
return ExtractResult(
|
|
37
|
+
name = display_name,
|
|
38
|
+
url = master_url,
|
|
39
|
+
referer = f"{self.main_url}/",
|
|
40
|
+
subtitles = []
|
|
41
|
+
)
|
|
@@ -9,6 +9,12 @@ class VidMoly(ExtractorBase):
|
|
|
9
9
|
name = "VidMoly"
|
|
10
10
|
main_url = "https://vidmoly.to"
|
|
11
11
|
|
|
12
|
+
# Birden fazla domain destekle
|
|
13
|
+
supported_domains = ["vidmoly.to", "vidmoly.me", "vidmoly.net"]
|
|
14
|
+
|
|
15
|
+
def can_handle_url(self, url: str) -> bool:
|
|
16
|
+
return any(domain in url for domain in self.supported_domains)
|
|
17
|
+
|
|
12
18
|
async def extract(self, url: str, referer: str = None) -> ExtractResult:
|
|
13
19
|
if referer:
|
|
14
20
|
self.httpx.headers.update({"Referer": referer})
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
|
+
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, SeriesInfo, Episode
|
|
4
|
+
from parsel import Selector
|
|
5
|
+
import re
|
|
6
|
+
|
|
7
|
+
class BelgeselX(PluginBase):
|
|
8
|
+
name = "BelgeselX"
|
|
9
|
+
language = "tr"
|
|
10
|
+
main_url = "https://belgeselx.com"
|
|
11
|
+
favicon = f"https://www.google.com/s2/favicons?domain={main_url}&sz=64"
|
|
12
|
+
description = "2022 yılında son çıkan belgeselleri belgeselx.com'da izle. En yeni belgeseller, türkçe altyazılı yada dublaj olarak 1080p kalitesinde hd belgesel izle."
|
|
13
|
+
|
|
14
|
+
main_page = {
|
|
15
|
+
f"{main_url}/konu/turk-tarihi-belgeselleri&page=" : "Türk Tarihi",
|
|
16
|
+
f"{main_url}/konu/tarih-belgeselleri&page=" : "Tarih",
|
|
17
|
+
f"{main_url}/konu/seyehat-belgeselleri&page=" : "Seyahat",
|
|
18
|
+
f"{main_url}/konu/seri-belgeseller&page=" : "Seri",
|
|
19
|
+
f"{main_url}/konu/savas-belgeselleri&page=" : "Savaş",
|
|
20
|
+
f"{main_url}/konu/sanat-belgeselleri&page=" : "Sanat",
|
|
21
|
+
f"{main_url}/konu/psikoloji-belgeselleri&page=" : "Psikoloji",
|
|
22
|
+
f"{main_url}/konu/polisiye-belgeselleri&page=" : "Polisiye",
|
|
23
|
+
f"{main_url}/konu/otomobil-belgeselleri&page=" : "Otomobil",
|
|
24
|
+
f"{main_url}/konu/nazi-belgeselleri&page=" : "Nazi",
|
|
25
|
+
f"{main_url}/konu/muhendislik-belgeselleri&page=" : "Mühendislik",
|
|
26
|
+
f"{main_url}/konu/kultur-din-belgeselleri&page=" : "Kültür Din",
|
|
27
|
+
f"{main_url}/konu/kozmik-belgeseller&page=" : "Kozmik",
|
|
28
|
+
f"{main_url}/konu/hayvan-belgeselleri&page=" : "Hayvan",
|
|
29
|
+
f"{main_url}/konu/eski-tarih-belgeselleri&page=" : "Eski Tarih",
|
|
30
|
+
f"{main_url}/konu/egitim-belgeselleri&page=" : "Eğitim",
|
|
31
|
+
f"{main_url}/konu/dunya-belgeselleri&page=" : "Dünya",
|
|
32
|
+
f"{main_url}/konu/doga-belgeselleri&page=" : "Doğa",
|
|
33
|
+
f"{main_url}/konu/bilim-belgeselleri&page=" : "Bilim"
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
@staticmethod
|
|
37
|
+
def _to_title_case(text: str) -> str:
|
|
38
|
+
"""Türkçe için title case dönüşümü."""
|
|
39
|
+
return " ".join(
|
|
40
|
+
word.lower().replace("i", "İ").capitalize() if word.lower().startswith("i") else word.capitalize()
|
|
41
|
+
for word in text.split()
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
45
|
+
istek = self.cloudscraper.get(f"{url}{page}")
|
|
46
|
+
secici = Selector(istek.text)
|
|
47
|
+
|
|
48
|
+
results = []
|
|
49
|
+
for item in secici.css("div.gen-movie-contain > div.gen-info-contain > div.gen-movie-info"):
|
|
50
|
+
title = item.css("div.gen-movie-info > h3 a::text").get()
|
|
51
|
+
href = item.css("div.gen-movie-info > h3 a::attr(href)").get()
|
|
52
|
+
parent = item.xpath("../../..")
|
|
53
|
+
poster = parent.css("div.gen-movie-img > img::attr(src)").get()
|
|
54
|
+
|
|
55
|
+
if title and href:
|
|
56
|
+
results.append(MainPageResult(
|
|
57
|
+
category = category,
|
|
58
|
+
title = self._to_title_case(title.strip()),
|
|
59
|
+
url = self.fix_url(href),
|
|
60
|
+
poster = self.fix_url(poster) if poster else None
|
|
61
|
+
))
|
|
62
|
+
|
|
63
|
+
return results
|
|
64
|
+
|
|
65
|
+
async def search(self, query: str) -> list[SearchResult]:
|
|
66
|
+
# Google Custom Search API kullanıyor
|
|
67
|
+
cx = "016376594590146270301:iwmy65ijgrm"
|
|
68
|
+
|
|
69
|
+
token_resp = self.cloudscraper.get(f"https://cse.google.com/cse.js?cx={cx}")
|
|
70
|
+
token_text = token_resp.text
|
|
71
|
+
|
|
72
|
+
cse_lib_match = re.search(r'cselibVersion": "(.*)"', token_text)
|
|
73
|
+
cse_tok_match = re.search(r'cse_token": "(.*)"', token_text)
|
|
74
|
+
|
|
75
|
+
if not cse_lib_match or not cse_tok_match:
|
|
76
|
+
return []
|
|
77
|
+
|
|
78
|
+
cse_lib = cse_lib_match.group(1)
|
|
79
|
+
cse_tok = cse_tok_match.group(1)
|
|
80
|
+
|
|
81
|
+
search_url = (
|
|
82
|
+
f"https://cse.google.com/cse/element/v1?"
|
|
83
|
+
f"rsz=filtered_cse&num=100&hl=tr&source=gcsc&cselibv={cse_lib}&cx={cx}"
|
|
84
|
+
f"&q={query}&safe=off&cse_tok={cse_tok}&sort=&exp=cc%2Capo&oq={query}"
|
|
85
|
+
f"&callback=google.search.cse.api9969&rurl=https%3A%2F%2Fbelgeselx.com%2F"
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
resp = self.cloudscraper.get(search_url)
|
|
89
|
+
resp_text = resp.text
|
|
90
|
+
|
|
91
|
+
titles = re.findall(r'"titleNoFormatting": "(.*?)"', resp_text)
|
|
92
|
+
urls = re.findall(r'"url": "(.*?)"', resp_text)
|
|
93
|
+
images = re.findall(r'"ogImage": "(.*?)"', resp_text)
|
|
94
|
+
|
|
95
|
+
results = []
|
|
96
|
+
for i, title in enumerate(titles):
|
|
97
|
+
url_val = urls[i] if i < len(urls) else None
|
|
98
|
+
poster = images[i] if i < len(images) else None
|
|
99
|
+
|
|
100
|
+
if not url_val or "diziresimleri" not in url_val:
|
|
101
|
+
# URL'den belgesel linkini oluştur
|
|
102
|
+
if poster and "diziresimleri" in poster:
|
|
103
|
+
file_name = poster.rsplit("/", 1)[-1]
|
|
104
|
+
file_name = re.sub(r"\.(jpe?g|png|webp)$", "", file_name)
|
|
105
|
+
url_val = f"{self.main_url}/belgeseldizi/{file_name}"
|
|
106
|
+
else:
|
|
107
|
+
continue
|
|
108
|
+
|
|
109
|
+
clean_title = title.split("İzle")[0].strip()
|
|
110
|
+
results.append(SearchResult(
|
|
111
|
+
title = self._to_title_case(clean_title),
|
|
112
|
+
url = url_val,
|
|
113
|
+
poster = poster
|
|
114
|
+
))
|
|
115
|
+
|
|
116
|
+
return results
|
|
117
|
+
|
|
118
|
+
async def load_item(self, url: str) -> SeriesInfo:
|
|
119
|
+
istek = await self.httpx.get(url)
|
|
120
|
+
secici = Selector(istek.text)
|
|
121
|
+
|
|
122
|
+
title = secici.css("h2.gen-title::text").get()
|
|
123
|
+
poster = secici.css("div.gen-tv-show-top img::attr(src)").get()
|
|
124
|
+
description = secici.css("div.gen-single-tv-show-info p::text").get()
|
|
125
|
+
|
|
126
|
+
tags = []
|
|
127
|
+
for tag_link in secici.css("div.gen-socail-share a[href*='belgeselkanali']"):
|
|
128
|
+
tag_href = tag_link.css("::attr(href)").get()
|
|
129
|
+
if tag_href:
|
|
130
|
+
tag_name = tag_href.rsplit("/", 1)[-1].replace("-", " ")
|
|
131
|
+
tags.append(self._to_title_case(tag_name))
|
|
132
|
+
|
|
133
|
+
episodes = []
|
|
134
|
+
counter = 0
|
|
135
|
+
for ep_item in secici.css("div.gen-movie-contain"):
|
|
136
|
+
ep_name = ep_item.css("div.gen-movie-info h3 a::text").get()
|
|
137
|
+
ep_href = ep_item.css("div.gen-movie-info h3 a::attr(href)").get()
|
|
138
|
+
|
|
139
|
+
if not ep_name or not ep_href:
|
|
140
|
+
continue
|
|
141
|
+
|
|
142
|
+
season_text = ep_item.css("div.gen-single-meta-holder ul li::text").get() or ""
|
|
143
|
+
episode_match = re.search(r"Bölüm (\d+)", season_text)
|
|
144
|
+
season_match = re.search(r"Sezon (\d+)", season_text)
|
|
145
|
+
|
|
146
|
+
ep_episode = int(episode_match.group(1)) if episode_match else counter
|
|
147
|
+
ep_season = int(season_match.group(1)) if season_match else 1
|
|
148
|
+
|
|
149
|
+
counter += 1
|
|
150
|
+
|
|
151
|
+
episodes.append(Episode(
|
|
152
|
+
season = ep_season,
|
|
153
|
+
episode = ep_episode,
|
|
154
|
+
title = ep_name.strip(),
|
|
155
|
+
url = self.fix_url(ep_href)
|
|
156
|
+
))
|
|
157
|
+
|
|
158
|
+
return SeriesInfo(
|
|
159
|
+
url = url,
|
|
160
|
+
poster = self.fix_url(poster) if poster else None,
|
|
161
|
+
title = self._to_title_case(title.strip()) if title else None,
|
|
162
|
+
description = description.strip() if description else None,
|
|
163
|
+
tags = tags,
|
|
164
|
+
episodes = episodes
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
async def load_links(self, url: str) -> list[dict]:
|
|
168
|
+
istek = await self.httpx.get(url)
|
|
169
|
+
text = istek.text
|
|
170
|
+
|
|
171
|
+
# fnc_addWatch div'inden data-episode ID'sini al
|
|
172
|
+
ep_match = re.search(r'<div[^>]*class=["\'][^"\']*fnc_addWatch[^"\']*["\'][^>]*data-episode=["\'](\d+)["\']', text)
|
|
173
|
+
if not ep_match:
|
|
174
|
+
return []
|
|
175
|
+
|
|
176
|
+
episode_id = ep_match.group(1)
|
|
177
|
+
iframe_url = f"{self.main_url}/video/data/new4.php?id={episode_id}"
|
|
178
|
+
|
|
179
|
+
iframe_resp = await self.httpx.get(iframe_url, headers={"Referer": url})
|
|
180
|
+
iframe_text = iframe_resp.text
|
|
181
|
+
|
|
182
|
+
links = []
|
|
183
|
+
for match in re.finditer(r'file:"([^"]+)", label: "([^"]+)"', iframe_text):
|
|
184
|
+
video_url = match.group(1)
|
|
185
|
+
quality = match.group(2)
|
|
186
|
+
|
|
187
|
+
source_name = "Google" if quality == "FULL" else self.name
|
|
188
|
+
quality_str = "1080p" if quality == "FULL" else quality
|
|
189
|
+
|
|
190
|
+
links.append({
|
|
191
|
+
"url" : video_url,
|
|
192
|
+
"name" : f"{source_name} | {quality_str}",
|
|
193
|
+
"referer" : url
|
|
194
|
+
})
|
|
195
|
+
|
|
196
|
+
return links
|
|
197
|
+
|
|
198
|
+
async def play(self, **kwargs):
|
|
199
|
+
extract_result = ExtractResult(**kwargs)
|
|
200
|
+
self.media_handler.title = kwargs.get("name")
|
|
201
|
+
if self.name not in self.media_handler.title:
|
|
202
|
+
self.media_handler.title = f"{self.name} | {self.media_handler.title}"
|
|
203
|
+
|
|
204
|
+
self.media_handler.play_media(extract_result)
|
|
@@ -7,7 +7,7 @@ import re
|
|
|
7
7
|
class RecTV(PluginBase):
|
|
8
8
|
name = "RecTV"
|
|
9
9
|
language = "tr"
|
|
10
|
-
main_url = "https://m.
|
|
10
|
+
main_url = "https://m.prectv60.lol"
|
|
11
11
|
favicon = "https://rectvapk.cc/wp-content/uploads/2023/02/Rec-TV.webp"
|
|
12
12
|
description = "RecTv APK, Türkiye’deki en popüler Çevrimiçi Medya Akış platformlarından biridir. Filmlerin, Canlı Sporların, Web Dizilerinin ve çok daha fazlasının keyfini ücretsiz çıkarın."
|
|
13
13
|
|
|
@@ -0,0 +1,243 @@
|
|
|
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
|
|
4
|
+
from parsel import Selector
|
|
5
|
+
import re, json
|
|
6
|
+
|
|
7
|
+
class SetFilmIzle(PluginBase):
|
|
8
|
+
name = "SetFilmIzle"
|
|
9
|
+
language = "tr"
|
|
10
|
+
main_url = "https://www.setfilmizle.uk"
|
|
11
|
+
favicon = f"https://www.google.com/s2/favicons?domain={main_url}&sz=64"
|
|
12
|
+
description = "Setfilmizle sitemizde, donma yaşamadan Türkçe dublaj ve altyazılı filmleri ile dizileri muhteşem 1080p full HD kalitesinde izleyebilirsiniz."
|
|
13
|
+
|
|
14
|
+
main_page = {
|
|
15
|
+
f"{main_url}/tur/aile/" : "Aile",
|
|
16
|
+
f"{main_url}/tur/aksiyon/" : "Aksiyon",
|
|
17
|
+
f"{main_url}/tur/animasyon/" : "Animasyon",
|
|
18
|
+
f"{main_url}/tur/belgesel/" : "Belgesel",
|
|
19
|
+
f"{main_url}/tur/bilim-kurgu/" : "Bilim-Kurgu",
|
|
20
|
+
f"{main_url}/tur/biyografi/" : "Biyografi",
|
|
21
|
+
f"{main_url}/tur/dini/" : "Dini",
|
|
22
|
+
f"{main_url}/tur/dram/" : "Dram",
|
|
23
|
+
f"{main_url}/tur/fantastik/" : "Fantastik",
|
|
24
|
+
f"{main_url}/tur/genclik/" : "Gençlik",
|
|
25
|
+
f"{main_url}/tur/gerilim/" : "Gerilim",
|
|
26
|
+
f"{main_url}/tur/gizem/" : "Gizem",
|
|
27
|
+
f"{main_url}/tur/komedi/" : "Komedi",
|
|
28
|
+
f"{main_url}/tur/korku/" : "Korku",
|
|
29
|
+
f"{main_url}/tur/macera/" : "Macera",
|
|
30
|
+
f"{main_url}/tur/romantik/" : "Romantik",
|
|
31
|
+
f"{main_url}/tur/savas/" : "Savaş",
|
|
32
|
+
f"{main_url}/tur/suc/" : "Suç",
|
|
33
|
+
f"{main_url}/tur/tarih/" : "Tarih",
|
|
34
|
+
f"{main_url}/tur/western/" : "Western"
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
38
|
+
istek = self.cloudscraper.get(url)
|
|
39
|
+
secici = Selector(istek.text)
|
|
40
|
+
|
|
41
|
+
results = []
|
|
42
|
+
for item in secici.css("div.items article"):
|
|
43
|
+
title = item.css("h2::text").get()
|
|
44
|
+
href = item.css("a::attr(href)").get()
|
|
45
|
+
poster = item.css("img::attr(data-src)").get()
|
|
46
|
+
|
|
47
|
+
if title and href:
|
|
48
|
+
results.append(MainPageResult(
|
|
49
|
+
category = category,
|
|
50
|
+
title = title.strip(),
|
|
51
|
+
url = self.fix_url(href),
|
|
52
|
+
poster = self.fix_url(poster) if poster else None
|
|
53
|
+
))
|
|
54
|
+
|
|
55
|
+
return results
|
|
56
|
+
|
|
57
|
+
async def search(self, query: str) -> list[SearchResult]:
|
|
58
|
+
# Ana sayfadan nonce değerini al
|
|
59
|
+
main_resp = self.cloudscraper.get(self.main_url)
|
|
60
|
+
|
|
61
|
+
# Birden fazla nonce pattern dene
|
|
62
|
+
nonce = ""
|
|
63
|
+
nonce_patterns = [
|
|
64
|
+
r'nonces:\s*\{\s*search:\s*"([^"]+)"', # STMOVIE_AJAX.nonces.search
|
|
65
|
+
r'"search":\s*"([a-zA-Z0-9]+)"', # JSON format
|
|
66
|
+
r"nonce:\s*'([^']*)'",
|
|
67
|
+
r'"nonce":"([^"]+)"',
|
|
68
|
+
r'data-nonce="([^"]+)"',
|
|
69
|
+
]
|
|
70
|
+
for pattern in nonce_patterns:
|
|
71
|
+
match = re.search(pattern, main_resp.text)
|
|
72
|
+
if match:
|
|
73
|
+
nonce = match.group(1)
|
|
74
|
+
break
|
|
75
|
+
|
|
76
|
+
search_resp = self.cloudscraper.post(
|
|
77
|
+
f"{self.main_url}/wp-admin/admin-ajax.php",
|
|
78
|
+
headers = {
|
|
79
|
+
"X-Requested-With" : "XMLHttpRequest",
|
|
80
|
+
"Content-Type" : "application/x-www-form-urlencoded",
|
|
81
|
+
"Referer" : f"{self.main_url}/"
|
|
82
|
+
},
|
|
83
|
+
data = {
|
|
84
|
+
"action" : "ajax_search",
|
|
85
|
+
"search" : query,
|
|
86
|
+
"original_search" : query,
|
|
87
|
+
"nonce" : nonce
|
|
88
|
+
}
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
try:
|
|
92
|
+
data = search_resp.json()
|
|
93
|
+
html = data.get("html", "")
|
|
94
|
+
except:
|
|
95
|
+
return []
|
|
96
|
+
|
|
97
|
+
secici = Selector(text=html)
|
|
98
|
+
results = []
|
|
99
|
+
|
|
100
|
+
for item in secici.css("div.items article"):
|
|
101
|
+
title = item.css("h2::text").get()
|
|
102
|
+
href = item.css("a::attr(href)").get()
|
|
103
|
+
poster = item.css("img::attr(data-src)").get()
|
|
104
|
+
|
|
105
|
+
if title and href:
|
|
106
|
+
results.append(SearchResult(
|
|
107
|
+
title = title.strip(),
|
|
108
|
+
url = self.fix_url(href),
|
|
109
|
+
poster = self.fix_url(poster) if poster else None
|
|
110
|
+
))
|
|
111
|
+
|
|
112
|
+
return results
|
|
113
|
+
|
|
114
|
+
async def load_item(self, url: str) -> MovieInfo | SeriesInfo:
|
|
115
|
+
istek = await self.httpx.get(url)
|
|
116
|
+
secici = Selector(istek.text)
|
|
117
|
+
|
|
118
|
+
raw_title = secici.css("h1::text").get() or ""
|
|
119
|
+
title = re.sub(r"\s*izle.*$", "", raw_title, flags=re.IGNORECASE).strip()
|
|
120
|
+
poster = secici.css("div.poster img::attr(src)").get()
|
|
121
|
+
description = secici.css("div.wp-content p::text").get()
|
|
122
|
+
year = secici.css("div.extra span.C a::text").get()
|
|
123
|
+
if year:
|
|
124
|
+
year_match = re.search(r"\d{4}", year)
|
|
125
|
+
year = year_match.group() if year_match else None
|
|
126
|
+
tags = [a.css("::text").get().strip() for a in secici.css("div.sgeneros a") if a.css("::text").get()]
|
|
127
|
+
duration = secici.css("span.runtime::text").get()
|
|
128
|
+
if duration:
|
|
129
|
+
dur_match = re.search(r"\d+", duration)
|
|
130
|
+
duration = int(dur_match.group()) if dur_match else None
|
|
131
|
+
|
|
132
|
+
actors = [span.css("::text").get().strip() for span in secici.css("span.valor a > span") if span.css("::text").get()]
|
|
133
|
+
|
|
134
|
+
trailer_match = re.search(r'embed/([^?]*)\?rel', istek.text)
|
|
135
|
+
trailer = f"https://www.youtube.com/embed/{trailer_match.group(1)}" if trailer_match else None
|
|
136
|
+
|
|
137
|
+
# Dizi mi film mi kontrol et
|
|
138
|
+
is_series = "/dizi/" in url
|
|
139
|
+
|
|
140
|
+
if is_series:
|
|
141
|
+
year_elem = secici.css("a[href*='/yil/']::text").get()
|
|
142
|
+
if year_elem:
|
|
143
|
+
year_match = re.search(r"\d{4}", year_elem)
|
|
144
|
+
year = year_match.group() if year_match else year
|
|
145
|
+
|
|
146
|
+
dur_elem = secici.css("div#info span:contains('Dakika')::text").get()
|
|
147
|
+
if dur_elem:
|
|
148
|
+
dur_match = re.search(r"\d+", dur_elem)
|
|
149
|
+
duration = int(dur_match.group()) if dur_match else duration
|
|
150
|
+
|
|
151
|
+
episodes = []
|
|
152
|
+
for ep_item in secici.css("div#episodes ul.episodios li"):
|
|
153
|
+
ep_href = ep_item.css("h4.episodiotitle a::attr(href)").get()
|
|
154
|
+
ep_name = ep_item.css("h4.episodiotitle a::text").get()
|
|
155
|
+
|
|
156
|
+
if not ep_href or not ep_name:
|
|
157
|
+
continue
|
|
158
|
+
|
|
159
|
+
ep_detail = ep_name.strip()
|
|
160
|
+
season_match = re.search(r"(\d+)\.\s*Sezon", ep_detail)
|
|
161
|
+
episode_match = re.search(r"Sezon\s+(\d+)\.\s*Bölüm", ep_detail)
|
|
162
|
+
|
|
163
|
+
ep_season = int(season_match.group(1)) if season_match else 1
|
|
164
|
+
ep_episode = int(episode_match.group(1)) if episode_match else None
|
|
165
|
+
|
|
166
|
+
episodes.append(Episode(
|
|
167
|
+
season = ep_season,
|
|
168
|
+
episode = ep_episode,
|
|
169
|
+
title = ep_name.strip(),
|
|
170
|
+
url = self.fix_url(ep_href)
|
|
171
|
+
))
|
|
172
|
+
|
|
173
|
+
return SeriesInfo(
|
|
174
|
+
url = url,
|
|
175
|
+
poster = self.fix_url(poster) if poster else None,
|
|
176
|
+
title = title,
|
|
177
|
+
description = description.strip() if description else None,
|
|
178
|
+
tags = tags,
|
|
179
|
+
year = year,
|
|
180
|
+
duration = duration,
|
|
181
|
+
actors = actors,
|
|
182
|
+
episodes = episodes
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
return MovieInfo(
|
|
186
|
+
url = url,
|
|
187
|
+
poster = self.fix_url(poster) if poster else None,
|
|
188
|
+
title = title,
|
|
189
|
+
description = description.strip() if description else None,
|
|
190
|
+
tags = tags,
|
|
191
|
+
year = year,
|
|
192
|
+
duration = duration,
|
|
193
|
+
actors = actors
|
|
194
|
+
)
|
|
195
|
+
|
|
196
|
+
async def load_links(self, url: str) -> list[dict]:
|
|
197
|
+
istek = await self.httpx.get(url)
|
|
198
|
+
secici = Selector(istek.text)
|
|
199
|
+
|
|
200
|
+
nonce = secici.css("div#playex::attr(data-nonce)").get() or ""
|
|
201
|
+
|
|
202
|
+
links = []
|
|
203
|
+
for player in secici.css("nav.player a"):
|
|
204
|
+
source_id = player.css("::attr(data-post-id)").get()
|
|
205
|
+
player_name = player.css("::attr(data-player-name)").get()
|
|
206
|
+
part_key = player.css("::attr(data-part-key)").get()
|
|
207
|
+
|
|
208
|
+
if not source_id or "event" in source_id or source_id == "":
|
|
209
|
+
continue
|
|
210
|
+
|
|
211
|
+
# Multipart form request
|
|
212
|
+
try:
|
|
213
|
+
resp = self.cloudscraper.post(
|
|
214
|
+
f"{self.main_url}/wp-admin/admin-ajax.php",
|
|
215
|
+
headers = {"Referer": url},
|
|
216
|
+
data = {
|
|
217
|
+
"action" : "get_video_url",
|
|
218
|
+
"nonce" : nonce,
|
|
219
|
+
"post_id" : source_id,
|
|
220
|
+
"player_name" : player_name or "",
|
|
221
|
+
"part_key" : part_key or ""
|
|
222
|
+
}
|
|
223
|
+
)
|
|
224
|
+
data = resp.json()
|
|
225
|
+
except:
|
|
226
|
+
continue
|
|
227
|
+
|
|
228
|
+
iframe_url = data.get("data", {}).get("url")
|
|
229
|
+
if not iframe_url:
|
|
230
|
+
continue
|
|
231
|
+
|
|
232
|
+
# SetPlay URL'si için part_key ekleme
|
|
233
|
+
if "setplay" not in iframe_url and part_key:
|
|
234
|
+
iframe_url = f"{iframe_url}?partKey={part_key}"
|
|
235
|
+
|
|
236
|
+
extractor = self.ex_manager.find_extractor(iframe_url)
|
|
237
|
+
links.append({
|
|
238
|
+
"url" : iframe_url,
|
|
239
|
+
"name" : extractor.name if extractor else player_name or "Direct Link",
|
|
240
|
+
"referer" : self.main_url
|
|
241
|
+
})
|
|
242
|
+
|
|
243
|
+
return links
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: KekikStream
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.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
|
|
@@ -28,7 +28,7 @@ KekikStream/Core/Plugin/PluginModels.py
|
|
|
28
28
|
KekikStream/Core/UI/UIManager.py
|
|
29
29
|
KekikStream/Extractors/CloseLoad.py
|
|
30
30
|
KekikStream/Extractors/ContentX.py
|
|
31
|
-
KekikStream/Extractors/
|
|
31
|
+
KekikStream/Extractors/DonilasPlay.py
|
|
32
32
|
KekikStream/Extractors/DzenRu.py
|
|
33
33
|
KekikStream/Extractors/ExPlay.py
|
|
34
34
|
KekikStream/Extractors/FirePlayer.py
|
|
@@ -39,13 +39,10 @@ KekikStream/Extractors/MixPlayHD.py
|
|
|
39
39
|
KekikStream/Extractors/MixTiger.py
|
|
40
40
|
KekikStream/Extractors/MolyStream.py
|
|
41
41
|
KekikStream/Extractors/Odnoklassniki.py
|
|
42
|
-
KekikStream/Extractors/Odnoklassniki_.py
|
|
43
42
|
KekikStream/Extractors/PeaceMakerst.py
|
|
44
|
-
KekikStream/Extractors/PeaceMakerst_.py
|
|
45
43
|
KekikStream/Extractors/PixelDrain.py
|
|
46
44
|
KekikStream/Extractors/PlayerFilmIzle.py
|
|
47
45
|
KekikStream/Extractors/RapidVid.py
|
|
48
|
-
KekikStream/Extractors/RapidVid_.py
|
|
49
46
|
KekikStream/Extractors/SetPlay.py
|
|
50
47
|
KekikStream/Extractors/SetPrime.py
|
|
51
48
|
KekikStream/Extractors/SibNet.py
|
|
@@ -54,14 +51,15 @@ KekikStream/Extractors/TRsTX.py
|
|
|
54
51
|
KekikStream/Extractors/TauVideo.py
|
|
55
52
|
KekikStream/Extractors/TurboImgz.py
|
|
56
53
|
KekikStream/Extractors/TurkeyPlayer.py
|
|
54
|
+
KekikStream/Extractors/VCTPlay.py
|
|
57
55
|
KekikStream/Extractors/VidHide.py
|
|
58
56
|
KekikStream/Extractors/VidMoly.py
|
|
59
|
-
KekikStream/Extractors/VidMoly_.py
|
|
60
57
|
KekikStream/Extractors/VidMoxy.py
|
|
61
58
|
KekikStream/Extractors/VidPapi.py
|
|
62
59
|
KekikStream/Extractors/VideoSeyred.py
|
|
63
60
|
KekikStream/Extractors/YTDLP.py
|
|
64
61
|
KekikStream/Extractors/YildizKisaFilm.py
|
|
62
|
+
KekikStream/Plugins/BelgeselX.py
|
|
65
63
|
KekikStream/Plugins/DiziBox.py
|
|
66
64
|
KekikStream/Plugins/DiziPal.py
|
|
67
65
|
KekikStream/Plugins/DiziYou.py
|
|
@@ -77,6 +75,7 @@ KekikStream/Plugins/KultFilmler.py
|
|
|
77
75
|
KekikStream/Plugins/RecTV.py
|
|
78
76
|
KekikStream/Plugins/RoketDizi.py
|
|
79
77
|
KekikStream/Plugins/SelcukFlix.py
|
|
78
|
+
KekikStream/Plugins/SetFilmIzle.py
|
|
80
79
|
KekikStream/Plugins/SezonlukDizi.py
|
|
81
80
|
KekikStream/Plugins/SineWix.py
|
|
82
81
|
KekikStream/Plugins/Sinefy.py
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: KekikStream
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.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.0.
|
|
9
|
+
version = "2.0.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,55 +0,0 @@
|
|
|
1
|
-
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
|
-
|
|
3
|
-
from KekikStream.Extractors.ContentX import ContentX
|
|
4
|
-
|
|
5
|
-
class SNDPlayer(ContentX):
|
|
6
|
-
name = "SNDPlayer"
|
|
7
|
-
main_url = "https://sn.dplayer82.site"
|
|
8
|
-
|
|
9
|
-
class FourDPlayer(ContentX):
|
|
10
|
-
name = "FourDPlayer"
|
|
11
|
-
main_url = "https://four.dplayer82.site"
|
|
12
|
-
|
|
13
|
-
class ORGDPlayer(ContentX):
|
|
14
|
-
name = "ORGDPlayer"
|
|
15
|
-
main_url = "https://org.dplayer82.site"
|
|
16
|
-
|
|
17
|
-
class SNDPlayer74(ContentX):
|
|
18
|
-
name = "SNDPlayer74"
|
|
19
|
-
main_url = "https://sn.dplayer74.site"
|
|
20
|
-
|
|
21
|
-
class Hotlinger(ContentX):
|
|
22
|
-
name = "Hotlinger"
|
|
23
|
-
main_url = "https://hotlinger.com"
|
|
24
|
-
|
|
25
|
-
class SNHotlinger(ContentX):
|
|
26
|
-
name = "SNHotlinger"
|
|
27
|
-
main_url = "https://sn.hotlinger.com"
|
|
28
|
-
|
|
29
|
-
class PlayRu(ContentX):
|
|
30
|
-
name = "PlayRu"
|
|
31
|
-
main_url = "https://playru.net"
|
|
32
|
-
|
|
33
|
-
class FourPlayRu(ContentX):
|
|
34
|
-
name = "FourPlayRu"
|
|
35
|
-
main_url = "https://four.playru.net"
|
|
36
|
-
|
|
37
|
-
class Pichive(ContentX):
|
|
38
|
-
name = "Pichive"
|
|
39
|
-
main_url = "https://pichive.online"
|
|
40
|
-
|
|
41
|
-
class PichiveMe(ContentX):
|
|
42
|
-
name = "PichiveMe"
|
|
43
|
-
main_url = "https://pichive.me"
|
|
44
|
-
|
|
45
|
-
class FourPichiveOnline(ContentX):
|
|
46
|
-
name = "FourPichiveOnline"
|
|
47
|
-
main_url = "https://four.pichive.online"
|
|
48
|
-
|
|
49
|
-
class FourPichiveMe(ContentX):
|
|
50
|
-
name = "FourPichive"
|
|
51
|
-
main_url = "https://four.pichive.me"
|
|
52
|
-
|
|
53
|
-
class FourCX(ContentX):
|
|
54
|
-
name = "FourCX"
|
|
55
|
-
main_url = "https://four.contentx.me"
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
|
-
|
|
3
|
-
from KekikStream.Extractors.Odnoklassniki import Odnoklassniki
|
|
4
|
-
|
|
5
|
-
class OkRuHTTP(Odnoklassniki):
|
|
6
|
-
name = "OkRuHTTP"
|
|
7
|
-
main_url = "http://ok.ru"
|
|
8
|
-
|
|
9
|
-
class OkRuSSL(Odnoklassniki):
|
|
10
|
-
name = "OkRuSSL"
|
|
11
|
-
main_url = "https://ok.ru"
|
|
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
|