diff --git a/src/all/nhentai/AndroidManifest.xml b/src/all/nhentai/AndroidManifest.xml new file mode 100644 index 000000000..a548905b1 --- /dev/null +++ b/src/all/nhentai/AndroidManifest.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android"> + + <application> + + <activity + android:name=".NHUrlActivity" + android:theme="@android:style/Theme.NoDisplay" + android:excludeFromRecents="true"> + <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:scheme="https" + android:host="nhentai.net" + android:pathPattern="/g/..*" /> + </intent-filter> + </activity> + </application> + +</manifest> diff --git a/src/all/nhentai/build.gradle b/src/all/nhentai/build.gradle index b2859bdab..5bbebf184 100644 --- a/src/all/nhentai/build.gradle +++ b/src/all/nhentai/build.gradle @@ -5,7 +5,7 @@ ext { appName = 'Tachiyomi: NHentai' pkgNameSuffix = 'all.nhentai' extClass = '.NHEnglish; .NHJapanese; .NHChinese' - extVersionCode = 9 + extVersionCode = 10 libVersion = '1.2' } diff --git a/src/all/nhentai/src/eu/kanade/tachiyomi/extension/all/nhentai/NHUrlActivity.kt b/src/all/nhentai/src/eu/kanade/tachiyomi/extension/all/nhentai/NHUrlActivity.kt new file mode 100644 index 000000000..9009e102f --- /dev/null +++ b/src/all/nhentai/src/eu/kanade/tachiyomi/extension/all/nhentai/NHUrlActivity.kt @@ -0,0 +1,37 @@ +package eu.kanade.tachiyomi.extension.all.nhentai + +import android.app.Activity +import android.content.ActivityNotFoundException +import android.content.Intent +import android.os.Bundle +import android.util.Log + +/** + * Springboard that accepts https://nhentai.net/g/xxxxxx intents and redirects them to + * the main Tachiyomi process. + */ +class NHUrlActivity : Activity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + val pathSegments = intent?.data?.pathSegments + if (pathSegments != null && pathSegments.size > 1) { + val id = pathSegments[1] + val mainIntent = Intent().apply { + action = "eu.kanade.tachiyomi.SEARCH" + putExtra("query", "${NHentai.PREFIX_ID_SEARCH}$id") + putExtra("filter", packageName) + } + + try { + startActivity(mainIntent) + } catch (e: ActivityNotFoundException) { + Log.e("NHUrlActivity", e.toString()) + } + } else { + Log.e("NHUrlActivity", "could not parse uri from intent $intent") + } + + finish() + System.exit(0) + } +} diff --git a/src/all/nhentai/src/eu/kanade/tachiyomi/extension/all/nhentai/NHentai.kt b/src/all/nhentai/src/eu/kanade/tachiyomi/extension/all/nhentai/NHentai.kt index 6789aa3fe..5dc727f49 100644 --- a/src/all/nhentai/src/eu/kanade/tachiyomi/extension/all/nhentai/NHentai.kt +++ b/src/all/nhentai/src/eu/kanade/tachiyomi/extension/all/nhentai/NHentai.kt @@ -6,7 +6,9 @@ import eu.kanade.tachiyomi.extension.all.nhentai.NHUtils.Companion.getGroups import eu.kanade.tachiyomi.extension.all.nhentai.NHUtils.Companion.getTags import eu.kanade.tachiyomi.extension.all.nhentai.NHUtils.Companion.getTime import eu.kanade.tachiyomi.network.GET +import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.source.model.FilterList +import eu.kanade.tachiyomi.source.model.MangasPage import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SManga @@ -19,6 +21,7 @@ import okhttp3.Request import okhttp3.Response import org.jsoup.nodes.Document import org.jsoup.nodes.Element +import rx.Observable open class NHentai(override val lang: String, private val nhLang: String) : ParsedHttpSource() { @@ -56,6 +59,17 @@ open class NHentai(override val lang: String, private val nhLang: String) : Pars override fun popularMangaNextPageSelector() = latestUpdatesNextPageSelector() + override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable<MangasPage> { + return if (query.startsWith(PREFIX_ID_SEARCH)) { + val id = query.removePrefix(PREFIX_ID_SEARCH) + client.newCall(searchMangaByIdRequest(id)) + .asObservableSuccess() + .map { response -> searchMangaByIdParse(response, id) } + } else { + return super.fetchSearchManga(page, query, filters) + } + } + override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { val url = HttpUrl.parse("$baseUrl/search")!!.newBuilder() .addQueryParameter("q", "$query +$nhLang") @@ -70,6 +84,14 @@ open class NHentai(override val lang: String, private val nhLang: String) : Pars return GET(url.build().toString(), headers) } + private fun searchMangaByIdRequest(id: String) = GET("$baseUrl/g/$id", headers) + + private fun searchMangaByIdParse(response: Response, id: String): MangasPage { + val details = mangaDetailsParse(response) + details.url = "/g/$id/" + return MangasPage(listOf(details), false) + } + override fun searchMangaFromElement(element: Element) = latestUpdatesFromElement(element) override fun searchMangaSelector() = latestUpdatesSelector() @@ -122,4 +144,8 @@ open class NHentai(override val lang: String, private val nhLang: String) : Pars override fun imageUrlParse(document: Document) = throw UnsupportedOperationException("Not used") + companion object { + const val PREFIX_ID_SEARCH = "id:" + } + }