Skip to content

Commit b6f662b

Browse files
Last Sync: 2026-02-24 22:37 (Mobile)
1 parent 0bc67cf commit b6f662b

2 files changed

Lines changed: 39 additions & 33 deletions

File tree

NekopoiProvider/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ cloudstream {
2121
"AnimeMovie",
2222
"Anime",
2323
"OVA",
24+
"NSFW",
2425
)
2526

2627
iconUrl = "https://www.google.com/s2/favicons?domain=nekopoi.care&sz=%size%"

NekopoiProvider/src/main/kotlin/com/nekopoi/NekopoiProvider.kt

Lines changed: 38 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package com.nekopoi
22

33
import com.lagradost.cloudstream3.*
4-
import com.lagradost.cloudstream3.amap
54
import com.lagradost.cloudstream3.utils.*
65
import com.lagradost.nicehttp.NiceResponse
76
import com.lagradost.nicehttp.Requests
@@ -20,7 +19,8 @@ class NekopoiProvider : MainAPI() {
2019
override val supportedTypes = setOf(
2120
TvType.Anime,
2221
TvType.AnimeMovie,
23-
TvType.OVA
22+
TvType.OVA,
23+
TvType.NSFW,
2424
)
2525

2626
companion object {
@@ -57,18 +57,20 @@ class NekopoiProvider : MainAPI() {
5757
page: Int,
5858
request: MainPageRequest
5959
): HomePageResponse {
60-
val url = if (page == 1) request.data else "${request.data}/page/$page"
60+
val baseUrl = request.data.removeSuffix("/")
61+
val url = if (page == 1) "$baseUrl/" else "$baseUrl/page/$page/"
62+
6163
val document = fetch.get(url).document
6264

63-
val home = document.select("div.result ul li").mapNotNull {
65+
val home = document.select("div.result ul li, div.eropost").mapNotNull {
6466
it.toSearchResult()
6567
}
6668

6769
return newHomePageResponse(
6870
list = HomePageList(
6971
name = request.name,
7072
list = home,
71-
isHorizontalImages = true
73+
isHorizontalImages = true
7274
),
7375
hasNext = home.isNotEmpty()
7476
)
@@ -84,18 +86,17 @@ class NekopoiProvider : MainAPI() {
8486
}
8587

8688
private fun Element.toSearchResult(): AnimeSearchResponse? {
87-
val title = this.selectFirst("h2 a")?.text()?.trim() ?: return null
89+
val title = this.selectFirst("h2 a, h2, h3 a, div.info h2")?.text()?.trim() ?: return null
8890
val href = getProperAnimeLink(this.selectFirst("a")?.attr("href") ?: return null)
8991

92+
val img = this.selectFirst("img")
9093
val posterUrl = fixUrlNull(
91-
this.selectFirst("img")?.let { img ->
92-
img.attr("data-src").takeIf { it.isNotBlank() }
93-
?: img.attr("data-lazy-src").takeIf { it.isNotBlank() }
94-
?: img.attr("src")
95-
}
94+
img?.attr("data-src").takeIf { !it.isNullOrBlank() }
95+
?: img?.attr("data-lazy-src").takeIf { !it.isNullOrBlank() }
96+
?: img?.attr("src")
9697
)
9798

98-
val epNum = this.selectFirst("i.dot")?.text()?.filter { it.isDigit() }?.toIntOrNull()
99+
val epNum = this.selectFirst("i.dot, div.ep, span.ep")?.text()?.filter { it.isDigit() }?.toIntOrNull()
99100

100101
return newAnimeSearchResponse(title, href, TvType.NSFW) {
101102
this.posterUrl = posterUrl
@@ -185,15 +186,27 @@ class NekopoiProvider : MainAPI() {
185186
}
186187
},
187188
{
188-
res.select("div.boxdownload div.liner").map { ele ->
189-
getIndexQuality(
190-
ele.select("div.name").text()
191-
) to (ele.selectFirst("a[href*=ouo]")?.attr("href") ?: ele.selectFirst("a[href*=mirrored]")?.attr("href"))
192-
}.filter { it.first != Qualities.P360.value }.map {
193-
val bypassedAds = bypassMirrored(bypassOuo(it.second))
194-
bypassedAds.amap(ads@{ adsLink ->
189+
res.select("div.boxdownload div.liner").mapNotNull { ele ->
190+
val url = ele.selectFirst("a[href*=ouo]")?.attr("href")
191+
?: ele.selectFirst("a[href*=mirrored]")?.attr("href")
192+
193+
if (url != null) {
194+
getIndexQuality(ele.select("div.name").text()) to url
195+
} else null
196+
}.filter { it.first != Qualities.P360.value }.amap { (quality, rawUrl) ->
197+
198+
val targetUrl = if (rawUrl.contains("ouo", ignoreCase = true)) {
199+
bypassOuo(rawUrl)
200+
} else {
201+
rawUrl
202+
}
203+
204+
val bypassedAds = bypassMirrored(targetUrl)
205+
206+
bypassedAds.forEach { adsLink ->
207+
val embedUrl = fixEmbed(adsLink) ?: return@forEach
195208
loadExtractor(
196-
fixEmbed(adsLink) ?: return@ads,
209+
embedUrl,
197210
"$mainUrl/",
198211
subtitleCallback,
199212
) { link ->
@@ -336,21 +349,13 @@ class NekopoiProvider : MainAPI() {
336349
}
337350

338351
private fun fixUrl(url: String, domain: String): String {
339-
if (url.startsWith("http")) {
340-
return url
341-
}
342-
if (url.isEmpty()) {
343-
return ""
344-
}
352+
if (url.startsWith("http")) return url
353+
if (url.isEmpty()) return ""
345354

346-
val startsWithNoHttp = url.startsWith("//")
347-
if (startsWithNoHttp) {
348-
return "https:$url"
355+
return if (url.startsWith("//")) {
356+
"https:$url"
349357
} else {
350-
if (url.startsWith('/')) {
351-
return domain + url
352-
}
353-
return "$domain/$url"
358+
if (url.startsWith('/')) domain + url else "$domain/$url"
354359
}
355360
}
356361

0 commit comments

Comments
 (0)