diff --git a/src/en/manhuamanga/AndroidManifest.xml b/src/en/manhuamanga/AndroidManifest.xml new file mode 100644 index 000000000..30deb7f79 --- /dev/null +++ b/src/en/manhuamanga/AndroidManifest.xml @@ -0,0 +1,2 @@ + + diff --git a/src/en/manhuamanga/build.gradle b/src/en/manhuamanga/build.gradle new file mode 100644 index 000000000..87fd732a6 --- /dev/null +++ b/src/en/manhuamanga/build.gradle @@ -0,0 +1,13 @@ +apply plugin: 'com.android.application' +apply plugin: 'kotlin-android' + +ext { + extName = 'ManhuaManga.net' + pkgNameSuffix = 'en.manhuamanga' + extClass = '.ManhuaManga' + extVersionCode = 1 + libVersion = '1.2' + containsNsfw = true +} + +apply from: "$rootDir/common.gradle" diff --git a/src/en/manhuamanga/res/mipmap-hdpi/ic_launcher.png b/src/en/manhuamanga/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 000000000..580694e1b Binary files /dev/null and b/src/en/manhuamanga/res/mipmap-hdpi/ic_launcher.png differ diff --git a/src/en/manhuamanga/res/mipmap-mdpi/ic_launcher.png b/src/en/manhuamanga/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 000000000..8efd2f57f Binary files /dev/null and b/src/en/manhuamanga/res/mipmap-mdpi/ic_launcher.png differ diff --git a/src/en/manhuamanga/res/mipmap-xhdpi/ic_launcher.png b/src/en/manhuamanga/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 000000000..a600bdf93 Binary files /dev/null and b/src/en/manhuamanga/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/src/en/manhuamanga/res/mipmap-xxhdpi/ic_launcher.png b/src/en/manhuamanga/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 000000000..dd11d3f4e Binary files /dev/null and b/src/en/manhuamanga/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/src/en/manhuamanga/res/mipmap-xxxhdpi/ic_launcher.png b/src/en/manhuamanga/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 000000000..a24fb6f44 Binary files /dev/null and b/src/en/manhuamanga/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/src/en/manhuamanga/res/web_hi_res_512.png b/src/en/manhuamanga/res/web_hi_res_512.png new file mode 100644 index 000000000..2ef804be2 Binary files /dev/null and b/src/en/manhuamanga/res/web_hi_res_512.png differ diff --git a/src/en/manhuamanga/src/eu/kanade/tachiyomi/extension/en/manhuamanga/ManhuaManga.kt b/src/en/manhuamanga/src/eu/kanade/tachiyomi/extension/en/manhuamanga/ManhuaManga.kt new file mode 100644 index 000000000..0de059e52 --- /dev/null +++ b/src/en/manhuamanga/src/eu/kanade/tachiyomi/extension/en/manhuamanga/ManhuaManga.kt @@ -0,0 +1,163 @@ +package eu.kanade.tachiyomi.extension.en.manhuamanga + +import eu.kanade.tachiyomi.annotations.Nsfw +import eu.kanade.tachiyomi.network.GET +import eu.kanade.tachiyomi.network.POST +import eu.kanade.tachiyomi.source.model.Filter +import eu.kanade.tachiyomi.source.model.FilterList +import eu.kanade.tachiyomi.source.model.Page +import eu.kanade.tachiyomi.source.model.SChapter +import eu.kanade.tachiyomi.source.model.SManga +import eu.kanade.tachiyomi.source.online.ParsedHttpSource +import eu.kanade.tachiyomi.util.asJsoup +import okhttp3.HttpUrl.Companion.toHttpUrlOrNull +import okhttp3.Request +import okhttp3.RequestBody +import okhttp3.Response +import org.jsoup.nodes.Document +import org.jsoup.nodes.Element + +@Nsfw +class ManhuaManga : ParsedHttpSource() { + override val name = "ManhuaManga.net" + override val baseUrl = "https://manhuamanga.net" + override val lang = "en" + override val supportsLatest = true + + override fun popularMangaSelector() = ".home-truyendecu" + override fun latestUpdatesSelector() = popularMangaSelector() + override fun searchMangaSelector() = popularMangaSelector() + override fun chapterListSelector() = "#list-chapter > div.row > div > ul > li:nth-child(n)" + + override fun popularMangaNextPageSelector() = "li.active+li a[data-page]" + override fun latestUpdatesNextPageSelector() = popularMangaNextPageSelector() + override fun searchMangaNextPageSelector() = popularMangaNextPageSelector() + + override fun popularMangaRequest(page: Int): Request { + return GET("$baseUrl/most-views/page/$page", headers) + } + + override fun latestUpdatesRequest(page: Int): Request { + return GET("$baseUrl/latest-updates/page/$page", headers) + } + + override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { + return if (query.isNotBlank()) { + GET("$baseUrl/?s=$query", headers) + } else { + val url = "$baseUrl/category/".toHttpUrlOrNull()!!.newBuilder() + filters.forEach { filter -> + when (filter) { + + is GenreFilter -> url.addPathSegment(filter.toUriPart()) + } + } + url.addPathSegment("page") + url.addPathSegment("$page") + GET(url.toString(), headers) + } + } + override fun popularMangaFromElement(element: Element): SManga { + val manga = SManga.create() + manga.setUrlWithoutDomain(element.select("a").attr("href")) + manga.title = element.select("a").attr("title") + manga.thumbnail_url = element.select("a img").attr("src") + + return manga + } + override fun latestUpdatesFromElement(element: Element): SManga = popularMangaFromElement(element) + override fun searchMangaFromElement(element: Element) = popularMangaFromElement(element) + + protected fun getXhrChapters(mangaId: String): Document { + val xhrHeaders = headersBuilder().add("Content-Type: application/x-www-form-urlencoded; charset=UTF-8") + .build() + val body = RequestBody.create(null, "action=tw_ajax&type=list_chap&id=$mangaId") + return client.newCall(POST("$baseUrl/wp-admin/admin-ajax.php", xhrHeaders, body)).execute().asJsoup() + } + + override fun chapterListParse(response: Response): List { + val document = response.asJsoup() + val dataIdSelector = "input[id^=id_post]" + + return getXhrChapters(document.select(dataIdSelector).attr("value")).select("option").map { chapterFromElement(it) }.reversed() + } + + override fun chapterFromElement(element: Element): SChapter { + val chapter = SChapter.create() + element.let { urlElement -> + chapter.setUrlWithoutDomain(urlElement.attr("value")) + chapter.name = urlElement.text() + } + chapter.date_upload = 0 + + return chapter + } + + override fun mangaDetailsParse(document: Document) = SManga.create().apply { + title = document.select("h3.title").text() + description = document.select("div.desc-text > p").text() + thumbnail_url = document.select("div.books > div > img").attr("src") + author = document.select("div.info > div:nth-child(1) > a").attr("title") + genre = document.select("div.info > div:nth-child(2) > a").joinToString { it.text() } + status = document.select("div.info > div:nth-child(3) > span").text().let { + when { + it.contains("Ongoing") -> SManga.ONGOING + it.contains("Completed") -> SManga.COMPLETED + else -> SManga.UNKNOWN + } + } + } + + override fun pageListParse(document: Document): List = mutableListOf().apply { + document.select(".chapter_beta_content p img").forEachIndexed { index, element -> + add(Page(index, "", element.attr("src"))) + } + } + + override fun imageUrlRequest(page: Page) = throw Exception("Not used") + override fun imageUrlParse(document: Document) = throw Exception("Not used") + + override fun getFilterList() = FilterList( + Filter.Header("NOTE: Ignored if using text search!"), + Filter.Separator(), + GenreFilter(getGenreList()) + ) + class GenreFilter(vals: Array>) : UriPartFilter("Category", vals) + + private fun getGenreList() = arrayOf( + Pair("All", ""), + Pair("Action", "action"), + Pair("Adventure", "adventure"), + Pair("Comedy", "comedy"), + Pair("Comic", "comic"), + Pair("Drama", "drama"), + Pair("Ecchi", "ecchi"), + Pair("Fantasy", "fantasy"), + Pair("Harem", "harem"), + Pair("Historical", "historical"), + Pair("Isekai", "isekai"), + Pair("Josei", "josei"), + Pair("Manhua", "manhua"), + Pair("Manhwa", "manhwa"), + Pair("Martial arts", "martial-arts"), + Pair("Moder", "moder"), + Pair("Mystery", "mystery"), + Pair("Psychological", "psychological"), + Pair("Romance", "romance"), + Pair("School Life", "school-life"), + Pair("Sci Fi", "sci-fi"), + Pair("Seinen", "seinen"), + Pair("Shoujo", "shoujo"), + Pair("Shounen", "shounen"), + Pair("Shounen ai", "shounen-ai"), + Pair("Slice of Life", "slice-of-life"), + Pair("Super power", "super-power"), + Pair("Tragedy", "tragedy"), + Pair("Webtoon", "webtoon"), + Pair("Webtoons", "webtoons"), + ) + open class UriPartFilter(displayName: String, private val vals: Array>) : + Filter.Select(displayName, vals.map { it.first }.toTypedArray()) { + fun toUriPart() = vals[state].second + } +} diff --git a/src/en/manhwamanga/build.gradle b/src/en/manhwamanga/build.gradle index b5e469189..41ea8c6c7 100644 --- a/src/en/manhwamanga/build.gradle +++ b/src/en/manhwamanga/build.gradle @@ -5,7 +5,7 @@ ext { extName = 'ManhwaManga.net' pkgNameSuffix = 'en.manhwamanga' extClass = '.ManhwaManga' - extVersionCode = 3 + extVersionCode = 4 libVersion = '1.2' containsNsfw = true } diff --git a/src/en/manhwamanga/res/mipmap-hdpi/ic_launcher.png b/src/en/manhwamanga/res/mipmap-hdpi/ic_launcher.png index 84f2e9487..580694e1b 100644 Binary files a/src/en/manhwamanga/res/mipmap-hdpi/ic_launcher.png and b/src/en/manhwamanga/res/mipmap-hdpi/ic_launcher.png differ diff --git a/src/en/manhwamanga/res/mipmap-mdpi/ic_launcher.png b/src/en/manhwamanga/res/mipmap-mdpi/ic_launcher.png index 068af711f..8efd2f57f 100644 Binary files a/src/en/manhwamanga/res/mipmap-mdpi/ic_launcher.png and b/src/en/manhwamanga/res/mipmap-mdpi/ic_launcher.png differ diff --git a/src/en/manhwamanga/res/mipmap-xhdpi/ic_launcher.png b/src/en/manhwamanga/res/mipmap-xhdpi/ic_launcher.png index ffcd483f5..a600bdf93 100644 Binary files a/src/en/manhwamanga/res/mipmap-xhdpi/ic_launcher.png and b/src/en/manhwamanga/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/src/en/manhwamanga/res/mipmap-xxhdpi/ic_launcher.png b/src/en/manhwamanga/res/mipmap-xxhdpi/ic_launcher.png index 14be764b9..dd11d3f4e 100644 Binary files a/src/en/manhwamanga/res/mipmap-xxhdpi/ic_launcher.png and b/src/en/manhwamanga/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/src/en/manhwamanga/res/mipmap-xxxhdpi/ic_launcher.png b/src/en/manhwamanga/res/mipmap-xxxhdpi/ic_launcher.png index f549c1e7d..a24fb6f44 100644 Binary files a/src/en/manhwamanga/res/mipmap-xxxhdpi/ic_launcher.png and b/src/en/manhwamanga/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/src/en/manhwamanga/res/web_hi_res_512.png b/src/en/manhwamanga/res/web_hi_res_512.png index c307cca26..2ef804be2 100644 Binary files a/src/en/manhwamanga/res/web_hi_res_512.png and b/src/en/manhwamanga/res/web_hi_res_512.png differ