KekikStream 0.0.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- KekikStream/CLI/__init__.py +3 -0
- KekikStream/Core/ExtractorBase.py +31 -0
- KekikStream/Core/ExtractorLoader.py +61 -0
- KekikStream/Core/ExtractorModels.py +17 -0
- KekikStream/Core/MediaHandler.py +58 -0
- KekikStream/Core/PluginBase.py +42 -0
- KekikStream/Core/PluginLoader.py +63 -0
- KekikStream/Core/PluginModels.py +32 -0
- KekikStream/Core/__init__.py +9 -0
- KekikStream/Extractors/CloseLoad.py +32 -0
- KekikStream/Extractors/MailRu.py +42 -0
- KekikStream/Extractors/VidMoxy.py +35 -0
- KekikStream/Managers/ExtractorManager.py +27 -0
- KekikStream/Managers/MediaManager.py +19 -0
- KekikStream/Managers/PluginManager.py +18 -0
- KekikStream/Managers/UIManager.py +32 -0
- KekikStream/Managers/__init__.py +6 -0
- KekikStream/Plugins/FilmMakinesi.py +65 -0
- KekikStream/Plugins/FullHDFilmizlesene.py +77 -0
- KekikStream/Plugins/UgurFilm.py +75 -0
- KekikStream/__init__.py +124 -0
- KekikStream/__main__.py +6 -0
- KekikStream/requirements.txt +9 -0
- KekikStream-0.0.3.dist-info/LICENSE +674 -0
- KekikStream-0.0.3.dist-info/METADATA +76 -0
- KekikStream-0.0.3.dist-info/RECORD +29 -0
- KekikStream-0.0.3.dist-info/WHEEL +5 -0
- KekikStream-0.0.3.dist-info/entry_points.txt +2 -0
- KekikStream-0.0.3.dist-info/top_level.txt +1 -0
@@ -0,0 +1,77 @@
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
2
|
+
|
3
|
+
from KekikStream.CLI import konsol
|
4
|
+
from KekikStream.Core import PluginBase, SearchResult, MovieInfo
|
5
|
+
from parsel import Selector
|
6
|
+
from Kekik.Sifreleme import StringCodec
|
7
|
+
import json, re
|
8
|
+
|
9
|
+
class FullHDFilmizlesene(PluginBase):
|
10
|
+
name = "FullHDFilmizlesene"
|
11
|
+
main_url = "https://www.fullhdfilmizlesene.de"
|
12
|
+
|
13
|
+
async def search(self, query: str) -> list[SearchResult]:
|
14
|
+
istek = await self.oturum.get(f"{self.main_url}/arama/{query}")
|
15
|
+
secici = Selector(istek.text)
|
16
|
+
|
17
|
+
results = []
|
18
|
+
for film in secici.css("li.film"):
|
19
|
+
title = film.css("span.film-title::text").get()
|
20
|
+
href = film.css("a::attr(href)").get()
|
21
|
+
poster = film.css("img::attr(data-src)").get()
|
22
|
+
|
23
|
+
if title and href:
|
24
|
+
results.append(
|
25
|
+
SearchResult(
|
26
|
+
title = title.strip(),
|
27
|
+
url = self.fix_url(href.strip()),
|
28
|
+
poster = self.fix_url(poster.strip()) if poster else None,
|
29
|
+
)
|
30
|
+
)
|
31
|
+
|
32
|
+
return results
|
33
|
+
|
34
|
+
async def load_item(self, url: str) -> MovieInfo:
|
35
|
+
istek = await self.oturum.get(url)
|
36
|
+
secici = Selector(istek.text)
|
37
|
+
|
38
|
+
title = secici.xpath("normalize-space(//div[@class='izle-titles'])").get().strip()
|
39
|
+
poster = secici.css("div img::attr(data-src)").get().strip()
|
40
|
+
description = secici.css("div.ozet-ic p::text").get().strip()
|
41
|
+
tags = secici.css("a[rel='category tag']::text").getall()
|
42
|
+
rating = secici.xpath("normalize-space(//div[@class='puanx-puan'])").get().split()[-1]
|
43
|
+
year = secici.css("div.dd a.category::text").get().strip().split()[0]
|
44
|
+
actors = secici.css("div.film-info ul li:nth-child(2) a > span::text").getall()
|
45
|
+
duration = secici.css("span.sure::text").get("0 Dakika").split()[0]
|
46
|
+
|
47
|
+
return MovieInfo(
|
48
|
+
url = url,
|
49
|
+
poster = self.fix_url(poster),
|
50
|
+
title = title,
|
51
|
+
description = description,
|
52
|
+
tags = tags,
|
53
|
+
rating = rating,
|
54
|
+
year = year,
|
55
|
+
actors = actors,
|
56
|
+
duration = duration
|
57
|
+
)
|
58
|
+
|
59
|
+
async def load_links(self, url: str) -> list[str]:
|
60
|
+
istek = await self.oturum.get(url)
|
61
|
+
secici = Selector(istek.text)
|
62
|
+
|
63
|
+
script = secici.xpath("(//script)[1]").get()
|
64
|
+
scx_data = json.loads(re.findall(r'scx = (.*?);', script)[0])
|
65
|
+
scx_keys = list(scx_data.keys())
|
66
|
+
|
67
|
+
link_list = []
|
68
|
+
for key in scx_keys:
|
69
|
+
t = scx_data[key]["sx"]["t"]
|
70
|
+
if isinstance(t, list):
|
71
|
+
link_list.extend(StringCodec.decode(elem) for elem in t)
|
72
|
+
if isinstance(t, dict):
|
73
|
+
link_list.extend(StringCodec.decode(v) for k, v in t.items())
|
74
|
+
|
75
|
+
link_list = [f"https:{link}" if link.startswith('//') else link for link in link_list]
|
76
|
+
# konsol.print(link_list)
|
77
|
+
return link_list
|
@@ -0,0 +1,75 @@
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
2
|
+
|
3
|
+
from KekikStream.Core import PluginBase, SearchResult, MovieInfo
|
4
|
+
from parsel import Selector
|
5
|
+
|
6
|
+
class UgurFilm(PluginBase):
|
7
|
+
name = "UgurFilm"
|
8
|
+
main_url = "https://ugurfilm8.com"
|
9
|
+
|
10
|
+
async def search(self, query: str) -> list[SearchResult]:
|
11
|
+
istek = await self.oturum.get(f"{self.main_url}/?s={query}")
|
12
|
+
secici = Selector(istek.text)
|
13
|
+
|
14
|
+
results = []
|
15
|
+
for film in secici.css("div.icerik div"):
|
16
|
+
title = film.css("span:nth-child(1)::text").get()
|
17
|
+
href = film.css("a::attr(href)").get()
|
18
|
+
poster = film.css("img::attr(src)").get()
|
19
|
+
|
20
|
+
if title and href:
|
21
|
+
results.append(
|
22
|
+
SearchResult(
|
23
|
+
title = title.strip(),
|
24
|
+
url = self.fix_url(href.strip()),
|
25
|
+
poster = self.fix_url(poster.strip()) if poster else None,
|
26
|
+
)
|
27
|
+
)
|
28
|
+
|
29
|
+
return results
|
30
|
+
|
31
|
+
async def load_item(self, url: str) -> MovieInfo:
|
32
|
+
istek = await self.oturum.get(url)
|
33
|
+
secici = Selector(istek.text)
|
34
|
+
|
35
|
+
title = secici.css("div.bilgi h2::text").get(default="").strip()
|
36
|
+
poster = secici.css("div.resim img::attr(src)").get(default="").strip()
|
37
|
+
description = secici.css("div.slayt-aciklama::text").get(default="").strip()
|
38
|
+
tags = secici.css("p.tur a[href*='/category/']::text").getall()
|
39
|
+
year = secici.css("a[href*='/yil/']::text").re_first(r"\d+")
|
40
|
+
actors = [actor.css("span::text").get() for actor in secici.css("li.oyuncu-k")]
|
41
|
+
|
42
|
+
return MovieInfo(
|
43
|
+
url = self.fix_url(url),
|
44
|
+
poster = self.fix_url(poster),
|
45
|
+
title = title,
|
46
|
+
description = description,
|
47
|
+
tags = tags,
|
48
|
+
year = year,
|
49
|
+
actors = actors,
|
50
|
+
)
|
51
|
+
|
52
|
+
async def load_links(self, url: str) -> list[str]:
|
53
|
+
istek = await self.oturum.get(url)
|
54
|
+
secici = Selector(istek.text)
|
55
|
+
results = []
|
56
|
+
|
57
|
+
for part_link in secici.css("li.parttab a::attr(href)").getall():
|
58
|
+
sub_response = await self.oturum.get(part_link)
|
59
|
+
sub_selector = Selector(sub_response.text)
|
60
|
+
|
61
|
+
iframe = sub_selector.css("div#vast iframe::attr(src)").get()
|
62
|
+
if iframe and self.main_url in iframe:
|
63
|
+
post_data = {
|
64
|
+
"vid" : iframe.split("vid=")[-1],
|
65
|
+
"alternative" : "default",
|
66
|
+
"ord" : "1",
|
67
|
+
}
|
68
|
+
player_response = await self.oturum.post(
|
69
|
+
url = f"{self.main_url}/player/ajax_sources.php",
|
70
|
+
data = post_data
|
71
|
+
)
|
72
|
+
iframe = player_response.json().get("iframe")
|
73
|
+
results.append(iframe)
|
74
|
+
|
75
|
+
return results
|
KekikStream/__init__.py
ADDED
@@ -0,0 +1,124 @@
|
|
1
|
+
# Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
|
2
|
+
|
3
|
+
from .CLI import konsol, cikis_yap, hata_yakala
|
4
|
+
from .Managers import PluginManager, ExtractorManager, UIManager, MediaManager
|
5
|
+
from .Core import PluginBase, ExtractorBase
|
6
|
+
from asyncio import run
|
7
|
+
|
8
|
+
class KekikStream:
|
9
|
+
def __init__(self):
|
10
|
+
self.plugin_manager = PluginManager()
|
11
|
+
self.extractor_manager = ExtractorManager()
|
12
|
+
self.ui_manager = UIManager()
|
13
|
+
self.media_manager = MediaManager()
|
14
|
+
self.current_plugin:PluginBase = None
|
15
|
+
|
16
|
+
async def run(self):
|
17
|
+
self.ui_manager.clear_console()
|
18
|
+
konsol.rule("[bold cyan]KekikStream Başlatılıyor[/bold cyan]")
|
19
|
+
if not self.plugin_manager.get_plugin_names():
|
20
|
+
konsol.print("[bold red]Hiçbir eklenti bulunamadı![/bold red]")
|
21
|
+
return
|
22
|
+
|
23
|
+
try:
|
24
|
+
await self.select_plugin()
|
25
|
+
finally:
|
26
|
+
await self.plugin_manager.close_plugins()
|
27
|
+
|
28
|
+
async def select_plugin(self):
|
29
|
+
plugin_name = await self.ui_manager.select_from_list(
|
30
|
+
message = "Bir eklenti seçin:",
|
31
|
+
choices = self.plugin_manager.get_plugin_names()
|
32
|
+
)
|
33
|
+
|
34
|
+
self.current_plugin = self.plugin_manager.select_plugin(plugin_name)
|
35
|
+
|
36
|
+
await self.search()
|
37
|
+
|
38
|
+
async def search(self):
|
39
|
+
self.ui_manager.clear_console()
|
40
|
+
konsol.rule(f"[bold cyan]{self.current_plugin.name} Eklentisinde Arama Yapın[/bold cyan]")
|
41
|
+
|
42
|
+
query = await self.ui_manager.prompt_text("Arama sorgusu girin:")
|
43
|
+
results = await self.current_plugin.search(query)
|
44
|
+
|
45
|
+
if not results:
|
46
|
+
konsol.print("[bold red]Arama sonucu bulunamadı![/bold red]")
|
47
|
+
return
|
48
|
+
|
49
|
+
await self.select_result(results)
|
50
|
+
|
51
|
+
async def select_result(self, results):
|
52
|
+
selected_url = await self.ui_manager.select_from_list(
|
53
|
+
message = "Bir içerik seçin:",
|
54
|
+
choices = [{"name": res.title, "value": res.url} for res in results]
|
55
|
+
)
|
56
|
+
|
57
|
+
await self.show_details(selected_url)
|
58
|
+
|
59
|
+
async def show_details(self, url):
|
60
|
+
try:
|
61
|
+
media_info = await self.current_plugin.load_item(url)
|
62
|
+
except Exception as hata:
|
63
|
+
konsol.log(url)
|
64
|
+
hata_yakala(hata)
|
65
|
+
return
|
66
|
+
|
67
|
+
self.media_manager.set_title(f"{self.current_plugin.name} | {media_info.title}")
|
68
|
+
|
69
|
+
self.ui_manager.display_media_info(self.current_plugin.name, media_info)
|
70
|
+
|
71
|
+
links = await self.current_plugin.load_links(url)
|
72
|
+
await self.show_options(links)
|
73
|
+
|
74
|
+
async def show_options(self, links):
|
75
|
+
mapping = self.extractor_manager.map_links_to_extractors(links)
|
76
|
+
if not mapping:
|
77
|
+
konsol.print("[bold red]Hiçbir Extractor bulunamadı![/bold red]")
|
78
|
+
konsol.print(links)
|
79
|
+
return
|
80
|
+
|
81
|
+
action = await self.ui_manager.select_from_list(
|
82
|
+
message = "Ne yapmak istersiniz?",
|
83
|
+
choices = ["İzle", "Geri Git", "Ana Menü"]
|
84
|
+
)
|
85
|
+
|
86
|
+
match action:
|
87
|
+
case "İzle":
|
88
|
+
selected_link = await self.ui_manager.select_from_list(
|
89
|
+
message = "Bir bağlantı seçin:",
|
90
|
+
choices = [{"name": extractor_name, "value": link} for link, extractor_name in mapping.items()]
|
91
|
+
)
|
92
|
+
if selected_link:
|
93
|
+
await self.play_media(selected_link)
|
94
|
+
|
95
|
+
case "Geri Git":
|
96
|
+
await self.search()
|
97
|
+
|
98
|
+
case _:
|
99
|
+
await self.run()
|
100
|
+
|
101
|
+
async def play_media(self, selected_link):
|
102
|
+
extractor:ExtractorBase = self.extractor_manager.find_extractor(selected_link)
|
103
|
+
if not extractor:
|
104
|
+
konsol.print("[bold red]Uygun Extractor bulunamadı.[/bold red]")
|
105
|
+
return
|
106
|
+
|
107
|
+
extract_data = await extractor.extract(selected_link, referer=self.current_plugin.main_url)
|
108
|
+
if extract_data.headers.get("Cookie"):
|
109
|
+
self.media_manager.set_headers({"Cookie": extract_data.headers.get("Cookie")})
|
110
|
+
|
111
|
+
self.media_manager.set_title(f"{self.media_manager.get_title()} | {extract_data.name}")
|
112
|
+
self.media_manager.set_headers({"Referer": extract_data.referer})
|
113
|
+
self.media_manager.play_media(extract_data)
|
114
|
+
|
115
|
+
|
116
|
+
def basla():
|
117
|
+
try:
|
118
|
+
app = KekikStream()
|
119
|
+
run(app.run())
|
120
|
+
cikis_yap(False)
|
121
|
+
except KeyboardInterrupt:
|
122
|
+
cikis_yap(True)
|
123
|
+
except Exception as hata:
|
124
|
+
hata_yakala(hata)
|
KekikStream/__main__.py
ADDED