KekikStream 1.7.1__py3-none-any.whl → 2.2.0__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.
Files changed (88) hide show
  1. KekikStream/Core/Extractor/ExtractorBase.py +20 -9
  2. KekikStream/Core/Extractor/ExtractorLoader.py +25 -17
  3. KekikStream/Core/Extractor/ExtractorManager.py +53 -9
  4. KekikStream/Core/Extractor/ExtractorModels.py +5 -7
  5. KekikStream/Core/Extractor/YTDLPCache.py +35 -0
  6. KekikStream/Core/Media/MediaHandler.py +44 -26
  7. KekikStream/Core/Media/MediaManager.py +0 -3
  8. KekikStream/Core/Plugin/PluginBase.py +82 -22
  9. KekikStream/Core/Plugin/PluginLoader.py +11 -7
  10. KekikStream/Core/Plugin/PluginModels.py +25 -26
  11. KekikStream/Core/__init__.py +1 -0
  12. KekikStream/Extractors/CloseLoad.py +21 -7
  13. KekikStream/Extractors/ContentX.py +21 -6
  14. KekikStream/Extractors/DonilasPlay.py +86 -0
  15. KekikStream/Extractors/DzenRu.py +38 -0
  16. KekikStream/Extractors/ExPlay.py +53 -0
  17. KekikStream/Extractors/Filemoon.py +78 -0
  18. KekikStream/Extractors/HDPlayerSystem.py +41 -0
  19. KekikStream/Extractors/JetTv.py +45 -0
  20. KekikStream/Extractors/MailRu.py +3 -4
  21. KekikStream/Extractors/MixPlayHD.py +2 -3
  22. KekikStream/Extractors/MixTiger.py +57 -0
  23. KekikStream/Extractors/MolyStream.py +5 -5
  24. KekikStream/Extractors/Odnoklassniki.py +13 -7
  25. KekikStream/Extractors/PeaceMakerst.py +10 -5
  26. KekikStream/Extractors/PixelDrain.py +1 -2
  27. KekikStream/Extractors/PlayerFilmIzle.py +65 -0
  28. KekikStream/Extractors/RapidVid.py +23 -8
  29. KekikStream/Extractors/SetPlay.py +66 -0
  30. KekikStream/Extractors/SetPrime.py +45 -0
  31. KekikStream/Extractors/SibNet.py +2 -3
  32. KekikStream/Extractors/Sobreatsesuyp.py +4 -5
  33. KekikStream/Extractors/TRsTX.py +4 -5
  34. KekikStream/Extractors/TauVideo.py +2 -3
  35. KekikStream/Extractors/TurboImgz.py +2 -3
  36. KekikStream/Extractors/TurkeyPlayer.py +34 -0
  37. KekikStream/Extractors/VCTPlay.py +41 -0
  38. KekikStream/Extractors/VidHide.py +81 -0
  39. KekikStream/Extractors/VidMoly.py +55 -34
  40. KekikStream/Extractors/VidMoxy.py +2 -3
  41. KekikStream/Extractors/VidPapi.py +89 -0
  42. KekikStream/Extractors/VideoSeyred.py +3 -4
  43. KekikStream/Extractors/YTDLP.py +211 -0
  44. KekikStream/Extractors/YildizKisaFilm.py +41 -0
  45. KekikStream/Plugins/BelgeselX.py +196 -0
  46. KekikStream/Plugins/DiziBox.py +25 -34
  47. KekikStream/Plugins/DiziPal.py +24 -35
  48. KekikStream/Plugins/DiziYou.py +54 -37
  49. KekikStream/Plugins/Dizilla.py +66 -46
  50. KekikStream/Plugins/FilmBip.py +142 -0
  51. KekikStream/Plugins/FilmMakinesi.py +36 -28
  52. KekikStream/Plugins/FilmModu.py +20 -24
  53. KekikStream/Plugins/FullHDFilm.py +220 -0
  54. KekikStream/Plugins/FullHDFilmizlesene.py +9 -15
  55. KekikStream/Plugins/HDFilmCehennemi.py +141 -69
  56. KekikStream/Plugins/JetFilmizle.py +85 -52
  57. KekikStream/Plugins/KultFilmler.py +217 -0
  58. KekikStream/Plugins/RecTV.py +22 -34
  59. KekikStream/Plugins/RoketDizi.py +222 -0
  60. KekikStream/Plugins/SelcukFlix.py +328 -0
  61. KekikStream/Plugins/SetFilmIzle.py +252 -0
  62. KekikStream/Plugins/SezonlukDizi.py +54 -21
  63. KekikStream/Plugins/SineWix.py +17 -29
  64. KekikStream/Plugins/Sinefy.py +241 -0
  65. KekikStream/Plugins/SinemaCX.py +154 -0
  66. KekikStream/Plugins/Sinezy.py +143 -0
  67. KekikStream/Plugins/SuperFilmGeldi.py +130 -0
  68. KekikStream/Plugins/UgurFilm.py +13 -19
  69. KekikStream/__init__.py +47 -56
  70. KekikStream/requirements.txt +3 -4
  71. kekikstream-2.2.0.dist-info/METADATA +312 -0
  72. kekikstream-2.2.0.dist-info/RECORD +81 -0
  73. KekikStream/Extractors/FourCX.py +0 -7
  74. KekikStream/Extractors/FourPichive.py +0 -7
  75. KekikStream/Extractors/FourPlayRu.py +0 -7
  76. KekikStream/Extractors/HDStreamAble.py +0 -7
  77. KekikStream/Extractors/Hotlinger.py +0 -7
  78. KekikStream/Extractors/OkRuHTTP.py +0 -7
  79. KekikStream/Extractors/OkRuSSL.py +0 -7
  80. KekikStream/Extractors/Pichive.py +0 -7
  81. KekikStream/Extractors/PlayRu.py +0 -7
  82. KekikStream/Extractors/VidMolyMe.py +0 -7
  83. kekikstream-1.7.1.dist-info/METADATA +0 -109
  84. kekikstream-1.7.1.dist-info/RECORD +0 -63
  85. {kekikstream-1.7.1.dist-info → kekikstream-2.2.0.dist-info}/WHEEL +0 -0
  86. {kekikstream-1.7.1.dist-info → kekikstream-2.2.0.dist-info}/entry_points.txt +0 -0
  87. {kekikstream-1.7.1.dist-info → kekikstream-2.2.0.dist-info}/licenses/LICENSE +0 -0
  88. {kekikstream-1.7.1.dist-info → kekikstream-2.2.0.dist-info}/top_level.txt +0 -0
@@ -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 kekik_cache, PluginBase, MainPageResult, SearchResult, MovieInfo
3
+ from KekikStream.Core import PluginBase, MainPageResult, SearchResult, MovieInfo, ExtractResult
4
4
  from parsel import Selector
5
5
 
6
6
  class UgurFilm(PluginBase):
@@ -8,7 +8,7 @@ class UgurFilm(PluginBase):
8
8
  language = "tr"
9
9
  main_url = "https://ugurfilm3.xyz"
10
10
  favicon = f"https://www.google.com/s2/favicons?domain={main_url}&sz=64"
11
- description = "Yabancı film izle, Türkçe dublaj ve Türkçe altyazılı film seçenekleriyle 720p ve 1080p HD kalitesinde film izle - Uğur Film full hd film izle."
11
+ description = "Uğur Film ile film izle! En yeni ve güncel filmleri, Türk yerli filmleri Full HD 1080p kalitede Türkçe Altyazılı olarak izle."
12
12
 
13
13
  main_page = {
14
14
  f"{main_url}/turkce-altyazili-filmler/page/" : "Türkçe Altyazılı Filmler",
@@ -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.cffi.get(f"{url}{page}", allow_redirects=True)
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.cffi.get(f"{self.main_url}/?s={query}")
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.cffi.get(url)
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
- async def load_links(self, url: str) -> list[dict]:
87
- istek = await self.cffi.get(url)
82
+ async def load_links(self, url: str) -> list[ExtractResult]:
83
+ istek = await self.httpx.get(url)
88
84
  secici = Selector(istek.text)
89
85
  results = []
90
86
 
91
- for idx, part_link in enumerate(secici.css("li.parttab a::attr(href)").getall()):
92
- sub_response = await self.cffi.get(part_link)
87
+ for part_link in secici.css("li.parttab a::attr(href)").getall():
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,15 +95,13 @@ class UgurFilm(PluginBase):
99
95
  "alternative" : "vidmoly",
100
96
  "ord" : "0",
101
97
  }
102
- player_response = await self.cffi.post(
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
  )
106
102
  iframe = self.fix_url(player_response.json().get("iframe"))
107
- extractor = self.ex_manager.find_extractor(iframe)
108
- results.append({
109
- "url" : iframe,
110
- "name" : f"{extractor.name if extractor else f'Part {idx + 1}'}"
111
- })
103
+ data = await self.extract(iframe)
104
+ if data:
105
+ results.append(data)
112
106
 
113
107
  return results
KekikStream/__init__.py CHANGED
@@ -1,8 +1,8 @@
1
1
  # Bu araç @keyiflerolsun tarafından | @KekikAkademi için yazılmıştır.
2
2
 
3
3
  from .CLI import konsol, cikis_yap, hata_yakala, pypi_kontrol_guncelle
4
- from .Core import PluginManager, ExtractorManager, UIManager, MediaManager, PluginBase, ExtractorBase, SeriesInfo
5
- from asyncio import run
4
+ from .Core import PluginManager, ExtractorManager, UIManager, MediaManager, PluginBase, ExtractorBase, SeriesInfo, ExtractResult
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
- for name, plugin in self.plugin.plugins.items():
95
- if not isinstance(plugin, PluginBase) or name == "Shorten":
96
- continue
97
-
98
- konsol.log(f"[yellow][~] {name:<19} aranıyor...[/]")
99
- try:
100
- results = await plugin.search(query)
101
- if results:
102
- all_results.extend([
103
- {"plugin": name, "title": r.title, "url": r.url, "poster": r.poster}
104
- for r in results
105
- ])
106
- except Exception as e:
107
- konsol.print(f"[bold red]{name} hatası: {e}[/bold red]")
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()
@@ -213,60 +226,42 @@ class KekikStream:
213
226
  case "Çıkış":
214
227
  cikis_yap(False)
215
228
 
216
- async def show_link_options(self, links: list[dict]):
229
+ async def show_link_options(self, links: list[ExtractResult]):
217
230
  """Bağlantı seçeneklerini göster"""
218
231
  if not links:
219
232
  konsol.print("[bold red]Bağlantı bulunamadı![/bold red]")
220
233
  return await self.handle_no_results()
221
234
 
222
- # Direkt oynatma varsa
223
- if hasattr(self.current_plugin, "play"):
224
- return await self.play_direct(links)
225
-
226
- # Extractor ile oynat
227
- url_list = [link["url"] for link in links]
228
- mapping = self.extractor.map_links_to_extractors(url_list)
229
-
230
- if not mapping:
231
- konsol.print("[bold red]Extractor bulunamadı![/bold red]")
232
- return await self.handle_no_results()
233
-
234
- choice = await self.ui.select_from_list("Ne yapmak istersiniz?", ["İzle", "Tüm Eklentilerde Ara", "Ana Menü"])
235
+ # Direkt oynatma - tüm pluginlerde artık play metodu var (PluginBase'den miras)
236
+ return await self.play_direct(links)
235
237
 
236
- match choice:
237
- case "İzle":
238
- await self.play_with_extractor(links, mapping)
239
- case "Tüm Eklentilerde Ara":
240
- await self.search_all_plugins()
241
- case "Ana Menü":
242
- await self.start()
243
-
244
- async def play_direct(self, links: list[dict]):
238
+ async def play_direct(self, links: list[ExtractResult]):
245
239
  """Plugin'in kendi metoduyla oynat"""
246
240
  selected = await self.ui.select_from_list(
247
241
  message = "Bağlantı seçin:",
248
- choices = [{"name": link.get("name", "Bilinmiyor"), "value": link} for link in links]
242
+ choices = [{"name": link.name or "Bilinmiyor", "value": link} for link in links]
249
243
  )
250
244
 
251
245
  if not selected:
252
246
  return await self.content_finished()
253
247
 
254
248
  self.update_title(self.episode_title)
255
- self.update_title(selected.get("name"))
249
+ self.update_title(selected.name)
256
250
 
257
251
  await self.current_plugin.play(
258
- name = self.media.get_title(),
259
- url = selected.get("url"),
260
- referer = selected.get("referer"),
261
- subtitles = selected.get("subtitles", [])
252
+ name = self.media.get_title(),
253
+ url = selected.url,
254
+ user_agent = selected.user_agent,
255
+ referer = selected.referer,
256
+ subtitles = selected.subtitles or []
262
257
  )
263
258
  return await self.content_finished()
264
259
 
265
- async def play_with_extractor(self, links: list[dict], mapping: dict):
260
+ async def play_with_extractor(self, links: list[ExtractResult], mapping: dict):
266
261
  """Extractor ile oynat"""
267
262
  options = [
268
- {"name": link.get("name", mapping[link["url"]]), "value": link}
269
- for link in links if link["url"] in mapping
263
+ {"name": link.name or mapping.get(link.url, "Bilinmiyor"), "value": link}
264
+ for link in links if link.url in mapping
270
265
  ]
271
266
 
272
267
  if not options:
@@ -277,7 +272,7 @@ class KekikStream:
277
272
  if not selected:
278
273
  return await self.content_finished()
279
274
 
280
- url = selected.get("url")
275
+ url = selected.url
281
276
  extractor: ExtractorBase = self.extractor.find_extractor(url)
282
277
 
283
278
  if not extractor:
@@ -285,7 +280,7 @@ class KekikStream:
285
280
  return await self.handle_no_results()
286
281
 
287
282
  try:
288
- referer = selected.get("referer", self.current_plugin.main_url)
283
+ referer = selected.referer or self.current_plugin.main_url
289
284
  extract_data = await extractor.extract(url, referer=referer)
290
285
  except Exception as e:
291
286
  konsol.print(f"[bold red]{extractor.name} hatası: {e}[/bold red]")
@@ -303,13 +298,9 @@ class KekikStream:
303
298
 
304
299
  # Başlıkları güncelle ve oynat
305
300
  self.update_title(self.episode_title)
306
- self.update_title(selected.get("name"))
301
+ self.update_title(selected.name)
307
302
  self.update_title(extract_data.name)
308
303
 
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
304
  self.media.play_media(extract_data)
314
305
  await self.content_finished()
315
306
 
@@ -1,10 +1,9 @@
1
1
  setuptools
2
2
  wheel
3
-
4
3
  Kekik
5
- curl-cffi
4
+ httpx
6
5
  cloudscraper
7
6
  parsel
8
-
9
7
  pydantic
10
- InquirerPy
8
+ InquirerPy
9
+ yt-dlp
@@ -0,0 +1,312 @@
1
+ Metadata-Version: 2.4
2
+ Name: KekikStream
3
+ Version: 2.2.0
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
+ [![Boyut](https://img.shields.io/github/repo-size/keyiflerolsun/KekikStream?logo=git&logoColor=white&label=Boyut)](#)
41
+ [![Görüntülenme](https://visitor-badge.laobi.icu/badge?page_id=keyiflerolsun/KekikStream&title=Görüntülenme)](#)
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
+ [![PyPI](https://img.shields.io/pypi/v/KekikStream?logo=pypi&logoColor=white&label=PyPI)](https://pypi.org/project/KekikStream)
45
+ [![PyPI - Yüklenme](https://img.shields.io/pypi/dm/KekikStream?logo=pypi&logoColor=white&label=Yüklenme)](https://pypi.org/project/KekikStream)
46
+ [![PyPI - Wheel](https://img.shields.io/pypi/wheel/KekikStream?logo=pypi&logoColor=white&label=Wheel)](https://pypi.org/project/KekikStream)
47
+
48
+ [![Python Version](https://img.shields.io/pypi/pyversions/KekikStream?logo=python&logoColor=white&label=Python)](#)
49
+ [![Lisans](https://img.shields.io/pypi/l/KekikStream?logo=gnu&logoColor=white&label=Lisans)](#)
50
+ [![Durum](https://img.shields.io/pypi/status/KekikStream?logo=windowsterminal&logoColor=white&label=Durum)](#)
51
+
52
+ [![PyPI Yükle](https://github.com/keyiflerolsun/KekikStream/actions/workflows/pypiYukle.yml/badge.svg)](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
+ [![Video](https://github.com/user-attachments/assets/63d31bb0-0b69-40b4-84aa-66623f2a253f)](https://github.com/user-attachments/assets/63d31bb0-0b69-40b4-84aa-66623f2a253f)
58
+
59
+ [![ForTheBadge made-with-python](https://ForTheBadge.com/images/badges/made-with-python.svg)](https://www.python.org/)
60
+ [![ForTheBadge built-with-love](https://ForTheBadge.com/images/badges/built-with-love.svg)](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, ExtractResult
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[ExtractResult]:
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
+ - [feroxx/Kekik-cloudstream](https://github.com/feroxx/Kekik-cloudstream)
296
+ - [kerimmkirac/cs-kerim](https://github.com/kerimmkirac/cs-kerim)
297
+ - [Phisher98/Extractors](https://github.com/phisher98/cloudstream-extensions-phisher/blob/master/StreamPlay/src/main/kotlin/com/Phisher98/Extractors.kt)
298
+
299
+ ## 🌐 Telif Hakkı ve Lisans
300
+
301
+ *Copyright (C) 2024 by* [keyiflerolsun](https://github.com/keyiflerolsun) ❤️️
302
+ [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..*
303
+
304
+ ---
305
+
306
+ <p align="center">
307
+ 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.
308
+ </p>
309
+
310
+ <p align="center">
311
+ <sub>⭐ Beğendiyseniz yıldız vermeyi unutmayın!</sub>
312
+ </p>
@@ -0,0 +1,81 @@
1
+ KekikStream/__init__.py,sha256=nTgIxO1716DVX-cZnMvwi6OjPbuebFyeYpHvpqCJ0Js,12767
2
+ KekikStream/__main__.py,sha256=B81dQoeGEb-T5Sycs3eNAmW7unvx0Mef0syCjs4nPds,137
3
+ KekikStream/requirements.txt,sha256=0fO-7byqgLMr4NyJO7fQBFOnLv0zcAeqk7tLhHXqonk,76
4
+ KekikStream/CLI/__init__.py,sha256=U6oLq_O7u5y2eHhBnmfhZNns_EqHHJXJmzl8jvZFUNY,230
5
+ KekikStream/CLI/pypi_kontrol.py,sha256=q6fNs6EKJDc5VuUFig9DBzLzNPp_kMD1vOVgLElcii8,1487
6
+ KekikStream/Core/__init__.py,sha256=Ise27_Hqe1YeqTcSNnf3HqynhbySEVC-pNP2uKa2GOo,771
7
+ KekikStream/Core/Extractor/ExtractorBase.py,sha256=CAdeel6zGlj_RHD0lwjyNW5hAaivo1XyAZbnmiVDaZo,2023
8
+ KekikStream/Core/Extractor/ExtractorLoader.py,sha256=GPGCmgFpDBywR8CsNw43-ddseZhSKTjAUETp1Ohbi6E,4796
9
+ KekikStream/Core/Extractor/ExtractorManager.py,sha256=VYkj4CCE5Puqsr6PCeN8i_OS0hfYKI4NScj98BLO39o,2644
10
+ KekikStream/Core/Extractor/ExtractorModels.py,sha256=Qj_gbIeGRewaZXNfYkTi4FFRRq6XBOc0HS0tXGDwajI,445
11
+ KekikStream/Core/Extractor/YTDLPCache.py,sha256=sRg5kwFxkRXA_8iRwsV29E51g9qQJvg8dWUnzfr7EwA,984
12
+ KekikStream/Core/Media/MediaHandler.py,sha256=MEn3spPAThVloN3WcoCwWhpoyMA7tAZvcwYjmjJsX3U,7678
13
+ KekikStream/Core/Media/MediaManager.py,sha256=AaUq2D7JSJIphjoAj2fjLOJjswm7Qf5hjYCbBdrbnDU,438
14
+ KekikStream/Core/Plugin/PluginBase.py,sha256=iirN7cQHccqUa6f6Gr86x8XYg4Rr6TlkaWOtbhnzU9g,5923
15
+ KekikStream/Core/Plugin/PluginLoader.py,sha256=GcDqN1u3nJeoGKH_oDFHCpwteJlLCxHNbmPrC5L-hZE,3692
16
+ KekikStream/Core/Plugin/PluginManager.py,sha256=CZVg1eegi8vfMfccx0DRV0Box8kXz-aoULTQLgbPbvM,893
17
+ KekikStream/Core/Plugin/PluginModels.py,sha256=Yvx-6Fkn8QCIcuqAkFbCP5EJcq3XBkK_P8S0tRNhS6E,2476
18
+ KekikStream/Core/UI/UIManager.py,sha256=T4V_kdTTWa-UDamgLSKa__dWJuzcvRK9NuwBlzU9Bzc,1693
19
+ KekikStream/Extractors/CloseLoad.py,sha256=m3wpLvbLRakqv0yn9v6OOpVlEDIqgAy6XBMIiuD5g0Q,1558
20
+ KekikStream/Extractors/ContentX.py,sha256=x0j67e1OAw4L1m7ejUTyiIxqr1EhvpjaA_0U-s4IQ-I,3617
21
+ KekikStream/Extractors/DonilasPlay.py,sha256=Lr60pEht96SMlXICYWo9J5dOwV4ty8fetBCCqJ3ARUY,3221
22
+ KekikStream/Extractors/DzenRu.py,sha256=X0Rhm1-W4YjQwVrJs8YFqVcCxMaZi8rsKiLhK_ZsYlU,1185
23
+ KekikStream/Extractors/ExPlay.py,sha256=EJNVKAbaIxlbOsCx7J9aLfNHKOFoqSLZZUw7W4QYeH0,1827
24
+ KekikStream/Extractors/Filemoon.py,sha256=l0AVyRrYA2DTuSkYoy6Jh02_w53TeBRyROkY9koiees,2684
25
+ KekikStream/Extractors/HDPlayerSystem.py,sha256=EgnFzx5Q4PkuwAtuff5SYU9k59B-CyOdySl7lbCZ9hM,1312
26
+ KekikStream/Extractors/JetTv.py,sha256=aA3WeOvR-tszac-WSwunZZb1NRy25TQH8vxY3TDscRI,1596
27
+ KekikStream/Extractors/MailRu.py,sha256=xQVCWwYqNoG5T43VAW1_m0v4e80FbO-1pNPKkwhTccU,1218
28
+ KekikStream/Extractors/MixPlayHD.py,sha256=POV_yq3KoZ6S6EqFsKYULEBz92NdUa2BpYKNo0eNQH8,1552
29
+ KekikStream/Extractors/MixTiger.py,sha256=4VbOYgE4s5H-BGVvJI0AI57M-WBWqnek_LGfCFHAucw,2116
30
+ KekikStream/Extractors/MolyStream.py,sha256=IeeBw9tJJrL5QQ-t2Yp-a-6lnDc3Y00UNiaN6m-o-7c,1160
31
+ KekikStream/Extractors/Odnoklassniki.py,sha256=YfFRCL3Ag5N4zDzK9ZLOr3HVQcsETFQpff1px02imJ0,4019
32
+ KekikStream/Extractors/PeaceMakerst.py,sha256=pEgJb3KDfEPAUjbuvrYbUlxIciKgED-Vd0arrRO3QCk,2317
33
+ KekikStream/Extractors/PixelDrain.py,sha256=Uk2pPvtBzaKtRXu1iNO8FLHd0EAuIOIzI1H_n02tg-U,964
34
+ KekikStream/Extractors/PlayerFilmIzle.py,sha256=kH-O_RtQvG4iRLGKi-sFn1ST14DrxxoAa5iRT2PsdXc,2503
35
+ KekikStream/Extractors/RapidVid.py,sha256=t_8ZUp5DCTIaohc5aW4s9HEQQ1A2lU5bTMX84lctmtY,3529
36
+ KekikStream/Extractors/SetPlay.py,sha256=6XuNXoNFM1h3KOCkTxeZmcAl8QTdqzVN_pp_dEIKF8A,2235
37
+ KekikStream/Extractors/SetPrime.py,sha256=ob09y-Sm91YR7rIRzikhZiMHX6D4Djm5QzFTg6KbO4k,1536
38
+ KekikStream/Extractors/SibNet.py,sha256=zJTkzlr34ufKCWzKKCgJrzhb2o-fpjTjFdi38gv6N6g,849
39
+ KekikStream/Extractors/Sobreatsesuyp.py,sha256=qlSQHUHjTjBoY0nsuZQWAjnfswbPORkBg6rUuP7SagA,2000
40
+ KekikStream/Extractors/TRsTX.py,sha256=mbSRGnQt26a73SbqwtY9rpiYFwgRgVbvA6bkGb_PvP8,2152
41
+ KekikStream/Extractors/TauVideo.py,sha256=2ai9BwwM6qlCgxK7E0B642LtOF5y4hEb9tQ2aDpbMtc,1112
42
+ KekikStream/Extractors/TurboImgz.py,sha256=nnWnP1K4JZbMj6S-YuXxej31UZtF4JcboSW4n7A4A5c,824
43
+ KekikStream/Extractors/TurkeyPlayer.py,sha256=FX_H3vzXjAD7IjK11bjJVVw_VdPQ4n6YQLfjQ6E3t7o,1247
44
+ KekikStream/Extractors/VCTPlay.py,sha256=1BCl2_vVIrwvG56LCzl2KE5g2CUaMAhzImOZMdZpZCQ,1377
45
+ KekikStream/Extractors/VidHide.py,sha256=UIAPFLbGDPRjcJVuDmaVbFN5r0ZyJoW4CRn1INH8mJs,2837
46
+ KekikStream/Extractors/VidMoly.py,sha256=QLRRGH1uHFTREl5Oq3V8WIkVpqaZuuygmHaW1ulj1Lg,4774
47
+ KekikStream/Extractors/VidMoxy.py,sha256=LT7wTKBtuuagXwfGjWZwQF2NQGuChurZJ-I6gM0Jcek,1771
48
+ KekikStream/Extractors/VidPapi.py,sha256=g9ohdL9VJrxy4N7xerbIRz3ZxjsXFHlJWy0NaZ31hFY,3259
49
+ KekikStream/Extractors/VideoSeyred.py,sha256=M6QPZ_isX9vM_7LPo-2I_8Cf1vB9awHw8vvzBODtoiQ,1977
50
+ KekikStream/Extractors/YTDLP.py,sha256=Hy8loCSFSquu2zaL3INord-Jm6T8CM6K2-VcDA2K79g,7390
51
+ KekikStream/Extractors/YildizKisaFilm.py,sha256=R_JlrOVeMiDlXYcuTdItnKvidyx8_u3B14fSrxew2aE,1316
52
+ KekikStream/Plugins/BelgeselX.py,sha256=upxN78gIFrPdVCw3hJ0DGqwa6vtrd_ShCWbO7_JLQhg,8427
53
+ KekikStream/Plugins/DiziBox.py,sha256=3O8RHPvzMPcMB-8Wc1gwxI7GQlBitQvz4WDR6bmXuqQ,9715
54
+ KekikStream/Plugins/DiziPal.py,sha256=xwz6XeN2bMvShClfsPTK5dI4EktSZQyCrVu8Gn0x_pU,9715
55
+ KekikStream/Plugins/DiziYou.py,sha256=sH4UOCEbl-o9fIGORgz1YVMMnfbZVfjnitPsGuCl7PI,8698
56
+ KekikStream/Plugins/Dizilla.py,sha256=Rk_rS6ymlj5RT-ZBspjXS-Dv0ds3d9n46LCpGKtycP4,11765
57
+ KekikStream/Plugins/FilmBip.py,sha256=xJA79gwPXwvdQLfUu5QGdwv8kGZngjAg3csLQqQYSDU,6036
58
+ KekikStream/Plugins/FilmMakinesi.py,sha256=_Ulwi0bo-8bXZZjRxbpBKAIkAnlyG6D0qEvD1UJTsjk,5708
59
+ KekikStream/Plugins/FilmModu.py,sha256=HVawdKHuqcFb3PQ-93uwGlwv1dNhkM2kpStBlTJJXR4,6553
60
+ KekikStream/Plugins/FullHDFilm.py,sha256=fimK5MqPYjmog859lfuEuJeg8AGylYyDm36Ak3X3Msg,9768
61
+ KekikStream/Plugins/FullHDFilmizlesene.py,sha256=_-HaoNvPVzITB_aK3jOkSSAOA50SYFNdnjHH4JGCmOc,6078
62
+ KekikStream/Plugins/HDFilmCehennemi.py,sha256=I-dwkerkwfzcaSQA9XzIGh2LeRywBGydX0D0k6FmoOc,13029
63
+ KekikStream/Plugins/JetFilmizle.py,sha256=njmaX7Rhi0bewZvK_NO9PTs86uB-8zxYcuwrYthA2aw,7956
64
+ KekikStream/Plugins/KultFilmler.py,sha256=ODnQu2_qLKx68dpT16MFUiIXYQlkQSDU0x15o91LWU8,9097
65
+ KekikStream/Plugins/RecTV.py,sha256=Nj4AdeetPMzvZ-VKUdUGhBC1SiFSBRYRebODgE2UeI8,7228
66
+ KekikStream/Plugins/RoketDizi.py,sha256=7cP6935unhrn_yDt0hsLoW3nboX3WUD0P2DqqRny3_M,8568
67
+ KekikStream/Plugins/SelcukFlix.py,sha256=WKMsZpVVdHn_zW69xxhAuIP7OhAPbPFxFRWzGzHBgaE,13601
68
+ KekikStream/Plugins/SetFilmIzle.py,sha256=EcoHSacJO9bvzA9lZZzDZAwAhXfaDstI4M4C3YOwvEU,10113
69
+ KekikStream/Plugins/SezonlukDizi.py,sha256=7N4S8ikA4IzHszD5WaXAUESAVfHDKSnMQeX4iQFP3KY,8457
70
+ KekikStream/Plugins/SineWix.py,sha256=z0r90lggAugEWE1g9vg8gZsInBObUZPnVFQwq7GYmJs,7052
71
+ KekikStream/Plugins/Sinefy.py,sha256=Ogw0-qjROz8T0EkV1jwbOvz0WM4FN9D24bNrJmi314k,9998
72
+ KekikStream/Plugins/SinemaCX.py,sha256=aujqCWPGZHcRqKcMFlZYEwMonj0C_UQ_J4ZqCyF59pU,7492
73
+ KekikStream/Plugins/Sinezy.py,sha256=lFOfbMwxzP6IkhPZ_C3ZWGrgwThSk58pYQAD61rCJnM,6128
74
+ KekikStream/Plugins/SuperFilmGeldi.py,sha256=dqU1IJHcTPU9zlnA9rSKsX0ehpBYSgDuz6eSlCCop8k,6044
75
+ KekikStream/Plugins/UgurFilm.py,sha256=TlMDy3tSfkEUy_ziIdCkgnfmoRtVdXEv8m4kjKeAWrE,4696
76
+ kekikstream-2.2.0.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
77
+ kekikstream-2.2.0.dist-info/METADATA,sha256=bTOZwY8eWMqFaV8mBsxRjS-NPd8HAAtdJGQvjD3K_Ng,10407
78
+ kekikstream-2.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
79
+ kekikstream-2.2.0.dist-info/entry_points.txt,sha256=dFwdiTx8djyehI0Gsz-rZwjAfZzUzoBSrmzRu9ubjJc,50
80
+ kekikstream-2.2.0.dist-info/top_level.txt,sha256=DNmGJDXl27Drdfobrak8KYLmocW_uznVYFJOzcjUgmY,12
81
+ kekikstream-2.2.0.dist-info/RECORD,,
@@ -1,7 +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 FourCX(ContentX):
6
- name = "FourCX"
7
- main_url = "https://four.contentx.me"