KekikStream 2.4.3__tar.gz → 2.4.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of KekikStream might be problematic. Click here for more details.

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