From 2b5359ca2656e182ecb29674db32920dd6e19000 Mon Sep 17 00:00:00 2001
From: jopejoe1 <34899572+jopejoe1@users.noreply.github.com>
Date: Mon, 7 Mar 2022 03:48:27 +1300
Subject: [PATCH] Mangadex: Add support for MDLists url intent (#11024)
* Update build.gradle
* Added list support
* Add error message for empty list
* Update AndroidManifest.xml
---
src/all/mangadex/AndroidManifest.xml | 26 ++-----
src/all/mangadex/build.gradle | 2 +-
.../extension/all/mangadex/MDConstants.kt | 2 +
.../extension/all/mangadex/MangaDex.kt | 74 ++++++++++++++++---
.../all/mangadex/MangadexUrlActivity.kt | 1 +
.../extension/all/mangadex/dto/ListDto.kt | 25 +++++++
6 files changed, 101 insertions(+), 29 deletions(-)
create mode 100644 src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/dto/ListDto.kt
diff --git a/src/all/mangadex/AndroidManifest.xml b/src/all/mangadex/AndroidManifest.xml
index d3558b582..78a723a92 100644
--- a/src/all/mangadex/AndroidManifest.xml
+++ b/src/all/mangadex/AndroidManifest.xml
@@ -15,25 +15,15 @@
+
-
-
-
-
-
-
+
+
+
+
+
+
+
diff --git a/src/all/mangadex/build.gradle b/src/all/mangadex/build.gradle
index f9141ab5a..32e799278 100644
--- a/src/all/mangadex/build.gradle
+++ b/src/all/mangadex/build.gradle
@@ -6,7 +6,7 @@ ext {
extName = 'MangaDex'
pkgNameSuffix = 'all.mangadex'
extClass = '.MangaDexFactory'
- extVersionCode = 156
+ extVersionCode = 157
isNsfw = true
}
diff --git a/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MDConstants.kt b/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MDConstants.kt
index c605f1306..4549a7a99 100644
--- a/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MDConstants.kt
+++ b/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MDConstants.kt
@@ -24,6 +24,7 @@ object MDConstants {
const val apiUrl = "https://api.mangadex.org"
const val apiMangaUrl = "$apiUrl/manga"
const val apiChapterUrl = "$apiUrl/chapter"
+ const val apiListUrl = "$apiUrl/list"
const val atHomePostUrl = "https://api.mangadex.network/report"
val whitespaceRegex = "\\s".toRegex()
@@ -37,6 +38,7 @@ object MDConstants {
const val prefixGrpSearch = "grp:"
const val prefixAuthSearch = "author:"
const val prefixUsrSearch = "usr:"
+ const val prefixListSearch = "list:"
const val coverQualityPref = "thumbnailQuality"
diff --git a/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MangaDex.kt b/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MangaDex.kt
index eb02b7136..ea65289a7 100644
--- a/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MangaDex.kt
+++ b/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MangaDex.kt
@@ -12,6 +12,7 @@ import eu.kanade.tachiyomi.extension.all.mangadex.dto.AggregateDto
import eu.kanade.tachiyomi.extension.all.mangadex.dto.AtHomeDto
import eu.kanade.tachiyomi.extension.all.mangadex.dto.ChapterDto
import eu.kanade.tachiyomi.extension.all.mangadex.dto.ChapterListDto
+import eu.kanade.tachiyomi.extension.all.mangadex.dto.ListDto
import eu.kanade.tachiyomi.extension.all.mangadex.dto.MangaDto
import eu.kanade.tachiyomi.extension.all.mangadex.dto.MangaListDto
import eu.kanade.tachiyomi.network.GET
@@ -191,17 +192,22 @@ abstract class MangaDex(override val lang: String, val dexLang: String) :
// SEARCH section
override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable {
- if (query.startsWith(MDConstants.prefixChSearch)) {
- return getMangaIdFromChapterId(query.removePrefix(MDConstants.prefixChSearch)).flatMap { manga_id ->
- super.fetchSearchManga(page, MDConstants.prefixIdSearch + manga_id, filters)
- }
+ when {
+ query.startsWith(MDConstants.prefixChSearch) ->
+ return getMangaIdFromChapterId(query.removePrefix(MDConstants.prefixChSearch)).flatMap { manga_id ->
+ super.fetchSearchManga(page, MDConstants.prefixIdSearch + manga_id, filters)
+ }
+ query.startsWith(MDConstants.prefixUsrSearch) ->
+ return client.newCall(searchMangaUploaderRequest(page, query.removePrefix(MDConstants.prefixUsrSearch)))
+ .asObservableSuccess()
+ .map { latestUpdatesParse(it) }
+ query.startsWith(MDConstants.prefixListSearch) ->
+ return client.newCall(GET(MDConstants.apiListUrl + "/" + query.removePrefix(MDConstants.prefixListSearch), headers, CacheControl.FORCE_NETWORK))
+ .asObservableSuccess()
+ .map { searchMangaListRequest(it, page) }
+ else ->
+ return super.fetchSearchManga(page, query, filters)
}
- if (query.startsWith(MDConstants.prefixUsrSearch)) {
- return client.newCall(searchMangaUploaderRequest(page, query.removePrefix(MDConstants.prefixUsrSearch)))
- .asObservableSuccess()
- .map { latestUpdatesParse(it) }
- }
- return super.fetchSearchManga(page, query, filters)
}
private fun getMangaIdFromChapterId(id: String): Observable {
@@ -277,6 +283,54 @@ abstract class MangaDex(override val lang: String, val dexLang: String) :
override fun searchMangaParse(response: Response): MangasPage = popularMangaParse(response)
+ private fun searchMangaListRequest(response: Response, page: Int): MangasPage {
+ if (response.isSuccessful.not()) {
+ throw Exception("HTTP ${response.code}")
+ }
+
+ val listDto = helper.json.decodeFromString(response.body!!.string())
+ val listDtoFiltered = listDto.data.relationships.filter { it.type != "Manga" }
+ val amount = listDtoFiltered.count()
+ if (amount < 1){
+ throw Exception("No Manga in List")
+ }
+ val minIndex = (page - 1) * MDConstants.mangaLimit
+
+ val url = MDConstants.apiMangaUrl.toHttpUrl().newBuilder().apply {
+ addQueryParameter("limit", MDConstants.mangaLimit.toString())
+ addQueryParameter("offset", "0")
+ addQueryParameter("includes[]", MDConstants.coverArt)
+ }
+ listDtoFiltered.forEachIndexed() { index, relationshipDto ->
+ if (index >= minIndex && index < (minIndex + MDConstants.mangaLimit)) {
+ url.addQueryParameter("ids[]", relationshipDto.id)
+ }
+ }
+
+ val request = client.newCall(GET(url.build().toString(), headers, CacheControl.FORCE_NETWORK))
+ val mangaList = searchMangaListParse(request.execute())
+ return MangasPage(mangaList, amount.toFloat() / MDConstants.mangaLimit - (page.toFloat() - 1) > 1)
+ }
+
+ private fun searchMangaListParse(response: Response): List {
+ if (response.isSuccessful.not()) {
+ throw Exception("HTTP ${response.code}")
+ }
+
+ val mangaListDto = helper.json.decodeFromString(response.body!!.string())
+
+ val coverSuffix = preferences.getString(MDConstants.getCoverQualityPreferenceKey(dexLang), "")
+
+ val mangaList = mangaListDto.data.map { mangaDataDto ->
+ val fileName = mangaDataDto.relationships.firstOrNull { relationshipDto ->
+ relationshipDto.type.equals(MDConstants.coverArt, true)
+ }?.attributes?.fileName
+ helper.createBasicManga(mangaDataDto, fileName, coverSuffix, dexLang)
+ }
+
+ return mangaList
+ }
+
private fun searchMangaUploaderRequest(page: Int, uploader: String): Request {
val url = MDConstants.apiChapterUrl.toHttpUrlOrNull()!!.newBuilder().apply {
addQueryParameter("offset", helper.getLatestChapterOffset(page))
diff --git a/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MangadexUrlActivity.kt b/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MangadexUrlActivity.kt
index 490f60201..fc473bdf6 100644
--- a/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MangadexUrlActivity.kt
+++ b/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/MangadexUrlActivity.kt
@@ -31,6 +31,7 @@ class MangadexUrlActivity : Activity() {
equals("group") -> putExtra("query", "${MDConstants.prefixGrpSearch}$titleid")
equals("user") -> putExtra("query", "${MDConstants.prefixUsrSearch}$titleid")
equals("author") -> putExtra("query", "${MDConstants.prefixAuthSearch}$titleid")
+ equals("list") -> putExtra("query", "${MDConstants.prefixListSearch}$titleid")
else -> putExtra("query", "${MDConstants.prefixIdSearch}$titleid")
}
}
diff --git a/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/dto/ListDto.kt b/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/dto/ListDto.kt
new file mode 100644
index 000000000..c7b71e69f
--- /dev/null
+++ b/src/all/mangadex/src/eu/kanade/tachiyomi/extension/all/mangadex/dto/ListDto.kt
@@ -0,0 +1,25 @@
+package eu.kanade.tachiyomi.extension.all.mangadex.dto
+
+import kotlinx.serialization.Serializable
+
+@Serializable
+data class ListDto(
+ val result: String,
+ val response: String,
+ val data: ListDataDto,
+)
+
+@Serializable
+data class ListDataDto(
+ val id: String,
+ val type: String,
+ val attributes: ListAttributesDto,
+ val relationships: List,
+)
+
+@Serializable
+data class ListAttributesDto(
+ val name: String,
+ val visibility: String,
+ val version: Int,
+)