diff --git a/src/all/nhentai/build.gradle b/src/all/nhentai/build.gradle index a5cc9fc66..3163fa863 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 = '.NHFactory' - extVersionCode = 17 + extVersionCode = 18 libVersion = '1.2' } diff --git a/src/all/nhentai/src/eu/kanade/tachiyomi/extension/all/nhentai/NHUtils.kt b/src/all/nhentai/src/eu/kanade/tachiyomi/extension/all/nhentai/NHUtils.kt index 67fce181e..69d81cbe2 100644 --- a/src/all/nhentai/src/eu/kanade/tachiyomi/extension/all/nhentai/NHUtils.kt +++ b/src/all/nhentai/src/eu/kanade/tachiyomi/extension/all/nhentai/NHUtils.kt @@ -1,90 +1,53 @@ package eu.kanade.tachiyomi.extension.all.nhentai import org.jsoup.nodes.Document +import org.jsoup.nodes.Element import java.text.SimpleDateFormat -class NHUtils { - companion object { - fun getArtists(document: Document): String { - val stringBuilder = StringBuilder() - val artists = document.select("#tags > div:nth-child(4) > span > a") - - artists.forEach { - stringBuilder.append(cleanTag(it.text())) - - if (it != artists.last()) - stringBuilder.append(", ") - } - - return stringBuilder.toString() - } - - fun getGroups(document: Document): String? { - val stringBuilder = StringBuilder() - val groups = document.select("#tags > div:nth-child(5) > span > a") - - groups.forEach { - stringBuilder.append(cleanTag(it.text())) - - if (it != groups.last()) - stringBuilder.append(", ") - } - - return if (stringBuilder.toString().isEmpty()) null else stringBuilder.toString() - } - - fun getTags(document: Document): String { - val stringBuilder = StringBuilder() - val parodies = document.select("#tags > div:nth-child(1) > span > a") - val characters = document.select("#tags > div:nth-child(2) > span > a") - val tags = document.select("#tags > div:nth-child(3) > span > a") - - if (parodies.size > 0) { - stringBuilder.append("Parodies: ") - - parodies.forEach { - stringBuilder.append(cleanTag(it.text())) - - if (it != parodies.last()) - stringBuilder.append(", ") - } - - stringBuilder.append("\n\n") - } - - if (characters.size > 0) { - stringBuilder.append("Characters: ") - - 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() - } - - fun getTime(document: Document): Long { - val timeString = document.toString().substringAfter("datetime=\"").substringBefore("\">").replace("T", " ") - - return SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSSZ").parse(timeString).time - } - - private fun cleanTag(tag: String): String = tag.replace(Regex("\\(.*\\)"), "").trim() +object NHUtils { + fun getArtists(document: Document): String { + val artists = document.select("#tags > div:nth-child(4) > span > a") + return artists.joinToString(", ") { it.cleanTag() } } + + fun getGroups(document: Document): String? { + val groups = document.select("#tags > div:nth-child(5) > span > a") + return if (groups.isNotEmpty()) { + groups.joinToString(", ") { it.cleanTag() } + } else { + null + } + } + + fun getTagDescription(document: Document): String { + val stringBuilder = StringBuilder() + + val parodies = document.select("#tags > div:nth-child(1) > span > a") + if (parodies.isNotEmpty()) { + stringBuilder.append("Parodies: ") + stringBuilder.append(parodies.joinToString(", ") { it.cleanTag() }) + stringBuilder.append("\n\n") + } + + val characters = document.select("#tags > div:nth-child(2) > span > a") + if (characters.isNotEmpty()) { + stringBuilder.append("Characters: ") + stringBuilder.append(characters.joinToString(", ") { it.cleanTag() }) + } + + 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 { + val timeString = document.toString().substringAfter("datetime=\"").substringBefore("\">").replace("T", " ") + + return SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSSSSSZ").parse(timeString).time + } + + private fun Element.cleanTag(): String = text().replace(Regex("\\(.*\\)"), "").trim() } 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 f7a8edd78..a66363c40 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 @@ -5,10 +5,11 @@ import android.content.SharedPreferences import android.support.v7.preference.ListPreference import android.support.v7.preference.PreferenceScreen import eu.kanade.tachiyomi.extension.BuildConfig -import eu.kanade.tachiyomi.extension.all.nhentai.NHUtils.Companion.getArtists -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.extension.all.nhentai.NHUtils.getArtists +import eu.kanade.tachiyomi.extension.all.nhentai.NHUtils.getGroups +import eu.kanade.tachiyomi.extension.all.nhentai.NHUtils.getTagDescription +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.asObservableSuccess import eu.kanade.tachiyomi.source.ConfigurableSource @@ -139,16 +140,24 @@ open class NHentai( } override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { - val url = HttpUrl.parse("$baseUrl/search")!!.newBuilder() - .addQueryParameter("q", "$query +$nhLang") - .addQueryParameter("page", page.toString()) + val favoriteFilter = filters.findInstance<FavoriteFilter>() + if (favoriteFilter != null && favoriteFilter.state) { + val url = HttpUrl.parse("$baseUrl/favorites")!!.newBuilder() + .addQueryParameter("q", query) + .addQueryParameter("page", page.toString()) - for (filter in if (filters.isEmpty()) getFilterList() else filters) { - when (filter) { - is SortFilter -> url.addQueryParameter("sort", filter.values[filter.state].toLowerCase()) + return GET(url.toString(), headers) + } else { + val url = HttpUrl.parse("$baseUrl/search")!!.newBuilder() + .addQueryParameter("q", "$query +$nhLang") + .addQueryParameter("page", page.toString()) + + filters.findInstance<SortFilter>()?.let { f -> + url.addQueryParameter("sort", f.values[f.state].toLowerCase()) } + + return GET(url.toString(), headers) } - return GET(url.toString(), headers) } private fun searchMangaByIdRequest(id: String) = GET("$baseUrl/g/$id", headers) @@ -159,6 +168,17 @@ open class NHentai( 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 searchMangaSelector() = latestUpdatesSelector() @@ -181,7 +201,8 @@ open class NHentai( .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("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 } - 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") + 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 { const val PREFIX_ID_SEARCH = "id:" private const val TITLE_PREF = "Display manga title as:" } - private class SortFilter : Filter.Select<String>("Sort", arrayOf("Popular", "Date")) - }