diff --git a/src/all/onepace/AndroidManifest.xml b/src/all/onepace/AndroidManifest.xml new file mode 100644 index 000000000..acb4de356 --- /dev/null +++ b/src/all/onepace/AndroidManifest.xml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/src/all/onepace/build.gradle b/src/all/onepace/build.gradle new file mode 100644 index 000000000..6be4cb1ec --- /dev/null +++ b/src/all/onepace/build.gradle @@ -0,0 +1,13 @@ +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' + +ext { + extName = 'Onepace' + pkgNameSuffix = 'all.onepace' + extClass = '.OnepaceFactory' + extVersionCode = 1 + libVersion = '12' + containsNsfw = false +} + +apply from: "$rootDir/common.gradle" diff --git a/src/all/onepace/res/mipmap-hdpi/ic_launcher.png b/src/all/onepace/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..0a05668e4 Binary files /dev/null and b/src/all/onepace/res/mipmap-hdpi/ic_launcher.png differ diff --git a/src/all/onepace/res/mipmap-mdpi/ic_launcher.png b/src/all/onepace/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..0a05668e4 Binary files /dev/null and b/src/all/onepace/res/mipmap-mdpi/ic_launcher.png differ diff --git a/src/all/onepace/res/mipmap-xhdpi/ic_launcher.png b/src/all/onepace/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..0a05668e4 Binary files /dev/null and b/src/all/onepace/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/src/all/onepace/res/mipmap-xxhdpi/ic_launcher.png b/src/all/onepace/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..0a05668e4 Binary files /dev/null and b/src/all/onepace/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/src/all/onepace/res/mipmap-xxxhdpi/ic_launcher.png b/src/all/onepace/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..0a05668e4 Binary files /dev/null and b/src/all/onepace/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/src/all/onepace/src/eu/kanade/tachiyomi/animeextension/all/onepace/Onepace.kt b/src/all/onepace/src/eu/kanade/tachiyomi/animeextension/all/onepace/Onepace.kt new file mode 100644 index 000000000..db149a59d --- /dev/null +++ b/src/all/onepace/src/eu/kanade/tachiyomi/animeextension/all/onepace/Onepace.kt @@ -0,0 +1,156 @@ +package eu.kanade.tachiyomi.animeextension.all.onepace + +import androidx.preference.PreferenceScreen +import eu.kanade.tachiyomi.animesource.ConfigurableAnimeSource +import eu.kanade.tachiyomi.animesource.model.AnimeFilterList +import eu.kanade.tachiyomi.animesource.model.AnimesPage +import eu.kanade.tachiyomi.animesource.model.SAnime +import eu.kanade.tachiyomi.animesource.model.SEpisode +import eu.kanade.tachiyomi.animesource.model.Video +import eu.kanade.tachiyomi.animesource.online.ParsedAnimeHttpSource +import eu.kanade.tachiyomi.network.GET +import eu.kanade.tachiyomi.util.asJsoup +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.jsonArray +import kotlinx.serialization.json.jsonObject +import okhttp3.OkHttpClient +import okhttp3.Request +import okhttp3.Response +import org.jsoup.nodes.Document +import org.jsoup.nodes.Element +import uy.kohesive.injekt.api.get +import uy.kohesive.injekt.injectLazy +import java.lang.Exception +import java.net.URLEncoder + +open class Onepace(override val lang: String, override val name: String) : ConfigurableAnimeSource, ParsedAnimeHttpSource() { + + override val baseUrl = "https://www.zippyshare.com/rest/public/getTree?user=onepace&ident=kbvatgfc&id=%23" + + override val supportsLatest = false + + override val client: OkHttpClient = network.cloudflareClient + + private val json: Json by injectLazy() + + override fun popularAnimeParse(response: Response): AnimesPage { + val animes = mutableListOf() + val document = client.newCall(GET(baseUrl)).execute().asJsoup() + val responseJson = json.decodeFromString(document.select("body").text().dropLast(1).drop(1)) + val childrenJson = responseJson["children"]?.jsonArray + // 0 = eng, 1 = sp, 2 = fr + val langId = when (lang) { + "es" -> 1 + "en" -> 0 + "fr" -> 2 + else -> 0 + } + val langAnJson = childrenJson!![langId].jsonObject["children"]!!.jsonArray + langAnJson.forEach { + val anName = it.jsonObject["text"].toString().replace("\"", "") + val anId = it.jsonObject["li_attr"]!!.jsonObject["ident"].toString().replace("\"", "") + val anStatus = if (anName.contains("Completo")) SAnime.COMPLETED else SAnime.ONGOING + val thumUrl = thumAnimeParser(anName) + animes.add( + SAnime.create().apply { + title = anName + status = anStatus + url = "https://www.zippyshare.com/onepace/$anId/dir.html" + thumbnail_url = thumUrl + } + ) + } + + return AnimesPage(animes, false) + } + + private fun thumAnimeParser(animeName: String): String { + val document = client.newCall(GET("https://onepace.net/_next/data/BM0nGdjN96o4xOSQR37x8/es/watch.json")).execute().asJsoup() + val jsonResponse = json.decodeFromString(document.body().text())["pageProps"]!! + val arcsJson = jsonResponse.jsonObject["arcs"]!!.jsonArray + arcsJson.forEach { + val thumId = it.jsonObject["images"]!!.jsonArray[0].jsonObject["src"].toString().replace("\"", "") + val langTitle = it.jsonObject["translations"]!!.jsonArray + langTitle.forEach { j -> + val langCode = j.jsonObject["language"]!!.jsonObject["code"] + if (langCode.toString().replace("\"", "") == lang) { + val title = j.jsonObject["title"].toString().replace("\"", "") + if (animeName.lowercase().contains(title.lowercase())) return "https://onepace.net/_next/image?url=%2Fimages%2Farcs%2F$thumId&w=828&q=75" + } + } + } + return "" + } + + override fun popularAnimeRequest(page: Int): Request = GET(baseUrl) + + override fun popularAnimeNextPageSelector() = throw Exception("not used") + + override fun popularAnimeSelector() = throw Exception("not used") + + override fun popularAnimeFromElement(element: Element) = throw Exception("not used") + + override fun episodeListParse(response: Response): List { + val episodes = mutableListOf() + val Realurl = response.request.url.toString().substringAfter("%23") + val jsoup = client.newCall(GET(Realurl)).execute().asJsoup() + jsoup.select("table.listingplikow tbody tr.filerow.even").forEach { + val epName = it.select("td.cien a.name").text().replace(".mp4", "") + val epNum = epName.substringAfter("][").substringBefore("]").replace("-", ".").replace(",", ".").toFloat() + val epUrl = it.select("td.cien a.name").attr("href") + episodes.add( + SEpisode.create().apply { + name = epName + url = epUrl + episode_number = epNum + } + ) + } + + return episodes + } + + override fun episodeListSelector() = throw Exception("not used") + + override fun episodeFromElement(element: Element) = throw Exception("not used") + + override fun videoListParse(response: Response): List