1
+ package com.hexated
2
+
3
+ import com.fasterxml.jackson.annotation.JsonProperty
4
+ import com.lagradost.cloudstream3.*
5
+ import com.lagradost.cloudstream3.LoadResponse.Companion.addActors
6
+ import com.lagradost.cloudstream3.LoadResponse.Companion.addTrailer
7
+ import com.lagradost.cloudstream3.extractors.DoodLaExtractor
8
+ import com.lagradost.cloudstream3.extractors.Filesim
9
+ import com.lagradost.cloudstream3.utils.*
10
+ import org.jsoup.nodes.Element
11
+
12
+ class Cinemathek : MainAPI () {
13
+ override var mainUrl = " https://cinemathek.net"
14
+ override var name = " Cinemathek"
15
+ override val hasMainPage = true
16
+ override var lang = " de"
17
+ override val supportedTypes = setOf (
18
+ TvType .Movie ,
19
+ TvType .TvSeries ,
20
+ )
21
+
22
+ override val mainPage = mainPageOf(
23
+ " filme" to " Filme" ,
24
+ " serien" to " TV Shows" ,
25
+ " episoden" to " Episodes" ,
26
+ )
27
+
28
+ override suspend fun getMainPage (
29
+ page : Int ,
30
+ request : MainPageRequest
31
+ ): HomePageResponse {
32
+ val document = app.get(" $mainUrl /${request.data} /page/$page /" ).document
33
+ val home =
34
+ document.select(" div.items.full article, div#archive-content article" ).mapNotNull {
35
+ it.toSearchResult()
36
+ }
37
+ return newHomePageResponse(
38
+ list = HomePageList (
39
+ name = request.name,
40
+ list = home,
41
+ request.data == " episoden"
42
+ ),
43
+ hasNext = true
44
+ )
45
+ }
46
+
47
+ private fun getProperLink (uri : String ): String {
48
+ return when {
49
+ uri.contains(" /episoden/" ) -> {
50
+ uri.replace(Regex (" -\\ d+x\\ d+" ), " " ).replace(" /episoden/" , " /serien/" )
51
+ }
52
+
53
+ else -> {
54
+ uri
55
+ }
56
+ }
57
+ }
58
+
59
+ private fun Element.toSearchResult (): SearchResponse {
60
+ val title = this .selectFirst(" h3 > a" )!! .text()
61
+ val href = getProperLink(this .selectFirst(" h3 > a" )!! .attr(" href" ))
62
+ val posterUrl = this .select(" div.poster > img" ).attr(" src" ).toString()
63
+ val quality = getQualityFromString(this .select(" span.quality" ).text())
64
+ return newMovieSearchResponse(title, href, TvType .Movie ) {
65
+ this .posterUrl = posterUrl
66
+ this .quality = quality
67
+ }
68
+ }
69
+
70
+ override suspend fun search (query : String ): List <SearchResponse > {
71
+ val document = app.get(" $mainUrl /search/$query " ).document
72
+ return document.select(" div.result-item" ).map {
73
+ val title = it.selectFirst(" div.title > a" )!! .text()
74
+ val href = getProperLink(it.selectFirst(" div.title > a" )!! .attr(" href" ))
75
+ val posterUrl = it.selectFirst(" img" )!! .attr(" src" ).toString()
76
+ newMovieSearchResponse(title, href, TvType .TvSeries ) {
77
+ this .posterUrl = posterUrl
78
+ }
79
+ }
80
+ }
81
+
82
+ override suspend fun load (url : String ): LoadResponse {
83
+ val document = app.get(url).document
84
+ val title = document.selectFirst(" div.data > h1" )?.text() ? : " "
85
+ val poster = document.select(" div.poster > img" ).attr(" src" ).toString()
86
+ val tags = document.select(" div.sgeneros > a" ).map { it.text() }
87
+
88
+ val year = Regex (" ,\\ s?(\\ d+)" ).find(
89
+ document.select(" span.date" ).text().trim()
90
+ )?.groupValues?.get(1 ).toString().toIntOrNull()
91
+ val tvType = if (document.select(" ul#section > li:nth-child(1)" ).text().contains(" Episodes" )
92
+ ) TvType .TvSeries else TvType .Movie
93
+ val description = document.select(" div.wp-content > p" ).text().trim()
94
+ val trailer = document.selectFirst(" div.embed iframe" )?.attr(" src" )
95
+ val rating =
96
+ document.selectFirst(" span.dt_rating_vgs" )?.text()?.toRatingInt()
97
+ val actors = document.select(" div.persons > div[itemprop=actor]" ).map {
98
+ Actor (it.select(" meta[itemprop=name]" ).attr(" content" ), it.select(" img" ).attr(" src" ))
99
+ }
100
+
101
+ val recommendations = document.select(" div.owl-item" ).map {
102
+ val recName =
103
+ it.selectFirst(" a" )!! .attr(" href" ).toString().removeSuffix(" /" ).split(" /" ).last()
104
+ val recHref = it.selectFirst(" a" )!! .attr(" href" )
105
+ val recPosterUrl = it.selectFirst(" img" )?.attr(" src" ).toString()
106
+ newTvSeriesSearchResponse(recName, recHref, TvType .TvSeries ) {
107
+ this .posterUrl = recPosterUrl
108
+ }
109
+ }
110
+
111
+ return if (tvType == TvType .TvSeries ) {
112
+ val episodes = document.select(" ul.episodios > li" ).map {
113
+ val href = it.select(" a" ).attr(" href" )
114
+ val name = fixTitle(it.select(" div.episodiotitle > a" ).text().trim())
115
+ val image = it.select(" div.imagen > img" ).attr(" src" )
116
+ val episode = it.select(" div.numerando" ).text().replace(" " , " " ).split(" -" ).last()
117
+ .toIntOrNull()
118
+ val season = it.select(" div.numerando" ).text().replace(" " , " " ).split(" -" ).first()
119
+ .toIntOrNull()
120
+ Episode (
121
+ href,
122
+ name,
123
+ season,
124
+ episode,
125
+ image
126
+ )
127
+ }
128
+ newTvSeriesLoadResponse(title, url, TvType .TvSeries , episodes) {
129
+ this .posterUrl = poster
130
+ this .year = year
131
+ this .plot = description
132
+ this .tags = tags
133
+ this .rating = rating
134
+ addActors(actors)
135
+ this .recommendations = recommendations
136
+ addTrailer(trailer)
137
+ }
138
+ } else {
139
+ newMovieLoadResponse(title, url, TvType .Movie , url) {
140
+ this .posterUrl = poster
141
+ this .year = year
142
+ this .plot = description
143
+ this .tags = tags
144
+ this .rating = rating
145
+ addActors(actors)
146
+ this .recommendations = recommendations
147
+ addTrailer(trailer)
148
+ }
149
+ }
150
+ }
151
+
152
+ override suspend fun loadLinks (
153
+ data : String ,
154
+ isCasting : Boolean ,
155
+ subtitleCallback : (SubtitleFile ) -> Unit ,
156
+ callback : (ExtractorLink ) -> Unit
157
+ ): Boolean {
158
+ val document = app.get(data).document
159
+ document.select(" ul#playeroptionsul > li" ).map {
160
+ Triple (
161
+ it.attr(" data-post" ),
162
+ it.attr(" data-nume" ),
163
+ it.attr(" data-type" )
164
+ )
165
+ }.apmap { (id, nume, type) ->
166
+ val iframe = app.get(
167
+ url = " $mainUrl /wp-json/dooplayer/v2/$id /$type /$nume " ,
168
+ referer = data,
169
+ headers = mapOf (" Accept" to " */*" , " X-Requested-With" to " XMLHttpRequest" )
170
+ ).parsedSafe<ResponseHash >()?.embedUrl ? : return @apmap
171
+
172
+ if (! iframe.contains(" youtube" )) loadExtractor(iframe, " $mainUrl /" , subtitleCallback, callback)
173
+ }
174
+
175
+ return true
176
+ }
177
+
178
+ data class ResponseHash (
179
+ @JsonProperty(" embed_url" ) val embedUrl : String ,
180
+ )
181
+
182
+ }
183
+
184
+ class StreamwishCom : Filesim () {
185
+ override val name = " Streamwish"
186
+ override var mainUrl = " https://streamwish.com"
187
+ }
188
+
189
+ class Ds2play : DoodLaExtractor () {
190
+ override var name = " Ds2play"
191
+ override var mainUrl = " https://ds2play.com"
192
+ }
193
+
194
+ class Do0od : DoodLaExtractor () {
195
+ override var name = " Do0od"
196
+ override var mainUrl = " https://do0od.com"
197
+ }
198
+
199
+ class Filelions : Filesim () {
200
+ override val name = " Filelions"
201
+ override var mainUrl = " https://filelions.live"
202
+ }
0 commit comments