Cubari: simplify url handling and search (#11216)
* migrate to keiyoushi.utils.parseAs * Refactor: Simplify URL handling - Pass URLs directly to search instead of pre-parsing in CubariUrlActivity - Remove custom `cubari:` prefix and parser - Handle direct URL searching in the main source file - Add support for Gist URLs - Remove redundant intent filters from AndroidManifest * bump and fix useragent * fix url * update useragent * trailing comma
This commit is contained in:
parent
775d39331e
commit
5a004d08f5
@ -32,19 +32,6 @@
|
|||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
<category android:name="android.intent.category.BROWSABLE" />
|
<category android:name="android.intent.category.BROWSABLE" />
|
||||||
|
|
||||||
<data android:host="*.guya.moe" />
|
|
||||||
<data android:host="guya.moe" />
|
|
||||||
|
|
||||||
<data
|
|
||||||
android:pathPattern="/proxy/..*"
|
|
||||||
android:scheme="https" />
|
|
||||||
</intent-filter>
|
|
||||||
<intent-filter>
|
|
||||||
<action android:name="android.intent.action.VIEW" />
|
|
||||||
|
|
||||||
<category android:name="android.intent.category.DEFAULT" />
|
|
||||||
<category android:name="android.intent.category.BROWSABLE" />
|
|
||||||
|
|
||||||
<data android:host="*.imgur.com" />
|
<data android:host="*.imgur.com" />
|
||||||
<data android:host="imgur.com" />
|
<data android:host="imgur.com" />
|
||||||
|
|
||||||
|
|||||||
@ -20,6 +20,6 @@ If you've setup the Remote Storage via WebView the Recent tab shows your recent,
|
|||||||
You can visit the [Cubari](https://cubari.moe/) website for for more information.
|
You can visit the [Cubari](https://cubari.moe/) website for for more information.
|
||||||
|
|
||||||
### How do I add a gallery to Cubari?
|
### How do I add a gallery to Cubari?
|
||||||
You can directly open a imgur or Cubari link in the extension.
|
You can directly open a imgur or Cubari link in the extension or paste the url in cubari browse
|
||||||
|
|
||||||
[Uncomment this if needed]: <> (## Guides)
|
[Uncomment this if needed]: <> (## Guides)
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
ext {
|
ext {
|
||||||
extName = 'Cubari'
|
extName = 'Cubari'
|
||||||
extClass = '.CubariFactory'
|
extClass = '.CubariFactory'
|
||||||
extVersionCode = 25
|
extVersionCode = 26
|
||||||
}
|
}
|
||||||
|
|
||||||
apply from: "$rootDir/common.gradle"
|
apply from: "$rootDir/common.gradle"
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
package eu.kanade.tachiyomi.extension.all.cubari
|
package eu.kanade.tachiyomi.extension.all.cubari
|
||||||
|
|
||||||
import android.app.Application
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
import android.util.Base64
|
||||||
import eu.kanade.tachiyomi.AppInfo
|
import eu.kanade.tachiyomi.AppInfo
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.network.asObservable
|
import eu.kanade.tachiyomi.network.asObservable
|
||||||
@ -12,7 +12,7 @@ import eu.kanade.tachiyomi.source.model.Page
|
|||||||
import eu.kanade.tachiyomi.source.model.SChapter
|
import eu.kanade.tachiyomi.source.model.SChapter
|
||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||||
import kotlinx.serialization.json.Json
|
import keiyoushi.utils.parseAs
|
||||||
import kotlinx.serialization.json.JsonArray
|
import kotlinx.serialization.json.JsonArray
|
||||||
import kotlinx.serialization.json.JsonObject
|
import kotlinx.serialization.json.JsonObject
|
||||||
import kotlinx.serialization.json.boolean
|
import kotlinx.serialization.json.boolean
|
||||||
@ -20,23 +20,18 @@ import kotlinx.serialization.json.double
|
|||||||
import kotlinx.serialization.json.jsonArray
|
import kotlinx.serialization.json.jsonArray
|
||||||
import kotlinx.serialization.json.jsonObject
|
import kotlinx.serialization.json.jsonObject
|
||||||
import kotlinx.serialization.json.jsonPrimitive
|
import kotlinx.serialization.json.jsonPrimitive
|
||||||
import okhttp3.Headers
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import uy.kohesive.injekt.Injekt
|
|
||||||
import uy.kohesive.injekt.api.get
|
|
||||||
import uy.kohesive.injekt.injectLazy
|
|
||||||
|
|
||||||
open class Cubari(override val lang: String) : HttpSource() {
|
class Cubari(override val lang: String) : HttpSource() {
|
||||||
|
|
||||||
final override val name = "Cubari"
|
override val name = "Cubari"
|
||||||
|
|
||||||
final override val baseUrl = "https://cubari.moe"
|
override val baseUrl = "https://cubari.moe"
|
||||||
|
|
||||||
final override val supportsLatest = true
|
override val supportsLatest = true
|
||||||
|
|
||||||
private val json: Json by injectLazy()
|
|
||||||
|
|
||||||
override val client = network.cloudflareClient.newBuilder()
|
override val client = network.cloudflareClient.newBuilder()
|
||||||
.addInterceptor { chain ->
|
.addInterceptor { chain ->
|
||||||
@ -48,18 +43,17 @@ open class Cubari(override val lang: String) : HttpSource() {
|
|||||||
}
|
}
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
override fun headersBuilder() = Headers.Builder().apply {
|
private val cubariHeaders = super.headersBuilder()
|
||||||
add(
|
.set(
|
||||||
"User-Agent",
|
"User-Agent",
|
||||||
"(Android ${Build.VERSION.RELEASE}; " +
|
"(Android ${Build.VERSION.RELEASE}; " +
|
||||||
"${Build.MANUFACTURER} ${Build.MODEL}) " +
|
"${Build.MANUFACTURER} ${Build.MODEL}) " +
|
||||||
"Tachiyomi/${AppInfo.getVersionName()} " +
|
"Tachiyomi/${AppInfo.getVersionName()} ${Build.ID} " +
|
||||||
Build.ID,
|
"Keiyoushi",
|
||||||
)
|
).build()
|
||||||
}
|
|
||||||
|
|
||||||
override fun latestUpdatesRequest(page: Int): Request {
|
override fun latestUpdatesRequest(page: Int): Request {
|
||||||
return GET("$baseUrl/", headers)
|
return GET("$baseUrl/", cubariHeaders)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun fetchLatestUpdates(page: Int): Observable<MangasPage> {
|
override fun fetchLatestUpdates(page: Int): Observable<MangasPage> {
|
||||||
@ -72,12 +66,12 @@ open class Cubari(override val lang: String) : HttpSource() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun latestUpdatesParse(response: Response): MangasPage {
|
override fun latestUpdatesParse(response: Response): MangasPage {
|
||||||
val result = json.parseToJsonElement(response.body.string()).jsonArray
|
val result = response.parseAs<JsonArray>()
|
||||||
return parseMangaList(result, SortType.UNPINNED)
|
return parseMangaList(result, SortType.UNPINNED)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun popularMangaRequest(page: Int): Request {
|
override fun popularMangaRequest(page: Int): Request {
|
||||||
return GET("$baseUrl/", headers)
|
return GET("$baseUrl/", cubariHeaders)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun fetchPopularManga(page: Int): Observable<MangasPage> {
|
override fun fetchPopularManga(page: Int): Observable<MangasPage> {
|
||||||
@ -90,19 +84,22 @@ open class Cubari(override val lang: String) : HttpSource() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun popularMangaParse(response: Response): MangasPage {
|
override fun popularMangaParse(response: Response): MangasPage {
|
||||||
val result = json.parseToJsonElement(response.body.string()).jsonArray
|
val result = response.parseAs<JsonArray>()
|
||||||
return parseMangaList(result, SortType.PINNED)
|
return parseMangaList(result, SortType.PINNED)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun fetchMangaDetails(manga: SManga): Observable<SManga> {
|
override fun fetchMangaDetails(manga: SManga): Observable<SManga> {
|
||||||
return client.newCall(chapterListRequest(manga))
|
return client.newCall(mangaDetailsRequest(manga))
|
||||||
.asObservableSuccess()
|
.asObservableSuccess()
|
||||||
.map { response -> mangaDetailsParse(response, manga) }
|
.map { response -> mangaDetailsParse(response, manga) }
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called when the series is loaded, or when opening in browser
|
override fun getMangaUrl(manga: SManga): String {
|
||||||
|
return "$baseUrl${manga.url}"
|
||||||
|
}
|
||||||
|
|
||||||
override fun mangaDetailsRequest(manga: SManga): Request {
|
override fun mangaDetailsRequest(manga: SManga): Request {
|
||||||
return GET("$baseUrl${manga.url}", headers)
|
return chapterListRequest(manga)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun mangaDetailsParse(response: Response): SManga {
|
override fun mangaDetailsParse(response: Response): SManga {
|
||||||
@ -110,7 +107,7 @@ open class Cubari(override val lang: String) : HttpSource() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun mangaDetailsParse(response: Response, manga: SManga): SManga {
|
private fun mangaDetailsParse(response: Response, manga: SManga): SManga {
|
||||||
val result = json.parseToJsonElement(response.body.string()).jsonObject
|
val result = response.parseAs<JsonObject>()
|
||||||
return parseManga(result, manga)
|
return parseManga(result, manga)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -126,17 +123,16 @@ open class Cubari(override val lang: String) : HttpSource() {
|
|||||||
val source = urlComponents[2]
|
val source = urlComponents[2]
|
||||||
val slug = urlComponents[3]
|
val slug = urlComponents[3]
|
||||||
|
|
||||||
return GET("$baseUrl/read/api/$source/series/$slug/", headers)
|
return GET("$baseUrl/read/api/$source/series/$slug/", cubariHeaders)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun chapterListParse(response: Response): List<SChapter> {
|
override fun chapterListParse(response: Response): List<SChapter> {
|
||||||
throw Exception("Unused")
|
throw UnsupportedOperationException()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called after the request
|
// Called after the request
|
||||||
private fun chapterListParse(response: Response, manga: SManga): List<SChapter> {
|
private fun chapterListParse(response: Response, manga: SManga): List<SChapter> {
|
||||||
val res = response.body.string()
|
return parseChapterList(response, manga)
|
||||||
return parseChapterList(res, manga)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun fetchPageList(chapter: SChapter): Observable<List<Page>> {
|
override fun fetchPageList(chapter: SChapter): Observable<List<Page>> {
|
||||||
@ -161,21 +157,20 @@ open class Cubari(override val lang: String) : HttpSource() {
|
|||||||
override fun pageListRequest(chapter: SChapter): Request {
|
override fun pageListRequest(chapter: SChapter): Request {
|
||||||
return when {
|
return when {
|
||||||
chapter.url.contains("/chapter/") -> {
|
chapter.url.contains("/chapter/") -> {
|
||||||
GET("$baseUrl${chapter.url}", headers)
|
GET("$baseUrl${chapter.url}", cubariHeaders)
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
val url = chapter.url.split("/")
|
val url = chapter.url.split("/")
|
||||||
val source = url[2]
|
val source = url[2]
|
||||||
val slug = url[3]
|
val slug = url[3]
|
||||||
|
|
||||||
GET("$baseUrl/read/api/$source/series/$slug/", headers)
|
GET("$baseUrl/read/api/$source/series/$slug/", cubariHeaders)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun directPageListParse(response: Response): List<Page> {
|
private fun directPageListParse(response: Response): List<Page> {
|
||||||
val res = response.body.string()
|
val pages = response.parseAs<JsonArray>()
|
||||||
val pages = json.parseToJsonElement(res).jsonArray
|
|
||||||
|
|
||||||
return pages.mapIndexed { i, jsonEl ->
|
return pages.mapIndexed { i, jsonEl ->
|
||||||
val page = if (jsonEl is JsonObject) {
|
val page = if (jsonEl is JsonObject) {
|
||||||
@ -189,7 +184,7 @@ open class Cubari(override val lang: String) : HttpSource() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun seriesJsonPageListParse(response: Response, chapter: SChapter): List<Page> {
|
private fun seriesJsonPageListParse(response: Response, chapter: SChapter): List<Page> {
|
||||||
val jsonObj = json.parseToJsonElement(response.body.string()).jsonObject
|
val jsonObj = response.parseAs<JsonObject>()
|
||||||
val groups = jsonObj["groups"]!!.jsonObject
|
val groups = jsonObj["groups"]!!.jsonObject
|
||||||
val groupMap = groups.entries.associateBy({ it.value.jsonPrimitive.content.ifEmpty { "default" } }, { it.key })
|
val groupMap = groups.entries.associateBy({ it.value.jsonPrimitive.content.ifEmpty { "default" } }, { it.key })
|
||||||
val chapterScanlator = chapter.scanlator ?: "default" // workaround for "" as group causing NullPointerException (#13772)
|
val chapterScanlator = chapter.scanlator ?: "default" // workaround for "" as group causing NullPointerException (#13772)
|
||||||
@ -222,23 +217,29 @@ open class Cubari(override val lang: String) : HttpSource() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stub
|
|
||||||
override fun pageListParse(response: Response): List<Page> {
|
override fun pageListParse(response: Response): List<Page> {
|
||||||
throw Exception("Unused")
|
throw UnsupportedOperationException()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> {
|
override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> {
|
||||||
return when {
|
return when {
|
||||||
query.startsWith(PROXY_PREFIX) -> {
|
// handle direct links or old cubari:source/id format
|
||||||
val trimmedQuery = query.removePrefix(PROXY_PREFIX)
|
query.startsWith("https://") || query.startsWith("cubari:") -> {
|
||||||
|
val (source, slug) = deepLinkHandler(query)
|
||||||
// Only tag for recently read on search
|
// Only tag for recently read on search
|
||||||
client.newBuilder()
|
client.newBuilder()
|
||||||
.addInterceptor(RemoteStorageUtils.TagInterceptor())
|
.addInterceptor(RemoteStorageUtils.TagInterceptor())
|
||||||
.build()
|
.build()
|
||||||
.newCall(proxySearchRequest(trimmedQuery))
|
.newCall(GET("$baseUrl/read/api/$source/series/$slug/", cubariHeaders))
|
||||||
.asObservableSuccess()
|
.asObservableSuccess()
|
||||||
.map { response ->
|
.map { response ->
|
||||||
proxySearchParse(response, trimmedQuery)
|
val result = response.parseAs<JsonObject>()
|
||||||
|
val manga = SManga.create().apply {
|
||||||
|
url = "/read/$source/$slug"
|
||||||
|
}
|
||||||
|
val mangaList = listOf(parseManga(result, manga))
|
||||||
|
|
||||||
|
MangasPage(mangaList, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
@ -259,18 +260,57 @@ open class Cubari(override val lang: String) : HttpSource() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||||
return GET("$baseUrl/", headers)
|
return GET("$baseUrl/", cubariHeaders)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun proxySearchRequest(query: String): Request {
|
private fun deepLinkHandler(query: String): Pair<String, String> {
|
||||||
try {
|
return if (query.startsWith("cubari:")) { // legacy cubari:source/slug format
|
||||||
val queryFragments = query.split("/")
|
val queryFragments = query.substringAfter("cubari:").split("/", limit = 2)
|
||||||
val source = queryFragments[0]
|
queryFragments[0] to queryFragments[1]
|
||||||
val slug = queryFragments[1]
|
} else { // direct url searching
|
||||||
|
val url = query.toHttpUrl()
|
||||||
|
val host = url.host
|
||||||
|
val pathSegments = url.pathSegments
|
||||||
|
|
||||||
return GET("$baseUrl/read/api/$source/series/$slug/", headers)
|
if (
|
||||||
} catch (e: Exception) {
|
host.endsWith("imgur.com") &&
|
||||||
throw Exception(SEARCH_FALLBACK_MSG)
|
pathSegments.size >= 2 &&
|
||||||
|
pathSegments[0] in listOf("a", "gallery")
|
||||||
|
) {
|
||||||
|
"imgur" to pathSegments[1]
|
||||||
|
} else if (
|
||||||
|
host.endsWith("reddit.com") &&
|
||||||
|
pathSegments.size >= 2 &&
|
||||||
|
pathSegments[0] == "gallery"
|
||||||
|
) {
|
||||||
|
"reddit" to pathSegments[1]
|
||||||
|
} else if (
|
||||||
|
host == "imgchest.com" &&
|
||||||
|
pathSegments.size >= 2 &&
|
||||||
|
pathSegments[0] == "p"
|
||||||
|
) {
|
||||||
|
"imgchest" to pathSegments[1]
|
||||||
|
} else if (
|
||||||
|
host.endsWith("catbox.moe") &&
|
||||||
|
pathSegments.size >= 2 &&
|
||||||
|
pathSegments[0] == "c"
|
||||||
|
) {
|
||||||
|
"catbox" to pathSegments[1]
|
||||||
|
} else if (
|
||||||
|
host.endsWith("cubari.moe") &&
|
||||||
|
pathSegments.size >= 3
|
||||||
|
) {
|
||||||
|
pathSegments[1] to pathSegments[2]
|
||||||
|
} else if (
|
||||||
|
host.endsWith(".githubusercontent.com")
|
||||||
|
) {
|
||||||
|
val src = host.substringBefore(".")
|
||||||
|
val path = url.encodedPath
|
||||||
|
|
||||||
|
"gist" to Base64.encodeToString("$src$path".toByteArray(), Base64.NO_PADDING)
|
||||||
|
} else {
|
||||||
|
throw Exception(SEARCH_FALLBACK_MSG)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -279,7 +319,7 @@ open class Cubari(override val lang: String) : HttpSource() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun searchMangaParse(response: Response, query: String): MangasPage {
|
private fun searchMangaParse(response: Response, query: String): MangasPage {
|
||||||
val result = json.parseToJsonElement(response.body.string()).jsonArray
|
val result = response.parseAs<JsonArray>()
|
||||||
|
|
||||||
val filterList = result.asSequence()
|
val filterList = result.asSequence()
|
||||||
.map { it as JsonObject }
|
.map { it as JsonObject }
|
||||||
@ -289,23 +329,14 @@ open class Cubari(override val lang: String) : HttpSource() {
|
|||||||
return parseMangaList(JsonArray(filterList), SortType.ALL)
|
return parseMangaList(JsonArray(filterList), SortType.ALL)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun proxySearchParse(response: Response, query: String): MangasPage {
|
|
||||||
val result = json.parseToJsonElement(response.body.string()).jsonObject
|
|
||||||
return parseSearchList(result, query)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ------------- Helpers and whatnot ---------------
|
// ------------- Helpers and whatnot ---------------
|
||||||
|
|
||||||
private val volumeNotSpecifiedTerms = setOf("Uncategorized", "null", "")
|
private val volumeNotSpecifiedTerms = setOf("Uncategorized", "null", "")
|
||||||
|
|
||||||
private fun parseChapterList(payload: String, manga: SManga): List<SChapter> {
|
private fun parseChapterList(response: Response, manga: SManga): List<SChapter> {
|
||||||
val jsonObj = json.parseToJsonElement(payload).jsonObject
|
val jsonObj = response.parseAs<JsonObject>()
|
||||||
val groups = jsonObj["groups"]!!.jsonObject
|
val groups = jsonObj["groups"]!!.jsonObject
|
||||||
val chapters = jsonObj["chapters"]!!.jsonObject
|
val chapters = jsonObj["chapters"]!!.jsonObject
|
||||||
val seriesSlug = jsonObj["slug"]!!.jsonPrimitive.content
|
|
||||||
|
|
||||||
val seriesPrefs = Injekt.get<Application>().getSharedPreferences("source_${id}_updateTime:$seriesSlug", 0)
|
|
||||||
val seriesPrefsEditor = seriesPrefs.edit()
|
|
||||||
|
|
||||||
val chapterList = chapters.entries.flatMap { chapterEntry ->
|
val chapterList = chapters.entries.flatMap { chapterEntry ->
|
||||||
val chapterNum = chapterEntry.key
|
val chapterNum = chapterEntry.key
|
||||||
@ -327,13 +358,7 @@ open class Cubari(override val lang: String) : HttpSource() {
|
|||||||
date_upload = if (releaseDate != null) {
|
date_upload = if (releaseDate != null) {
|
||||||
releaseDate.jsonPrimitive.double.toLong() * 1000
|
releaseDate.jsonPrimitive.double.toLong() * 1000
|
||||||
} else {
|
} else {
|
||||||
val currentTimeMillis = System.currentTimeMillis()
|
0L
|
||||||
|
|
||||||
if (!seriesPrefs.contains(chapterNum)) {
|
|
||||||
seriesPrefsEditor.putLong(chapterNum, currentTimeMillis)
|
|
||||||
}
|
|
||||||
|
|
||||||
seriesPrefs.getLong(chapterNum, currentTimeMillis)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
name = buildString {
|
name = buildString {
|
||||||
@ -351,8 +376,6 @@ open class Cubari(override val lang: String) : HttpSource() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
seriesPrefsEditor.apply()
|
|
||||||
|
|
||||||
return chapterList.sortedByDescending { it.chapter_number }
|
return chapterList.sortedByDescending { it.chapter_number }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -375,16 +398,6 @@ open class Cubari(override val lang: String) : HttpSource() {
|
|||||||
return MangasPage(mangaList, false)
|
return MangasPage(mangaList, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun parseSearchList(payload: JsonObject, query: String): MangasPage {
|
|
||||||
val tempManga = SManga.create().apply {
|
|
||||||
url = "/read/$query"
|
|
||||||
}
|
|
||||||
|
|
||||||
val mangaList = listOf(parseManga(payload, tempManga))
|
|
||||||
|
|
||||||
return MangasPage(mangaList, false)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun parseManga(jsonObj: JsonObject, mangaReference: SManga? = null): SManga =
|
private fun parseManga(jsonObj: JsonObject, mangaReference: SManga? = null): SManga =
|
||||||
SManga.create().apply {
|
SManga.create().apply {
|
||||||
title = jsonObj["title"]!!.jsonPrimitive.content
|
title = jsonObj["title"]!!.jsonPrimitive.content
|
||||||
@ -413,11 +426,10 @@ open class Cubari(override val lang: String) : HttpSource() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val PROXY_PREFIX = "cubari:"
|
|
||||||
const val AUTHOR_FALLBACK = "Unknown"
|
const val AUTHOR_FALLBACK = "Unknown"
|
||||||
const val ARTIST_FALLBACK = "Unknown"
|
const val ARTIST_FALLBACK = "Unknown"
|
||||||
const val DESCRIPTION_FALLBACK = "No description."
|
const val DESCRIPTION_FALLBACK = "No description."
|
||||||
const val SEARCH_FALLBACK_MSG = "Unable to parse. Is your query in the format of $PROXY_PREFIX<source>/<slug>?"
|
const val SEARCH_FALLBACK_MSG = "Please enter a valid Cubari URL"
|
||||||
|
|
||||||
enum class SortType {
|
enum class SortType {
|
||||||
PINNED,
|
PINNED,
|
||||||
|
|||||||
@ -11,59 +11,20 @@ class CubariUrlActivity : Activity() {
|
|||||||
|
|
||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
val host = intent?.data?.host
|
|
||||||
val pathSegments = intent?.data?.pathSegments
|
|
||||||
|
|
||||||
if (host != null && pathSegments != null) {
|
val mainIntent = Intent().apply {
|
||||||
val query = with(host) {
|
action = "eu.kanade.tachiyomi.SEARCH"
|
||||||
when {
|
putExtra("query", intent.data.toString())
|
||||||
equals("m.imgur.com") || equals("imgur.com") -> fromSource("imgur", pathSegments)
|
putExtra("filter", packageName)
|
||||||
equals("m.reddit.com") || equals("reddit.com") || equals("www.reddit.com") -> fromSource("reddit", pathSegments)
|
}
|
||||||
equals("imgchest.com") -> fromSource("imgchest", pathSegments)
|
|
||||||
equals("catbox.moe") || equals("www.catbox.moe") -> fromSource("catbox", pathSegments)
|
|
||||||
else -> fromCubari(pathSegments)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (query == null) {
|
try {
|
||||||
Log.e("CubariUrlActivity", "Unable to parse URI from intent $intent")
|
startActivity(mainIntent)
|
||||||
finish()
|
} catch (e: ActivityNotFoundException) {
|
||||||
exitProcess(1)
|
Log.e("CubariUrlActivity", "Unable to find activity", e)
|
||||||
}
|
|
||||||
|
|
||||||
val mainIntent = Intent().apply {
|
|
||||||
action = "eu.kanade.tachiyomi.SEARCH"
|
|
||||||
putExtra("query", query)
|
|
||||||
putExtra("filter", packageName)
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
startActivity(mainIntent)
|
|
||||||
} catch (e: ActivityNotFoundException) {
|
|
||||||
Log.e("CubariUrlActivity", e.toString())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
finish()
|
finish()
|
||||||
exitProcess(0)
|
exitProcess(0)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun fromSource(source: String, pathSegments: List<String>): String? {
|
|
||||||
if (pathSegments.size >= 2) {
|
|
||||||
val id = pathSegments[1]
|
|
||||||
|
|
||||||
return "${Cubari.PROXY_PREFIX}$source/$id"
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun fromCubari(pathSegments: MutableList<String>): String? {
|
|
||||||
return if (pathSegments.size >= 3) {
|
|
||||||
val source = pathSegments[1]
|
|
||||||
val slug = pathSegments[2]
|
|
||||||
"${Cubari.PROXY_PREFIX}$source/$slug"
|
|
||||||
} else {
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user