Webtoons: Add Search By Url + Deeplinking (#7026)

This commit is contained in:
h-hyuuga 2021-05-16 15:20:54 -04:00 committed by GitHub
parent 759b614000
commit 640b5f035d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 123 additions and 1 deletions

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="eu.kanade.tachiyomi.extension">
<application>
<activity
android:name="eu.kanade.tachiyomi.multisrc.webtoons.WebtoonsUrlActivity"
android:excludeFromRecents="true"
android:theme="@android:style/Theme.NoDisplay">
<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="webtoons.com"
android:pathPattern="/.*/.*/.*/..*"
android:scheme="https" />
<data
android:host="www.webtoons.com"
android:pathPattern="/.*/.*/.*/..*"
android:scheme="https" />
<data
android:host="m.webtoons.com"
android:pathPattern="/.*/.*/.*/..*"
android:scheme="https" />
<data
android:host="webtoons.com"
android:pathPattern="/.*/.*/.*/.*/..*"
android:scheme="https" />
<data
android:host="www.webtoons.com"
android:pathPattern="/.*/.*/.*/.*/..*"
android:scheme="https" />
<data
android:host="m.webtoons.com"
android:pathPattern="/.*/.*/.*/.*/..*"
android:scheme="https" />
</intent-filter>
</activity>
</application>
</manifest>

View File

@ -22,6 +22,7 @@ import okhttp3.Response
import org.json.JSONObject
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import rx.Observable
import java.text.SimpleDateFormat
import java.util.Calendar
import java.util.Locale
@ -129,6 +130,35 @@ open class Webtoons(
override fun latestUpdatesNextPageSelector(): String? = null
override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> {
if (!query.startsWith(URL_SEARCH_PREFIX))
return super.fetchSearchManga(page, query, filters)
val emptyResult = Observable.just(MangasPage(emptyList(), false))
// given a url to either a webtoon or an episode, returns a url path to corresponding webtoon
fun webtoonPath(u: HttpUrl) = when {
langCode == u.pathSegments[0] -> "/${u.pathSegments[0]}/${u.pathSegments[1]}/${u.pathSegments[2]}/list"
else -> "/${u.pathSegments[0]}/${u.pathSegments[1]}/list" // dongmanmanhua doesn't include langCode
}
return query.substringAfter(URL_SEARCH_PREFIX).toHttpUrlOrNull()?.let { url ->
val title_no = url.queryParameter("title_no")
val couldBeWebtoonOrEpisode = title_no != null && (url.pathSegments.size >= 3 && url.pathSegments.last().isNotEmpty())
val isThisLang = "$url".startsWith("$baseUrl/$langCode")
if (! (couldBeWebtoonOrEpisode && isThisLang))
emptyResult
else{
val potentialUrl = "${webtoonPath(url)}?title_no=$title_no"
fetchMangaDetails(SManga.create().apply { this.url = potentialUrl }).map {
it.url = potentialUrl
MangasPage(listOf(it), false)
}
}
} ?: emptyResult
}
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val url = "$baseUrl/$langCode/search?keyword=$query".toHttpUrlOrNull()?.newBuilder()!!
val uriPart = (filters.find { it is SearchType } as? SearchType)?.toUriPart() ?: ""
@ -156,6 +186,7 @@ open class Webtoons(
val infoElement = document.select("#_asideDetail")
val manga = SManga.create()
manga.title = document.selectFirst("h1.subj").text()
manga.author = detailElement.select(".author:nth-of-type(1)").first()?.ownText()
manga.artist = detailElement.select(".author:nth-of-type(2)").first()?.ownText() ?: manga.author
manga.genre = detailElement.select(".genre").joinToString(", ") { it.text() }
@ -241,4 +272,8 @@ open class Webtoons(
Page(i, "", motiontoonPath + motiontoonJson.getString(key))
}
}
companion object {
const val URL_SEARCH_PREFIX = "url:"
}
}

View File

@ -13,7 +13,7 @@ class WebtoonsGenerator : ThemeSourceGenerator {
override val baseVersionCode: Int = 1
override val sources = listOf(
MultiLang("Webtoons.com", "https://www.webtoons.com", listOf("en", "fr", "es", "id", "th", "zh"), className = "WebtoonsFactory", pkgName = "webtoons", overrideVersionCode = 27),
MultiLang("Webtoons.com", "https://www.webtoons.com", listOf("en", "fr", "es", "id", "th", "zh"), className = "WebtoonsFactory", pkgName = "webtoons", overrideVersionCode = 28),
SingleLang("Dongman Manhua", "https://www.dongmanmanhua.cn", "zh")
)

View File

@ -0,0 +1,44 @@
package eu.kanade.tachiyomi.multisrc.webtoons
import android.app.Activity
import android.content.ActivityNotFoundException
import android.content.Intent
import android.os.Bundle
import android.util.Log
import kotlin.system.exitProcess
/**
* Springboard that accepts https://mangadex.com/title/xxx intents and redirects them to
* the main tachiyomi process. The idea is to not install the intent filter unless
* you have this extension installed, but still let the main tachiyomi app control
* things.
*
* Main goal was to make it easier to open manga in Tachiyomi in spite of the DDoS blocking
* the usual search screen from working.
*/
class WebtoonsUrlActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val pathSegments = intent?.data?.pathSegments
val title_no = intent?.data?.getQueryParameter("title_no")
if (pathSegments != null && pathSegments.size >= 3 && title_no != null) {
val mainIntent = Intent().apply {
action = "eu.kanade.tachiyomi.SEARCH"
putExtra("query", "${Webtoons.URL_SEARCH_PREFIX}${intent?.data?.toString()}")
putExtra("filter", packageName)
}
try {
startActivity(mainIntent)
} catch (e: ActivityNotFoundException) {
Log.e("WebtoonsUrlActivity", e.toString())
}
} else {
Log.e("WebtoonsUrlActivity", "could not parse uri from intent $intent")
}
finish()
exitProcess(0)
}
}