NHentai: use genre for tags, support favorites filter when logged in
This commit is contained in:
parent
0b3e69ec69
commit
906d76a9aa
@ -5,7 +5,7 @@ ext {
|
|||||||
appName = 'Tachiyomi: NHentai'
|
appName = 'Tachiyomi: NHentai'
|
||||||
pkgNameSuffix = 'all.nhentai'
|
pkgNameSuffix = 'all.nhentai'
|
||||||
extClass = '.NHFactory'
|
extClass = '.NHFactory'
|
||||||
extVersionCode = 17
|
extVersionCode = 18
|
||||||
libVersion = '1.2'
|
libVersion = '1.2'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,90 +1,53 @@
|
|||||||
package eu.kanade.tachiyomi.extension.all.nhentai
|
package eu.kanade.tachiyomi.extension.all.nhentai
|
||||||
|
|
||||||
import org.jsoup.nodes.Document
|
import org.jsoup.nodes.Document
|
||||||
|
import org.jsoup.nodes.Element
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
|
|
||||||
class NHUtils {
|
object NHUtils {
|
||||||
companion object {
|
|
||||||
fun getArtists(document: Document): String {
|
fun getArtists(document: Document): String {
|
||||||
val stringBuilder = StringBuilder()
|
|
||||||
val artists = document.select("#tags > div:nth-child(4) > span > a")
|
val artists = document.select("#tags > div:nth-child(4) > span > a")
|
||||||
|
return artists.joinToString(", ") { it.cleanTag() }
|
||||||
artists.forEach {
|
|
||||||
stringBuilder.append(cleanTag(it.text()))
|
|
||||||
|
|
||||||
if (it != artists.last())
|
|
||||||
stringBuilder.append(", ")
|
|
||||||
}
|
|
||||||
|
|
||||||
return stringBuilder.toString()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getGroups(document: Document): String? {
|
fun getGroups(document: Document): String? {
|
||||||
val stringBuilder = StringBuilder()
|
|
||||||
val groups = document.select("#tags > div:nth-child(5) > span > a")
|
val groups = document.select("#tags > div:nth-child(5) > span > a")
|
||||||
|
return if (groups.isNotEmpty()) {
|
||||||
groups.forEach {
|
groups.joinToString(", ") { it.cleanTag() }
|
||||||
stringBuilder.append(cleanTag(it.text()))
|
} else {
|
||||||
|
null
|
||||||
if (it != groups.last())
|
}
|
||||||
stringBuilder.append(", ")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (stringBuilder.toString().isEmpty()) null else stringBuilder.toString()
|
fun getTagDescription(document: Document): String {
|
||||||
}
|
|
||||||
|
|
||||||
fun getTags(document: Document): String {
|
|
||||||
val stringBuilder = StringBuilder()
|
val stringBuilder = StringBuilder()
|
||||||
|
|
||||||
val parodies = document.select("#tags > div:nth-child(1) > span > a")
|
val parodies = document.select("#tags > div:nth-child(1) > span > a")
|
||||||
val characters = document.select("#tags > div:nth-child(2) > span > a")
|
if (parodies.isNotEmpty()) {
|
||||||
val tags = document.select("#tags > div:nth-child(3) > span > a")
|
|
||||||
|
|
||||||
if (parodies.size > 0) {
|
|
||||||
stringBuilder.append("Parodies: ")
|
stringBuilder.append("Parodies: ")
|
||||||
|
stringBuilder.append(parodies.joinToString(", ") { it.cleanTag() })
|
||||||
parodies.forEach {
|
|
||||||
stringBuilder.append(cleanTag(it.text()))
|
|
||||||
|
|
||||||
if (it != parodies.last())
|
|
||||||
stringBuilder.append(", ")
|
|
||||||
}
|
|
||||||
|
|
||||||
stringBuilder.append("\n\n")
|
stringBuilder.append("\n\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (characters.size > 0) {
|
val characters = document.select("#tags > div:nth-child(2) > span > a")
|
||||||
|
if (characters.isNotEmpty()) {
|
||||||
stringBuilder.append("Characters: ")
|
stringBuilder.append("Characters: ")
|
||||||
|
stringBuilder.append(characters.joinToString(", ") { it.cleanTag() })
|
||||||
characters.forEach {
|
|
||||||
stringBuilder.append(cleanTag(it.text()))
|
|
||||||
|
|
||||||
if (it != characters.last())
|
|
||||||
stringBuilder.append(", ")
|
|
||||||
}
|
|
||||||
|
|
||||||
stringBuilder.append("\n\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tags.size > 0) {
|
|
||||||
stringBuilder.append("Tags: ")
|
|
||||||
|
|
||||||
tags.forEach {
|
|
||||||
stringBuilder.append(cleanTag(it.text()))
|
|
||||||
|
|
||||||
if (it != tags.last())
|
|
||||||
stringBuilder.append(", ")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return stringBuilder.toString()
|
return stringBuilder.toString()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getTags(document: Document): String {
|
||||||
|
val tags = document.select("#tags > div:nth-child(3) > span > a")
|
||||||
|
return tags.map { it.cleanTag() }.sorted().joinToString(", ")
|
||||||
|
}
|
||||||
|
|
||||||
fun getTime(document: Document): Long {
|
fun getTime(document: Document): Long {
|
||||||
val timeString = document.toString().substringAfter("datetime=\"").substringBefore("\">").replace("T", " ")
|
val timeString = document.toString().substringAfter("datetime=\"").substringBefore("\">").replace("T", " ")
|
||||||
|
|
||||||
return SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSSZ").parse(timeString).time
|
return SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSSZ").parse(timeString).time
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun cleanTag(tag: String): String = tag.replace(Regex("\\(.*\\)"), "").trim()
|
private fun Element.cleanTag(): String = text().replace(Regex("\\(.*\\)"), "").trim()
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -5,10 +5,11 @@ import android.content.SharedPreferences
|
|||||||
import android.support.v7.preference.ListPreference
|
import android.support.v7.preference.ListPreference
|
||||||
import android.support.v7.preference.PreferenceScreen
|
import android.support.v7.preference.PreferenceScreen
|
||||||
import eu.kanade.tachiyomi.extension.BuildConfig
|
import eu.kanade.tachiyomi.extension.BuildConfig
|
||||||
import eu.kanade.tachiyomi.extension.all.nhentai.NHUtils.Companion.getArtists
|
import eu.kanade.tachiyomi.extension.all.nhentai.NHUtils.getArtists
|
||||||
import eu.kanade.tachiyomi.extension.all.nhentai.NHUtils.Companion.getGroups
|
import eu.kanade.tachiyomi.extension.all.nhentai.NHUtils.getGroups
|
||||||
import eu.kanade.tachiyomi.extension.all.nhentai.NHUtils.Companion.getTags
|
import eu.kanade.tachiyomi.extension.all.nhentai.NHUtils.getTagDescription
|
||||||
import eu.kanade.tachiyomi.extension.all.nhentai.NHUtils.Companion.getTime
|
import eu.kanade.tachiyomi.extension.all.nhentai.NHUtils.getTags
|
||||||
|
import eu.kanade.tachiyomi.extension.all.nhentai.NHUtils.getTime
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.network.asObservableSuccess
|
import eu.kanade.tachiyomi.network.asObservableSuccess
|
||||||
import eu.kanade.tachiyomi.source.ConfigurableSource
|
import eu.kanade.tachiyomi.source.ConfigurableSource
|
||||||
@ -139,17 +140,25 @@ open class NHentai(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
|
||||||
|
val favoriteFilter = filters.findInstance<FavoriteFilter>()
|
||||||
|
if (favoriteFilter != null && favoriteFilter.state) {
|
||||||
|
val url = HttpUrl.parse("$baseUrl/favorites")!!.newBuilder()
|
||||||
|
.addQueryParameter("q", query)
|
||||||
|
.addQueryParameter("page", page.toString())
|
||||||
|
|
||||||
|
return GET(url.toString(), headers)
|
||||||
|
} else {
|
||||||
val url = HttpUrl.parse("$baseUrl/search")!!.newBuilder()
|
val url = HttpUrl.parse("$baseUrl/search")!!.newBuilder()
|
||||||
.addQueryParameter("q", "$query +$nhLang")
|
.addQueryParameter("q", "$query +$nhLang")
|
||||||
.addQueryParameter("page", page.toString())
|
.addQueryParameter("page", page.toString())
|
||||||
|
|
||||||
for (filter in if (filters.isEmpty()) getFilterList() else filters) {
|
filters.findInstance<SortFilter>()?.let { f ->
|
||||||
when (filter) {
|
url.addQueryParameter("sort", f.values[f.state].toLowerCase())
|
||||||
is SortFilter -> url.addQueryParameter("sort", filter.values[filter.state].toLowerCase())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return GET(url.toString(), headers)
|
return GET(url.toString(), headers)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun searchMangaByIdRequest(id: String) = GET("$baseUrl/g/$id", headers)
|
private fun searchMangaByIdRequest(id: String) = GET("$baseUrl/g/$id", headers)
|
||||||
|
|
||||||
@ -159,6 +168,17 @@ open class NHentai(
|
|||||||
return MangasPage(listOf(details), false)
|
return MangasPage(listOf(details), false)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun searchMangaParse(response: Response): MangasPage {
|
||||||
|
if (response.request().url().toString().contains("/login/")) {
|
||||||
|
val document = response.asJsoup()
|
||||||
|
if (document.select(".fa-sign-in").isNotEmpty()) {
|
||||||
|
throw Exception("Log in via WebView to view favorites")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return super.searchMangaParse(response)
|
||||||
|
}
|
||||||
|
|
||||||
override fun searchMangaFromElement(element: Element) = latestUpdatesFromElement(element)
|
override fun searchMangaFromElement(element: Element) = latestUpdatesFromElement(element)
|
||||||
|
|
||||||
override fun searchMangaSelector() = latestUpdatesSelector()
|
override fun searchMangaSelector() = latestUpdatesSelector()
|
||||||
@ -181,7 +201,8 @@ open class NHentai(
|
|||||||
.plus("Length: ${document.select("div#info div:contains(pages)").text()}\n")
|
.plus("Length: ${document.select("div#info div:contains(pages)").text()}\n")
|
||||||
.plus("Favorited by: ${document.select("div#info i.fa-heart + span span").text().removeSurrounding("(", ")")}\n")
|
.plus("Favorited by: ${document.select("div#info i.fa-heart + span span").text().removeSurrounding("(", ")")}\n")
|
||||||
.plus("Categories: ${document.select("div.field-name:contains(Categories) span.tags a").first()?.ownText()}\n\n")
|
.plus("Categories: ${document.select("div.field-name:contains(Categories) span.tags a").first()?.ownText()}\n\n")
|
||||||
.plus(getTags(document))
|
.plus(getTagDescription(document))
|
||||||
|
genre = getTags(document)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,15 +239,23 @@ open class NHentai(
|
|||||||
return pageList
|
return pageList
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getFilterList(): FilterList = FilterList(SortFilter())
|
override fun getFilterList(): FilterList = FilterList(
|
||||||
|
SortFilter(),
|
||||||
|
Filter.Header("Sort is ignored if favorites only"),
|
||||||
|
FavoriteFilter()
|
||||||
|
)
|
||||||
|
|
||||||
override fun imageUrlParse(document: Document) = throw UnsupportedOperationException("Not used")
|
override fun imageUrlParse(document: Document) = throw UnsupportedOperationException("Not used")
|
||||||
|
|
||||||
|
private class FavoriteFilter : Filter.CheckBox("Show favorites only", false)
|
||||||
|
|
||||||
|
private class SortFilter : Filter.Select<String>("Sort", arrayOf("Popular", "Date"))
|
||||||
|
|
||||||
|
private inline fun <reified T> Iterable<*>.findInstance() = find { it is T } as? T
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
const val PREFIX_ID_SEARCH = "id:"
|
const val PREFIX_ID_SEARCH = "id:"
|
||||||
private const val TITLE_PREF = "Display manga title as:"
|
private const val TITLE_PREF = "Display manga title as:"
|
||||||
}
|
}
|
||||||
|
|
||||||
private class SortFilter : Filter.Select<String>("Sort", arrayOf("Popular", "Date"))
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user