KekikStream 1.7.1__py3-none-any.whl → 2.0.2__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 +13 -7
- KekikStream/Core/Extractor/ExtractorLoader.py +25 -17
- KekikStream/Core/Extractor/ExtractorManager.py +53 -9
- KekikStream/Core/Extractor/ExtractorModels.py +5 -7
- KekikStream/Core/Extractor/YTDLPCache.py +35 -0
- KekikStream/Core/Media/MediaHandler.py +44 -26
- KekikStream/Core/Media/MediaManager.py +0 -3
- KekikStream/Core/Plugin/PluginBase.py +21 -9
- KekikStream/Core/Plugin/PluginLoader.py +11 -7
- KekikStream/Core/Plugin/PluginModels.py +25 -26
- KekikStream/Core/__init__.py +1 -0
- KekikStream/Extractors/CloseLoad.py +4 -5
- KekikStream/Extractors/ContentX.py +4 -6
- KekikStream/Extractors/ContentX_.py +40 -0
- KekikStream/Extractors/DzenRu.py +38 -0
- KekikStream/Extractors/ExPlay.py +53 -0
- KekikStream/Extractors/FirePlayer.py +60 -0
- KekikStream/Extractors/HDPlayerSystem.py +41 -0
- KekikStream/Extractors/JetTv.py +45 -0
- KekikStream/Extractors/MailRu.py +3 -4
- KekikStream/Extractors/MixPlayHD.py +2 -3
- KekikStream/Extractors/MixTiger.py +57 -0
- KekikStream/Extractors/MolyStream.py +5 -5
- KekikStream/Extractors/Odnoklassniki.py +7 -7
- KekikStream/Extractors/{OkRuHTTP.py → Odnoklassniki_.py} +5 -1
- KekikStream/Extractors/PeaceMakerst.py +4 -5
- KekikStream/Extractors/{HDStreamAble.py → PeaceMakerst_.py} +1 -1
- KekikStream/Extractors/PixelDrain.py +1 -2
- KekikStream/Extractors/PlayerFilmIzle.py +62 -0
- KekikStream/Extractors/RapidVid.py +2 -3
- KekikStream/Extractors/RapidVid_.py +7 -0
- KekikStream/Extractors/SetPlay.py +57 -0
- KekikStream/Extractors/SetPrime.py +45 -0
- KekikStream/Extractors/SibNet.py +2 -3
- KekikStream/Extractors/Sobreatsesuyp.py +4 -5
- KekikStream/Extractors/TRsTX.py +4 -5
- KekikStream/Extractors/TauVideo.py +2 -3
- KekikStream/Extractors/TurboImgz.py +2 -3
- KekikStream/Extractors/TurkeyPlayer.py +34 -0
- KekikStream/Extractors/VidHide.py +72 -0
- KekikStream/Extractors/VidMoly.py +4 -5
- KekikStream/Extractors/{VidMolyMe.py → VidMoly_.py} +1 -1
- KekikStream/Extractors/VidMoxy.py +2 -3
- KekikStream/Extractors/VidPapi.py +89 -0
- KekikStream/Extractors/VideoSeyred.py +3 -4
- KekikStream/Extractors/YTDLP.py +177 -0
- KekikStream/Extractors/YildizKisaFilm.py +41 -0
- KekikStream/Plugins/DiziBox.py +18 -23
- KekikStream/Plugins/DiziPal.py +16 -16
- KekikStream/Plugins/DiziYou.py +48 -23
- KekikStream/Plugins/Dizilla.py +47 -32
- KekikStream/Plugins/FilmBip.py +145 -0
- KekikStream/Plugins/FilmMakinesi.py +6 -8
- KekikStream/Plugins/FilmModu.py +9 -9
- KekikStream/Plugins/FullHDFilm.py +164 -0
- KekikStream/Plugins/FullHDFilmizlesene.py +4 -8
- KekikStream/Plugins/HDFilmCehennemi.py +15 -19
- KekikStream/Plugins/JetFilmizle.py +67 -49
- KekikStream/Plugins/KultFilmler.py +219 -0
- KekikStream/Plugins/RecTV.py +18 -22
- KekikStream/Plugins/RoketDizi.py +232 -0
- KekikStream/Plugins/SelcukFlix.py +309 -0
- KekikStream/Plugins/SezonlukDizi.py +12 -13
- KekikStream/Plugins/SineWix.py +8 -12
- KekikStream/Plugins/Sinefy.py +238 -0
- KekikStream/Plugins/SinemaCX.py +157 -0
- KekikStream/Plugins/Sinezy.py +146 -0
- KekikStream/Plugins/SuperFilmGeldi.py +121 -0
- KekikStream/Plugins/UgurFilm.py +7 -11
- KekikStream/__init__.py +34 -24
- KekikStream/requirements.txt +3 -4
- kekikstream-2.0.2.dist-info/METADATA +309 -0
- kekikstream-2.0.2.dist-info/RECORD +82 -0
- KekikStream/Extractors/FourCX.py +0 -7
- KekikStream/Extractors/FourPichive.py +0 -7
- KekikStream/Extractors/FourPlayRu.py +0 -7
- KekikStream/Extractors/Hotlinger.py +0 -7
- KekikStream/Extractors/OkRuSSL.py +0 -7
- KekikStream/Extractors/Pichive.py +0 -7
- KekikStream/Extractors/PlayRu.py +0 -7
- kekikstream-1.7.1.dist-info/METADATA +0 -109
- kekikstream-1.7.1.dist-info/RECORD +0 -63
- {kekikstream-1.7.1.dist-info → kekikstream-2.0.2.dist-info}/WHEEL +0 -0
- {kekikstream-1.7.1.dist-info → kekikstream-2.0.2.dist-info}/entry_points.txt +0 -0
- {kekikstream-1.7.1.dist-info → kekikstream-2.0.2.dist-info}/licenses/LICENSE +0 -0
- {kekikstream-1.7.1.dist-info → kekikstream-2.0.2.dist-info}/top_level.txt +0 -0
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
|
+
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, ExtractResult, Subtitle
|
|
4
|
+
from parsel import Selector
|
|
5
|
+
import re
|
|
6
|
+
|
|
7
|
+
class SuperFilmGeldi(PluginBase):
|
|
8
|
+
name = "SuperFilmGeldi"
|
|
9
|
+
language = "tr"
|
|
10
|
+
main_url = "https://www.superfilmgeldi13.art"
|
|
11
|
+
favicon = f"https://www.google.com/s2/favicons?domain={main_url}&sz=64"
|
|
12
|
+
description = "Ücretsiz film izleme sitesi."
|
|
13
|
+
|
|
14
|
+
main_page = {
|
|
15
|
+
f"{main_url}/page/SAYFA" : "Son Eklenenler",
|
|
16
|
+
f"{main_url}/hdizle/category/aksiyon/page/SAYFA" : "Aksiyon",
|
|
17
|
+
f"{main_url}/hdizle/category/animasyon/page/SAYFA" : "Animasyon",
|
|
18
|
+
f"{main_url}/hdizle/category/belgesel/page/SAYFA" : "Belgesel",
|
|
19
|
+
f"{main_url}/hdizle/category/bilim-kurgu/page/SAYFA" : "Bilim Kurgu",
|
|
20
|
+
f"{main_url}/hdizle/category/fantastik/page/SAYFA" : "Fantastik",
|
|
21
|
+
f"{main_url}/hdizle/category/komedi-filmleri/page/SAYFA" : "Komedi Filmleri",
|
|
22
|
+
f"{main_url}/hdizle/category/macera/page/SAYFA" : "Macera",
|
|
23
|
+
f"{main_url}/hdizle/category/gerilim/page/SAYFA" : "Gerilim",
|
|
24
|
+
f"{main_url}/hdizle/category/suc/page/SAYFA" : "Suç",
|
|
25
|
+
f"{main_url}/hdizle/category/karete-filmleri/page/SAYFA" : "Karate Filmleri",
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
29
|
+
istek = await self.httpx.get(url.replace("SAYFA", str(page)))
|
|
30
|
+
secici = Selector(istek.text)
|
|
31
|
+
|
|
32
|
+
return [
|
|
33
|
+
MainPageResult(
|
|
34
|
+
category = category,
|
|
35
|
+
title = self.clean_title(veri.css("span.movie-title a::text").get().split(" izle")[0]),
|
|
36
|
+
url = self.fix_url(veri.css("span.movie-title a::attr(href)").get()),
|
|
37
|
+
poster = self.fix_url(veri.css("img::attr(src)").get()),
|
|
38
|
+
)
|
|
39
|
+
for veri in secici.css("div.movie-preview-content")
|
|
40
|
+
if veri.css("span.movie-title a::text").get()
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
async def search(self, query: str) -> list[SearchResult]:
|
|
44
|
+
istek = await self.httpx.get(f"{self.main_url}?s={query}")
|
|
45
|
+
secici = Selector(istek.text)
|
|
46
|
+
|
|
47
|
+
return [
|
|
48
|
+
SearchResult(
|
|
49
|
+
title = self.clean_title(veri.css("span.movie-title a::text").get().split(" izle")[0]),
|
|
50
|
+
url = self.fix_url(veri.css("span.movie-title a::attr(href)").get()),
|
|
51
|
+
poster = self.fix_url(veri.css("img::attr(src)").get()),
|
|
52
|
+
)
|
|
53
|
+
for veri in secici.css("div.movie-preview-content")
|
|
54
|
+
if veri.css("span.movie-title a::text").get()
|
|
55
|
+
]
|
|
56
|
+
|
|
57
|
+
async def load_item(self, url: str) -> MovieInfo:
|
|
58
|
+
istek = await self.httpx.get(url)
|
|
59
|
+
secici = Selector(istek.text)
|
|
60
|
+
|
|
61
|
+
title = secici.css("div.title h1::text").get()
|
|
62
|
+
title = self.clean_title(title.split(" izle")[0]) if title else ""
|
|
63
|
+
poster = self.fix_url(secici.css("div.poster img::attr(src)").get())
|
|
64
|
+
year = secici.css("div.release a::text").re_first(r"(\d{4})")
|
|
65
|
+
description = secici.css("div.excerpt p::text").get()
|
|
66
|
+
tags = secici.css("div.categories a::text").getall()
|
|
67
|
+
actors = secici.css("div.actor a::text").getall()
|
|
68
|
+
|
|
69
|
+
return MovieInfo(
|
|
70
|
+
url = url,
|
|
71
|
+
poster = poster,
|
|
72
|
+
title = title,
|
|
73
|
+
description = description,
|
|
74
|
+
tags = tags,
|
|
75
|
+
year = year,
|
|
76
|
+
actors = actors,
|
|
77
|
+
)
|
|
78
|
+
|
|
79
|
+
async def load_links(self, url: str) -> list[dict]:
|
|
80
|
+
istek = await self.httpx.get(url)
|
|
81
|
+
secici = Selector(istek.text)
|
|
82
|
+
|
|
83
|
+
iframe = self.fix_url(secici.css("div#vast iframe::attr(src)").get())
|
|
84
|
+
if not iframe:
|
|
85
|
+
return []
|
|
86
|
+
|
|
87
|
+
results = []
|
|
88
|
+
|
|
89
|
+
# Mix player özel işleme
|
|
90
|
+
if "mix" in iframe and "index.php?data=" in iframe:
|
|
91
|
+
iframe_istek = await self.httpx.get(iframe, headers={"Referer": f"{self.main_url}/"})
|
|
92
|
+
mix_point = re.search(r'videoUrl":"(.*)","videoServer', iframe_istek.text)
|
|
93
|
+
|
|
94
|
+
if mix_point:
|
|
95
|
+
mix_point = mix_point[1].replace("\\", "")
|
|
96
|
+
|
|
97
|
+
# Endpoint belirleme
|
|
98
|
+
if "mixlion" in iframe:
|
|
99
|
+
end_point = "?s=3&d="
|
|
100
|
+
elif "mixeagle" in iframe:
|
|
101
|
+
end_point = "?s=1&d="
|
|
102
|
+
else:
|
|
103
|
+
end_point = "?s=0&d="
|
|
104
|
+
|
|
105
|
+
m3u_link = iframe.split("/player")[0] + mix_point + end_point
|
|
106
|
+
|
|
107
|
+
results.append({
|
|
108
|
+
"name" : f"{self.name} | Mix Player",
|
|
109
|
+
"url" : m3u_link,
|
|
110
|
+
"referer" : iframe,
|
|
111
|
+
"subtitles" : []
|
|
112
|
+
})
|
|
113
|
+
else:
|
|
114
|
+
extractor = self.ex_manager.find_extractor(iframe)
|
|
115
|
+
results.append({
|
|
116
|
+
"name" : extractor.name if extractor else "Player",
|
|
117
|
+
"url" : iframe,
|
|
118
|
+
"referer" : f"{self.main_url}/"
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
return results
|
KekikStream/Plugins/UgurFilm.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
|
2
2
|
|
|
3
|
-
from KekikStream.Core import
|
|
3
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo
|
|
4
4
|
from parsel import Selector
|
|
5
5
|
|
|
6
6
|
class UgurFilm(PluginBase):
|
|
@@ -23,9 +23,8 @@ class UgurFilm(PluginBase):
|
|
|
23
23
|
f"{main_url}/category/erotik/page/" : "Erotik"
|
|
24
24
|
}
|
|
25
25
|
|
|
26
|
-
#@kekik_cache(ttl=60*60)
|
|
27
26
|
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
28
|
-
istek = await self.
|
|
27
|
+
istek = await self.httpx.get(f"{url}{page}", follow_redirects=True)
|
|
29
28
|
secici = Selector(istek.text)
|
|
30
29
|
|
|
31
30
|
return [
|
|
@@ -38,9 +37,8 @@ class UgurFilm(PluginBase):
|
|
|
38
37
|
for veri in secici.css("div.icerik div") if veri.css("span:nth-child(1)::text").get()
|
|
39
38
|
]
|
|
40
39
|
|
|
41
|
-
#@kekik_cache(ttl=60*60)
|
|
42
40
|
async def search(self, query: str) -> list[SearchResult]:
|
|
43
|
-
istek = await self.
|
|
41
|
+
istek = await self.httpx.get(f"{self.main_url}/?s={query}")
|
|
44
42
|
secici = Selector(istek.text)
|
|
45
43
|
|
|
46
44
|
results = []
|
|
@@ -60,9 +58,8 @@ class UgurFilm(PluginBase):
|
|
|
60
58
|
|
|
61
59
|
return results
|
|
62
60
|
|
|
63
|
-
#@kekik_cache(ttl=60*60)
|
|
64
61
|
async def load_item(self, url: str) -> MovieInfo:
|
|
65
|
-
istek = await self.
|
|
62
|
+
istek = await self.httpx.get(url)
|
|
66
63
|
secici = Selector(istek.text)
|
|
67
64
|
|
|
68
65
|
title = secici.css("div.bilgi h2::text").get().strip()
|
|
@@ -82,14 +79,13 @@ class UgurFilm(PluginBase):
|
|
|
82
79
|
actors = actors,
|
|
83
80
|
)
|
|
84
81
|
|
|
85
|
-
#@kekik_cache(ttl=15*60)
|
|
86
82
|
async def load_links(self, url: str) -> list[dict]:
|
|
87
|
-
istek = await self.
|
|
83
|
+
istek = await self.httpx.get(url)
|
|
88
84
|
secici = Selector(istek.text)
|
|
89
85
|
results = []
|
|
90
86
|
|
|
91
87
|
for idx, part_link in enumerate(secici.css("li.parttab a::attr(href)").getall()):
|
|
92
|
-
sub_response = await self.
|
|
88
|
+
sub_response = await self.httpx.get(part_link)
|
|
93
89
|
sub_selector = Selector(sub_response.text)
|
|
94
90
|
|
|
95
91
|
iframe = sub_selector.css("div#vast iframe::attr(src)").get()
|
|
@@ -99,7 +95,7 @@ class UgurFilm(PluginBase):
|
|
|
99
95
|
"alternative" : "vidmoly",
|
|
100
96
|
"ord" : "0",
|
|
101
97
|
}
|
|
102
|
-
player_response = await self.
|
|
98
|
+
player_response = await self.httpx.post(
|
|
103
99
|
url = f"{self.main_url}/player/ajax_sources.php",
|
|
104
100
|
data = post_data
|
|
105
101
|
)
|
KekikStream/__init__.py
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from .CLI import konsol, cikis_yap, hata_yakala, pypi_kontrol_guncelle
|
|
4
4
|
from .Core import PluginManager, ExtractorManager, UIManager, MediaManager, PluginBase, ExtractorBase, SeriesInfo
|
|
5
|
-
from asyncio import run
|
|
5
|
+
from asyncio import run, TaskGroup, Semaphore
|
|
6
6
|
from contextlib import suppress
|
|
7
7
|
|
|
8
8
|
class KekikStream:
|
|
@@ -90,21 +90,34 @@ class KekikStream:
|
|
|
90
90
|
|
|
91
91
|
query = await self.ui.prompt_text("Arama sorgusu:")
|
|
92
92
|
all_results = []
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
93
|
+
|
|
94
|
+
# Maksimum 5 eşzamanlı arama için semaphore
|
|
95
|
+
semaphore = Semaphore(5)
|
|
96
|
+
|
|
97
|
+
async def search_plugin(name: str, plugin: PluginBase):
|
|
98
|
+
"""Tek bir plugin'de ara (semaphore ile sınırlandırılmış)"""
|
|
99
|
+
async with semaphore:
|
|
100
|
+
konsol.log(f"[yellow][~] {name:<19} aranıyor...[/]")
|
|
101
|
+
try:
|
|
102
|
+
results = await plugin.search(query)
|
|
103
|
+
if results:
|
|
104
|
+
return [
|
|
105
|
+
{"plugin": name, "title": r.title, "url": r.url, "poster": r.poster}
|
|
106
|
+
for r in results
|
|
107
|
+
]
|
|
108
|
+
except Exception as e:
|
|
109
|
+
konsol.print(f"[bold red]{name} hatası: {e}[/bold red]")
|
|
110
|
+
return []
|
|
111
|
+
|
|
112
|
+
# Tüm plugin'leri paralel olarak ara
|
|
113
|
+
async with TaskGroup() as tg:
|
|
114
|
+
tasks = []
|
|
115
|
+
for name, plugin in self.plugin.plugins.items():
|
|
116
|
+
tasks.append(tg.create_task(search_plugin(name, plugin)))
|
|
117
|
+
|
|
118
|
+
# Sonuçları topla
|
|
119
|
+
for task in tasks:
|
|
120
|
+
all_results.extend(task.result())
|
|
108
121
|
|
|
109
122
|
if not all_results:
|
|
110
123
|
return await self.handle_no_results()
|
|
@@ -255,10 +268,11 @@ class KekikStream:
|
|
|
255
268
|
self.update_title(selected.get("name"))
|
|
256
269
|
|
|
257
270
|
await self.current_plugin.play(
|
|
258
|
-
name
|
|
259
|
-
url
|
|
260
|
-
|
|
261
|
-
|
|
271
|
+
name = self.media.get_title(),
|
|
272
|
+
url = selected.get("url"),
|
|
273
|
+
user_agent = selected.get("user_agent"),
|
|
274
|
+
referer = selected.get("referer"),
|
|
275
|
+
subtitles = selected.get("subtitles", [])
|
|
262
276
|
)
|
|
263
277
|
return await self.content_finished()
|
|
264
278
|
|
|
@@ -306,10 +320,6 @@ class KekikStream:
|
|
|
306
320
|
self.update_title(selected.get("name"))
|
|
307
321
|
self.update_title(extract_data.name)
|
|
308
322
|
|
|
309
|
-
self.media.set_headers(extract_data.headers)
|
|
310
|
-
if extract_data.referer and not extract_data.headers.get("Referer"):
|
|
311
|
-
self.media.set_headers({"Referer": extract_data.referer})
|
|
312
|
-
|
|
313
323
|
self.media.play_media(extract_data)
|
|
314
324
|
await self.content_finished()
|
|
315
325
|
|
KekikStream/requirements.txt
CHANGED
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: KekikStream
|
|
3
|
+
Version: 2.0.2
|
|
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
|
+
Home-page: https://github.com/keyiflerolsun/KekikStream
|
|
6
|
+
Author: keyiflerolsun
|
|
7
|
+
Author-email: keyiflerolsun@gmail.com
|
|
8
|
+
License: GPLv3+
|
|
9
|
+
Keywords: KekikStream,KekikAkademi,keyiflerolsun
|
|
10
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
11
|
+
Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Requires-Python: >=3.11
|
|
14
|
+
Description-Content-Type: text/markdown
|
|
15
|
+
License-File: LICENSE
|
|
16
|
+
Requires-Dist: setuptools
|
|
17
|
+
Requires-Dist: wheel
|
|
18
|
+
Requires-Dist: Kekik
|
|
19
|
+
Requires-Dist: httpx
|
|
20
|
+
Requires-Dist: cloudscraper
|
|
21
|
+
Requires-Dist: parsel
|
|
22
|
+
Requires-Dist: pydantic
|
|
23
|
+
Requires-Dist: InquirerPy
|
|
24
|
+
Requires-Dist: yt-dlp
|
|
25
|
+
Dynamic: author
|
|
26
|
+
Dynamic: author-email
|
|
27
|
+
Dynamic: classifier
|
|
28
|
+
Dynamic: description
|
|
29
|
+
Dynamic: description-content-type
|
|
30
|
+
Dynamic: home-page
|
|
31
|
+
Dynamic: keywords
|
|
32
|
+
Dynamic: license
|
|
33
|
+
Dynamic: license-file
|
|
34
|
+
Dynamic: requires-dist
|
|
35
|
+
Dynamic: requires-python
|
|
36
|
+
Dynamic: summary
|
|
37
|
+
|
|
38
|
+
# <img src="https://github.com/keyiflerolsun/KekikStream/raw/master/.github/icons/KekikStream.png?raw=True" height="32" align="center"> KekikStream
|
|
39
|
+
|
|
40
|
+
[](#)
|
|
41
|
+
[](#)
|
|
42
|
+
<a href="https://KekikAkademi.org/Kahve" target="_blank"><img src="https://img.shields.io/badge/☕️-Kahve Ismarla-ffdd00" title="☕️ Kahve Ismarla" style="padding-left:5px;"></a>
|
|
43
|
+
|
|
44
|
+
[](https://pypi.org/project/KekikStream)
|
|
45
|
+
[](https://pypi.org/project/KekikStream)
|
|
46
|
+
[](https://pypi.org/project/KekikStream)
|
|
47
|
+
|
|
48
|
+
[](#)
|
|
49
|
+
[](#)
|
|
50
|
+
[](#)
|
|
51
|
+
|
|
52
|
+
[](https://github.com/keyiflerolsun/KekikStream/actions/workflows/pypiYukle.yml)
|
|
53
|
+
|
|
54
|
+
**Modüler ve genişletilebilir medya streaming kütüphanesi**
|
|
55
|
+
Terminal üzerinden içerik arayın, VLC/MPV ile doğrudan izleyin veya kendi API’nizi kurun. 🚀
|
|
56
|
+
|
|
57
|
+
[](https://github.com/user-attachments/assets/63d31bb0-0b69-40b4-84aa-66623f2a253f)
|
|
58
|
+
|
|
59
|
+
[](https://www.python.org/)
|
|
60
|
+
[](https://GitHub.com/keyiflerolsun/)
|
|
61
|
+
|
|
62
|
+
---
|
|
63
|
+
|
|
64
|
+
## 🚦 Ne Sunar?
|
|
65
|
+
|
|
66
|
+
KekikStream, Türkçe medya kaynaklarını tek CLI arayüzünde toplayarak hızlı arama ve oynatma sunar. Plugin mimarisi sayesinde yeni kaynaklar eklemek ve [KekikStreamAPI](https://github.com/keyiflerolsun/KekikStreamAPI) ile web/API üzerinden yayın yapmak kolaydır.
|
|
67
|
+
|
|
68
|
+
- 🎥 Çoklu kaynak desteği: Onlarca Türkçe medya sitesi
|
|
69
|
+
- 🔌 Plugin mimarisi: Yeni kaynak eklemek dakikalar sürer
|
|
70
|
+
- 🎬 Çoklu oynatıcı: VLC, MPV, MX Player
|
|
71
|
+
- 🖥️ CLI & kütüphane: Terminalde veya kod içinde kullanın
|
|
72
|
+
- 🌐 API/Web UI: KekikStreamAPI üzerinden uzak erişim
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## 🚀 Hızlı Başlangıç
|
|
77
|
+
|
|
78
|
+
> Gereksinimler: Python 3.11+, sistemde VLC veya MPV kurulu olmalı (Android için MX Player + ADB).
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
# Kurulum
|
|
82
|
+
pip install KekikStream
|
|
83
|
+
|
|
84
|
+
# Güncelleme
|
|
85
|
+
pip install -U KekikStream
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Temel Kullanım
|
|
89
|
+
|
|
90
|
+
**CLI:**
|
|
91
|
+
```bash
|
|
92
|
+
KekikStream
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
---
|
|
96
|
+
|
|
97
|
+
## ✨ Özellikler
|
|
98
|
+
|
|
99
|
+
### 🔌 Plugin Sistemi
|
|
100
|
+
|
|
101
|
+
KekikStream modüler bir plugin mimarisi kullanır; her medya kaynağı bağımsız bir plugin'dir.
|
|
102
|
+
|
|
103
|
+
**Mevcut Pluginler (örnek):** Dizilla, HDFilmCehennemi, Dizipal, Dizifon, RoketDizi, Sinefy, Moviesseed, FullHDFilmizlesene, HDBestMovies, SuperFilmGeldi, Sinezy ve daha fazlası.
|
|
104
|
+
|
|
105
|
+
**Plugin Geliştirme:**
|
|
106
|
+
```python
|
|
107
|
+
from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, SeriesInfo
|
|
108
|
+
|
|
109
|
+
class MyPlugin(PluginBase):
|
|
110
|
+
name = "MyPlugin"
|
|
111
|
+
language = "en"
|
|
112
|
+
main_url = "https://example.com"
|
|
113
|
+
favicon = f"https://www.google.com/s2/favicons?domain={main_url}&sz=64"
|
|
114
|
+
description = "MyPlugin description"
|
|
115
|
+
|
|
116
|
+
main_page = {
|
|
117
|
+
f"{main_url}/category/" : "Category Name"
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
async def get_main_page(self, page: int, url: str, category: str) -> list[MainPageResult]:
|
|
121
|
+
return results
|
|
122
|
+
|
|
123
|
+
async def search(self, query: str) -> list[SearchResult]:
|
|
124
|
+
return results
|
|
125
|
+
|
|
126
|
+
async def load_item(self, url: str) -> MovieInfo | SeriesInfo:
|
|
127
|
+
return details
|
|
128
|
+
|
|
129
|
+
async def load_links(self, url: str) -> list[dict]:
|
|
130
|
+
return links
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
### 🎬 Oynatıcı Desteği
|
|
134
|
+
|
|
135
|
+
| Oynatıcı | Platform | Özellikler |
|
|
136
|
+
|---------------|----------|---------------------------|
|
|
137
|
+
| **MPV** | Desktop | Custom headers, subtitles |
|
|
138
|
+
| **VLC** | Desktop | Custom headers, subtitles |
|
|
139
|
+
| **MX Player** | Android | ADB üzerinden |
|
|
140
|
+
|
|
141
|
+
> Özel durumlar için (Google Drive vb.) arka planda otomatik olarak yt-dlp devreye girer.
|
|
142
|
+
|
|
143
|
+
### 🔗 Extractor Sistemi
|
|
144
|
+
|
|
145
|
+
Vidmoly, Filemoon, Sibnet, Sendvid, Voe, Doodstream, Streamtape, Upstream, Dailymotion, JWPlayer ve birçok kaynaktan direkt streaming linki çıkarır.
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## 🏗️ Mimari
|
|
150
|
+
|
|
151
|
+
```mermaid
|
|
152
|
+
graph TB
|
|
153
|
+
CLI[🖥️ CLI Interface]
|
|
154
|
+
Manager[🔌 Plugin Manager]
|
|
155
|
+
|
|
156
|
+
subgraph Plugins
|
|
157
|
+
P1[📺 Dizilla]
|
|
158
|
+
P2[🎬 HDFilmCehennemi]
|
|
159
|
+
P3[🍿 Dizipal]
|
|
160
|
+
PN[... 20+ Plugin]
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
subgraph Extractors
|
|
164
|
+
E1[🔗 Vidmoly]
|
|
165
|
+
E2[🔗 Filemoon]
|
|
166
|
+
E3[🔗 Sibnet]
|
|
167
|
+
EN[... Extractors]
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
subgraph Players
|
|
171
|
+
MPV[🎥 MPV]
|
|
172
|
+
VLC[🎥 VLC]
|
|
173
|
+
MX[🎥 MX Player]
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
CLI --> Manager
|
|
177
|
+
Manager --> P1
|
|
178
|
+
Manager --> P2
|
|
179
|
+
Manager --> P3
|
|
180
|
+
Manager --> PN
|
|
181
|
+
|
|
182
|
+
%% Her plugin otomatik olarak ihtiyaç duyduğu extractor'ı kullanır
|
|
183
|
+
P1 -.-> E1
|
|
184
|
+
P1 -.-> E2
|
|
185
|
+
P1 -.-> E3
|
|
186
|
+
|
|
187
|
+
P2 -.-> E1
|
|
188
|
+
P2 -.-> E2
|
|
189
|
+
P2 -.-> E3
|
|
190
|
+
|
|
191
|
+
P3 -.-> E1
|
|
192
|
+
P3 -.-> E2
|
|
193
|
+
P3 -.-> E3
|
|
194
|
+
|
|
195
|
+
PN -.-> EN
|
|
196
|
+
|
|
197
|
+
E1 --> VLC
|
|
198
|
+
E2 --> VLC
|
|
199
|
+
E3 --> VLC
|
|
200
|
+
EN --> VLC
|
|
201
|
+
|
|
202
|
+
E1 --> MPV
|
|
203
|
+
E2 --> MPV
|
|
204
|
+
E3 --> MPV
|
|
205
|
+
EN --> MPV
|
|
206
|
+
|
|
207
|
+
E1 --> MX
|
|
208
|
+
E2 --> MX
|
|
209
|
+
E3 --> MX
|
|
210
|
+
EN --> MX
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## 🛠️ Geliştirme
|
|
216
|
+
|
|
217
|
+
### Proje Yapısı
|
|
218
|
+
|
|
219
|
+
```
|
|
220
|
+
KekikStream/
|
|
221
|
+
├── KekikStream/
|
|
222
|
+
│ ├── Core/ # Temel sınıflar
|
|
223
|
+
│ ├── Libs/ # Yardımcı kütüphaneler
|
|
224
|
+
│ ├── Plugins/ # Medya kaynak pluginleri
|
|
225
|
+
│ ├── Extractors/ # Video extractorları
|
|
226
|
+
│ └── __init__.py # CLI entry point
|
|
227
|
+
├── Tests/ # Örnek kullanım
|
|
228
|
+
└── requirements.txt
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
### Yeni Plugin Ekleme
|
|
232
|
+
|
|
233
|
+
1. `KekikStream/Plugins/` altına yeni dosya oluşturun.
|
|
234
|
+
2. `PluginBase` sınıfından türetin.
|
|
235
|
+
3. `get_main_page`, `search`, `load_item`, `load_links` metodlarını implemente edin.
|
|
236
|
+
4. Plugin'i test edin (örnek: `Tests/Single.py`).
|
|
237
|
+
|
|
238
|
+
### 🔧 Geliştirme Modu
|
|
239
|
+
|
|
240
|
+
KekikStream, eklenti geliştiricileri için otomatik bir **geliştirme modu** sunar:
|
|
241
|
+
|
|
242
|
+
**Plugin Geliştirme:**
|
|
243
|
+
- Çalışma dizininde `Plugins/` klasörü oluşturup içine plugin dosyası eklerseniz, **sadece bu local plugin'ler** yüklenir
|
|
244
|
+
- Global plugin'ler (sisteme kurulu olanlar) otomatik olarak atlanır
|
|
245
|
+
- Bu sayede test sırasında diğer plugin'lerle karışma olmaz
|
|
246
|
+
|
|
247
|
+
**Extractor Geliştirme:**
|
|
248
|
+
- Çalışma dizininde `Extractors/` klasörü oluşturup içine extractor dosyası eklerseniz, **sadece bu local extractor'lar** yüklenir
|
|
249
|
+
- Global extractor'lar otomatik olarak atlanır
|
|
250
|
+
- Kendi extractor'ınızı izole bir ortamda test edebilirsiniz
|
|
251
|
+
|
|
252
|
+
**Örnek:**
|
|
253
|
+
```bash
|
|
254
|
+
# Çalışma dizininizde
|
|
255
|
+
mkdir Plugins
|
|
256
|
+
touch Plugins/MyTestPlugin.py # Plugin'inizi yazın
|
|
257
|
+
|
|
258
|
+
# KekikStream'i çalıştırın - sadece MyTestPlugin yüklenecek
|
|
259
|
+
KekikStream
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
> 💡 **Not:** Yerel dizinde herhangi bir Plugin/Extractor dosyası bulunmazsa, sistem normal şekilde global olanları yükler.
|
|
263
|
+
|
|
264
|
+
---
|
|
265
|
+
|
|
266
|
+
## 📊 Performans
|
|
267
|
+
|
|
268
|
+
| Metrik | Değer |
|
|
269
|
+
|----------------------|------------------|
|
|
270
|
+
| Plugin Sayısı | 20+ |
|
|
271
|
+
| Extractor Sayısı | 40+ |
|
|
272
|
+
| Desteklenen Platform | Desktop, Android |
|
|
273
|
+
| Async Arama | ✅ |
|
|
274
|
+
| Cache Desteği | ✅ |
|
|
275
|
+
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## 🤝 Katkıda Bulunma
|
|
279
|
+
|
|
280
|
+
Projeyi geliştirmek için katkılarınızı bekliyoruz!
|
|
281
|
+
|
|
282
|
+
1. Yeni plugin ekleyin
|
|
283
|
+
2. Bug raporu açın
|
|
284
|
+
3. Feature request gönderin
|
|
285
|
+
4. Dokümantasyon iyileştirin
|
|
286
|
+
|
|
287
|
+
### 🎁 Teşekkürler
|
|
288
|
+
|
|
289
|
+
- [DeoDorqnt387/aniwatch-tr](https://github.com/DeoDorqnt387/aniwatch-tr)
|
|
290
|
+
|
|
291
|
+
### 💻 Genişletme Referansları
|
|
292
|
+
|
|
293
|
+
- [keyiflerolsun/Kekik-cloudstream](https://github.com/keyiflerolsun/Kekik-cloudstream)
|
|
294
|
+
- [keyiflerolsun/seyirTurk-Parser](https://github.com/keyiflerolsun/seyirTurk-Parser)
|
|
295
|
+
|
|
296
|
+
## 🌐 Telif Hakkı ve Lisans
|
|
297
|
+
|
|
298
|
+
*Copyright (C) 2024 by* [keyiflerolsun](https://github.com/keyiflerolsun) ❤️️
|
|
299
|
+
[GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007](https://github.com/keyiflerolsun/KekikStream/blob/master/LICENSE) *Koşullarına göre lisanslanmıştır..*
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
<p align="center">
|
|
304
|
+
Bu proje <a href="https://github.com/keyiflerolsun">@keyiflerolsun</a> tarafından <a href="https://t.me/KekikAkademi">@KekikAkademi</a> için geliştirilmiştir.
|
|
305
|
+
</p>
|
|
306
|
+
|
|
307
|
+
<p align="center">
|
|
308
|
+
<sub>⭐ Beğendiyseniz yıldız vermeyi unutmayın!</sub>
|
|
309
|
+
</p>
|