diff --git a/src/all/hentaiera/build.gradle b/src/all/hentaiera/build.gradle new file mode 100644 index 000000000..ea9c400d2 --- /dev/null +++ b/src/all/hentaiera/build.gradle @@ -0,0 +1,10 @@ +ext { + extName = 'HentaiEra' + extClass = '.HentaiEraFactory' + themePkg = 'galleryadults' + baseUrl = 'https://hentaiera.com' + overrideVersionCode = 0 + isNsfw = true +} + +apply from: "$rootDir/common.gradle" diff --git a/src/all/hentaiera/res/mipmap-hdpi/ic_launcher.png b/src/all/hentaiera/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..ae8d99876 Binary files /dev/null and b/src/all/hentaiera/res/mipmap-hdpi/ic_launcher.png differ diff --git a/src/all/hentaiera/res/mipmap-mdpi/ic_launcher.png b/src/all/hentaiera/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..f7de7c44a Binary files /dev/null and b/src/all/hentaiera/res/mipmap-mdpi/ic_launcher.png differ diff --git a/src/all/hentaiera/res/mipmap-xhdpi/ic_launcher.png b/src/all/hentaiera/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..c5f1be93e Binary files /dev/null and b/src/all/hentaiera/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/src/all/hentaiera/res/mipmap-xxhdpi/ic_launcher.png b/src/all/hentaiera/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..d65fbf70b Binary files /dev/null and b/src/all/hentaiera/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/src/all/hentaiera/res/mipmap-xxxhdpi/ic_launcher.png b/src/all/hentaiera/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..deddbb843 Binary files /dev/null and b/src/all/hentaiera/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/src/all/hentaiera/src/eu/kanade/tachiyomi/extension/all/hentaiera/HentaiEra.kt b/src/all/hentaiera/src/eu/kanade/tachiyomi/extension/all/hentaiera/HentaiEra.kt new file mode 100644 index 000000000..a4f53302f --- /dev/null +++ b/src/all/hentaiera/src/eu/kanade/tachiyomi/extension/all/hentaiera/HentaiEra.kt @@ -0,0 +1,104 @@ +package eu.kanade.tachiyomi.extension.all.hentaiera + +import eu.kanade.tachiyomi.multisrc.galleryadults.GalleryAdults +import eu.kanade.tachiyomi.multisrc.galleryadults.Genre +import eu.kanade.tachiyomi.multisrc.galleryadults.SearchFlagFilter +import eu.kanade.tachiyomi.multisrc.galleryadults.imgAttr +import eu.kanade.tachiyomi.multisrc.galleryadults.toBinary +import eu.kanade.tachiyomi.network.GET +import okhttp3.HttpUrl.Companion.toHttpUrl +import okhttp3.Request +import org.jsoup.nodes.Document +import org.jsoup.nodes.Element + +class HentaiEra( + lang: String = "all", + override val mangaLang: String = LANGUAGE_MULTI, +) : GalleryAdults( + "HentaiEra", + "https://hentaiera.com", + lang = lang, +) { + override val supportsLatest = true + override val useIntermediateSearch: Boolean = true + override val supportSpeechless: Boolean = true + + override fun Element.mangaTitle(selector: String): String? = + mangaFullTitle(selector.replace("caption", "gallery_title")).let { + if (preferences.shortTitle) it?.shortenTitle() else it + } + + override fun Element.mangaLang() = + select("a:has(.g_flag)").attr("href") + .removeSuffix("/").substringAfterLast("/") + .let { + // Include Speechless in search results + if (it == LANGUAGE_SPEECHLESS) mangaLang else it + } + + override fun popularMangaRequest(page: Int): Request { + // Only for query string or multiple tags + val url = "$baseUrl/search".toHttpUrl().newBuilder().apply { + addQueryParameter("pp", "1") + + getLanguageURIs().forEach { pair -> + addQueryParameter( + pair.second, + toBinary(mangaLang == pair.first || mangaLang == LANGUAGE_MULTI), + ) + } + + addPageUri(page) + } + return GET(url.build()) + } + + /* Details */ + override fun Element.getInfo(tag: String): String { + return select("li:has(.tags_text:contains($tag)) .tag .item_name") + .joinToString { + val name = it.ownText() + if (tag.contains(regexTag)) { + genres[name] = it.parent()!!.attr("href") + .removeSuffix("/").substringAfterLast('/') + } + listOf( + name, + it.select(".split_tag").text() + .trim() + .removePrefix("| "), + ) + .filter { s -> s.isNotBlank() } + .joinToString() + } + } + + override fun Element.getCover() = + selectFirst(".left_cover img")?.imgAttr() + + override fun tagsParser(document: Document): List { + return document.select("h2.gallery_title a") + .mapNotNull { + Genre( + it.text(), + it.attr("href") + .removeSuffix("/").substringAfterLast('/'), + ) + } + } + + override val mangaDetailInfoSelector = ".gallery_first" + + /* Pages */ + override val thumbnailSelector = ".gthumb" + override val pageUri = "view" + + override fun getCategoryURIs() = listOf( + SearchFlagFilter("Manga", "mg"), + SearchFlagFilter("Doujinshi", "dj"), + SearchFlagFilter("Western", "ws"), + SearchFlagFilter("Image Set", "is"), + SearchFlagFilter("Artist CG", "ac"), + SearchFlagFilter("Game CG", "gc"), + ) +} diff --git a/src/all/hentaiera/src/eu/kanade/tachiyomi/extension/all/hentaiera/HentaiEraFactory.kt b/src/all/hentaiera/src/eu/kanade/tachiyomi/extension/all/hentaiera/HentaiEraFactory.kt new file mode 100644 index 000000000..332b271a2 --- /dev/null +++ b/src/all/hentaiera/src/eu/kanade/tachiyomi/extension/all/hentaiera/HentaiEraFactory.kt @@ -0,0 +1,19 @@ +package eu.kanade.tachiyomi.extension.all.hentaiera + +import eu.kanade.tachiyomi.multisrc.galleryadults.GalleryAdults +import eu.kanade.tachiyomi.source.Source +import eu.kanade.tachiyomi.source.SourceFactory + +class HentaiEraFactory : SourceFactory { + + override fun createSources(): List = listOf( + HentaiEra("en", GalleryAdults.LANGUAGE_ENGLISH), + HentaiEra("ja", GalleryAdults.LANGUAGE_JAPANESE), + HentaiEra("es", GalleryAdults.LANGUAGE_SPANISH), + HentaiEra("fr", GalleryAdults.LANGUAGE_FRENCH), + HentaiEra("ko", GalleryAdults.LANGUAGE_KOREAN), + HentaiEra("de", GalleryAdults.LANGUAGE_GERMAN), + HentaiEra("ru", GalleryAdults.LANGUAGE_RUSSIAN), + HentaiEra("all", GalleryAdults.LANGUAGE_MULTI), + ) +}