mangadex beta WIP (#427)

* This update does a few things
fixes #384
updates to support new api for mangadex being released soon
switches genre to tristate
adds filter by source language
updates icon

* added icons back

* updated build.gradle
This commit is contained in:
Carlos 2018-08-07 19:46:06 -04:00 committed by GitHub
parent d2f6744188
commit 934b69d9cd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 104 additions and 71 deletions

View File

@ -5,8 +5,8 @@ ext {
appName = 'Tachiyomi: MangaDex' appName = 'Tachiyomi: MangaDex'
pkgNameSuffix = 'all.mangadex' pkgNameSuffix = 'all.mangadex'
extClass = '.MangadexFactory' extClass = '.MangadexFactory'
extVersionCode = 32 extVersionCode = 33
extVersionSuffix = 32 extVersionSuffix = 33
libVersion = '1.2' libVersion = '1.2'
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 7.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

@ -53,7 +53,6 @@ open class Mangadex(override val lang: String, private val internalLang: String,
.request() .request()
.newBuilder() .newBuilder()
.addHeader("Cookie", cookiesHeader(r18Toggle, langCode)) .addHeader("Cookie", cookiesHeader(r18Toggle, langCode))
.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 6.3; WOW64)")
.build() .build()
chain.proceed(newReq) chain.proceed(newReq)
}.build()!! }.build()!!
@ -154,17 +153,21 @@ open class Mangadex(override val lang: String, private val internalLang: String,
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
val byGenre = filters.find { it is GenreList } val byGenre = filters.find { it is GenreList }
val genres = mutableListOf<String>() val genresToInclude = mutableListOf<String>()
val genresToExclude = mutableListOf<String>()
if (byGenre != null) { if (byGenre != null) {
byGenre as GenreList byGenre as GenreList
byGenre.state.forEach { genre -> byGenre.state.forEach { genre ->
when (genre.state) { if (genre.isExcluded()) {
true -> genres.add(genre.id) genresToExclude.add(genre.id)
} else if (genre.isIncluded()) {
genresToInclude.add(genre.id)
} }
} }
} }
//do traditional search //do traditional search
val url = HttpUrl.parse("$baseUrl/?page=search")!!.newBuilder().addQueryParameter("p", page.toString()).addQueryParameter("title", query.replace(whitespaceRegex, " ")) val url = HttpUrl.parse("$baseUrl/?page=search")!!.newBuilder().addQueryParameter("s", "0").addQueryParameter("p", page.toString()).addQueryParameter("title", query.replace(whitespaceRegex, " "))
filters.forEach { filter -> filters.forEach { filter ->
when (filter) { when (filter) {
is TextField -> url.addQueryParameter(filter.key, filter.state) is TextField -> url.addQueryParameter(filter.key, filter.state)
@ -173,11 +176,20 @@ open class Mangadex(override val lang: String, private val internalLang: String,
url.addQueryParameter("demo", filter.state.toString()) url.addQueryParameter("demo", filter.state.toString())
} }
} }
is OriginalLanguage -> {
if (filter.state != 0) {
val number: String = SOURCE_LANG_LIST.first { it -> it.first == filter.values[filter.state] }?.second
url.addQueryParameter("source_lang", number)
}
}
} }
} }
if (genres.isNotEmpty()) { if (genresToInclude.isNotEmpty()) {
url.addQueryParameter("genres", genres.joinToString(",")) url.addQueryParameter("genres_inc", genresToInclude.joinToString(","))
}
if (genresToExclude.isNotEmpty()) {
url.addQueryParameter("genres_exc", genresToExclude.joinToString(","))
} }
return GET(url.toString(), headers) return GET(url.toString(), headers)
@ -208,7 +220,7 @@ open class Mangadex(override val lang: String, private val internalLang: String,
} }
private fun apiRequest(manga: SManga): Request { private fun apiRequest(manga: SManga): Request {
return GET(baseUrl + URL + getMangaId(manga.url), headers) return GET(baseUrl + API_MANGA + getMangaId(manga.url), headers)
} }
private fun getMangaId(url: String): String { private fun getMangaId(url: String): String {
@ -244,7 +256,7 @@ open class Mangadex(override val lang: String, private val internalLang: String,
var genres = mutableListOf<String>() var genres = mutableListOf<String>()
mangaJson.get("genres").asJsonArray.forEach { id -> mangaJson.get("genres").asJsonArray.forEach { id ->
getGenreList().find { it -> it.id == id.string }?.let { genre -> GENRE_LIST.find { it -> it.id == id.string }?.let { genre ->
genres.add(genre.name) genres.add(genre.name)
} }
} }
@ -287,7 +299,7 @@ open class Mangadex(override val lang: String, private val internalLang: String,
override fun chapterListParse(response: Response): List<SChapter> { override fun chapterListParse(response: Response): List<SChapter> {
val now = Date().time val now = Date().time
var jsonData = response.body()!!.string() val jsonData = response.body()!!.string()
val json = JsonParser().parse(jsonData).asJsonObject val json = JsonParser().parse(jsonData).asJsonObject
val mangaJson = json.getAsJsonObject("manga") val mangaJson = json.getAsJsonObject("manga")
val status = mangaJson.get("status").int val status = mangaJson.get("status").int
@ -310,8 +322,8 @@ open class Mangadex(override val lang: String, private val internalLang: String,
private fun chapterFromJson(chapterId: String, chapterJson: JsonObject, finalChapterNumber: String, status: Int): SChapter { private fun chapterFromJson(chapterId: String, chapterJson: JsonObject, finalChapterNumber: String, status: Int): SChapter {
val chapter = SChapter.create() val chapter = SChapter.create()
chapter.url = BASE_CHAPTER + chapterId chapter.url = API_CHAPTER + chapterId
var chapterName = mutableListOf<String>() val chapterName = mutableListOf<String>()
//build chapter name //build chapter name
if (chapterJson.get("volume").string.isNotBlank()) { if (chapterJson.get("volume").string.isNotBlank()) {
chapterName.add("Vol." + chapterJson.get("volume").string) chapterName.add("Vol." + chapterJson.get("volume").string)
@ -342,7 +354,7 @@ open class Mangadex(override val lang: String, private val internalLang: String,
if (!chapterJson.get("group_name_3").nullString.isNullOrBlank()) { if (!chapterJson.get("group_name_3").nullString.isNullOrBlank()) {
scanlatorName.add(chapterJson.get("group_name_3").string) scanlatorName.add(chapterJson.get("group_name_3").string)
} }
chapter.scanlator = scanlatorName.joinToString(" & ") chapter.scanlator = cleanString(scanlatorName.joinToString(" & "))
return chapter return chapter
@ -350,15 +362,20 @@ open class Mangadex(override val lang: String, private val internalLang: String,
override fun chapterFromElement(element: Element) = throw Exception("Not used") override fun chapterFromElement(element: Element) = throw Exception("Not used")
override fun pageListParse(document: Document): List<Page> { override fun pageListParse(document: Document) = throw Exception("Not used")
val pages = mutableListOf<Page>()
val dataUrl = document.select("script").last().html().substringAfter("dataurl = '").substringBefore("';")
val imageUrl = document.select("script").last().html().substringAfter("page_array = [").substringBefore("];")
val listImageUrls = imageUrl.replace("'", "").split(",")
val server = document.select("script").last().html().substringAfter("server = '").substringBefore("';")
listImageUrls.filter { it.isNotBlank() }.forEach { override fun pageListParse(response: Response): List<Page> {
val url = "$server$dataUrl/$it" var jsonData = response.body()!!.string()
val json = JsonParser().parse(jsonData).asJsonObject
val pages = mutableListOf<Page>()
val hash = json.get("hash").string
val pageArray = json.getAsJsonArray("page_array")
val server = json.get("server").string
pageArray.forEach {
val url = "$server$hash/$it"
pages.add(Page(pages.size, "", getImageUrl(url))) pages.add(Page(pages.size, "", getImageUrl(url)))
} }
@ -403,64 +420,23 @@ open class Mangadex(override val lang: String, private val internalLang: String,
private class TextField(name: String, val key: String) : Filter.Text(name) private class TextField(name: String, val key: String) : Filter.Text(name)
private class Genre(val id: String, name: String) : Filter.CheckBox(name) private class Genre(val id: String, name: String) : Filter.TriState(name)
private class GenreList(genres: List<Genre>) : Filter.Group<Genre>("Genres", genres) private class GenreList(genres: List<Genre>) : Filter.Group<Genre>("Genres", genres)
private class R18 : Filter.Select<String>("R18+", arrayOf("Show all", "Show only", "Show none")) private class R18 : Filter.Select<String>("R18+", arrayOf("Show all", "Show only", "Show none"))
private class Demographic : Filter.Select<String>("Demographic", arrayOf("All", "Shounen", "Shoujo", "Seinen", "Josei")) private class Demographic : Filter.Select<String>("Demographic", arrayOf("All", "Shounen", "Shoujo", "Seinen", "Josei"))
private class OriginalLanguage : Filter.Select<String>("Original Language", SOURCE_LANG_LIST.map { it -> it.first }.toTypedArray())
override fun getFilterList() = FilterList( override fun getFilterList() = FilterList(
TextField("Author", "author"), TextField("Author", "author"),
TextField("Artist", "artist"), TextField("Artist", "artist"),
R18(), R18(),
Demographic(), Demographic(),
GenreList(getGenreList()) OriginalLanguage(),
GenreList(GENRE_LIST)
) )
private fun getGenreList() = listOf(
Genre("1", "4-koma"),
Genre("2", "Action"),
Genre("3", "Adventure"),
Genre("4", "Award Winning"),
Genre("5", "Comedy"),
Genre("6", "Cooking"),
Genre("7", "Doujinshi"),
Genre("8", "Drama"),
Genre("9", "Ecchi"),
Genre("10", "Fantasy"),
Genre("11", "Gender Bender"),
Genre("12", "Harem"),
Genre("13", "Historical"),
Genre("14", "Horror"),
Genre("15", "Josei"),
Genre("16", "Martial Arts"),
Genre("17", "Mecha"),
Genre("18", "Medical"),
Genre("19", "Music"),
Genre("20", "Mystery"),
Genre("21", "Oneshot"),
Genre("22", "Psychological"),
Genre("23", "Romance"),
Genre("24", "School Life"),
Genre("25", "Sci-Fi"),
Genre("26", "Seinen"),
Genre("27", "Shoujo"),
Genre("28", "Shoujo Ai"),
Genre("29", "Shounen"),
Genre("30", "Shounen Ai"),
Genre("31", "Slice of Life"),
Genre("32", "Smut"),
Genre("33", "Sports"),
Genre("34", "Supernatural"),
Genre("35", "Tragedy"),
Genre("36", "Webtoon"),
Genre("37", "Yaoi"),
Genre("38", "Yuri"),
Genre("39", "[no chapters]"),
Genre("40", "Game"),
Genre("41", "Isekai")
)
companion object { companion object {
//this number matches to the cookie //this number matches to the cookie
private const val NO_R18 = 0 private const val NO_R18 = 0
@ -468,8 +444,65 @@ open class Mangadex(override val lang: String, private val internalLang: String,
private const val ONLY_R18 = 2 private const val ONLY_R18 = 2
private const val SHOW_R18_PREF_Title = "Default R18 Setting" private const val SHOW_R18_PREF_Title = "Default R18 Setting"
private const val SHOW_R18_PREF = "showR18Default" private const val SHOW_R18_PREF = "showR18Default"
private const val URL = "/api/3640f3fb/" private const val API_MANGA = "/api/manga/"
private const val BASE_CHAPTER = "/chapter/" private const val API_CHAPTER = "/api/chapter/"
private val SOURCE_LANG_LIST = listOf(
Pair("All", "0"),
Pair("Japanese", "2"),
Pair("English", "1"),
Pair("Polish", "3"),
Pair("German", "8"),
Pair("French", "10"),
Pair("Vietnamese", "12"),
Pair("Chinese", "21"),
Pair("Indonesian", "27"),
Pair("Korean", "28"),
Pair("Spanish (LATAM)", "29"),
Pair("Thai", "32"),
Pair("Filipino", "34")
)
private val GENRE_LIST = listOf(
Genre("1", "4-koma"),
Genre("2", "Action"),
Genre("3", "Adventure"),
Genre("4", "Award Winning"),
Genre("5", "Comedy"),
Genre("6", "Cooking"),
Genre("7", "Doujinshi"),
Genre("8", "Drama"),
Genre("9", "Ecchi"),
Genre("10", "Fantasy"),
Genre("11", "Gender Bender"),
Genre("12", "Harem"),
Genre("13", "Historical"),
Genre("14", "Horror"),
Genre("15", "Josei"),
Genre("16", "Martial Arts"),
Genre("17", "Mecha"),
Genre("18", "Medical"),
Genre("19", "Music"),
Genre("20", "Mystery"),
Genre("21", "Oneshot"),
Genre("22", "Psychological"),
Genre("23", "Romance"),
Genre("24", "School Life"),
Genre("25", "Sci-Fi"),
Genre("26", "Seinen"),
Genre("27", "Shoujo"),
Genre("28", "Shoujo Ai"),
Genre("29", "Shounen"),
Genre("30", "Shounen Ai"),
Genre("31", "Slice of Life"),
Genre("32", "Smut"),
Genre("33", "Sports"),
Genre("34", "Supernatural"),
Genre("35", "Tragedy"),
Genre("36", "Webtoon"),
Genre("37", "Yaoi"),
Genre("38", "Yuri"),
Genre("39", "[no chapters]"),
Genre("40", "Game"),
Genre("41", "Isekai"))
} }
} }