Added support for OriginLanguage filtering in latest and browse, fixed porn chapters too (#8993)

* Added originalLanguage filters

* add content preference in chapter list

* Remove zero width space

* change default originLanguagepref to false

* made originLang work in browse too

* actually fixed nsfw chapter list maybe

* added new MangaDex icons

* filter all chapters with external links

* change browse sort to followCount

* add origin language filtering to browse and properly set default filter values

* add all contentRating queries to the actual chapterlist request no matter what
This commit is contained in:
loocool2 2021-09-08 12:38:29 -07:00 committed by GitHub
parent f91e5f6b41
commit 75bdb0bec5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 146 additions and 26 deletions

View File

@ -6,7 +6,7 @@ ext {
extName = 'MangaDex' extName = 'MangaDex'
pkgNameSuffix = 'all.mangadex' pkgNameSuffix = 'all.mangadex'
extClass = '.MangaDexFactory' extClass = '.MangaDexFactory'
extVersionCode = 130 extVersionCode = 131
libVersion = '1.2' libVersion = '1.2'
containsNsfw = true containsNsfw = true
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.5 KiB

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 31 KiB

After

Width:  |  Height:  |  Size: 24 KiB

View File

@ -80,4 +80,22 @@ object MDConstants {
fun getContentRatingPornographicPrefKey(dexLang: String): String { fun getContentRatingPornographicPrefKey(dexLang: String): String {
return "${contentRatingPornographicPref}_$dexLang" return "${contentRatingPornographicPref}_$dexLang"
} }
private const val originalLanguageJapanesePref = "originalLanguageJapanese"
fun getOriginalLanguageJapanesePref(dexLang: String): String {
return "${originalLanguageJapanesePref}_$dexLang"
}
private const val originalLanguageChinesePref = "originalLanguageChinese"
fun getOriginalLanguageChinesePref(dexLang: String): String {
return "${originalLanguageChinesePref}_$dexLang"
}
private const val originalLanguageKoreanPref = "originalLanguageKorean"
fun getOriginalLanguageKoreanPref(dexLang: String): String {
return "${originalLanguageKoreanPref}_$dexLang"
}
} }

View File

@ -61,7 +61,7 @@ abstract class MangaDex(override val lang: String, val dexLang: String) :
override fun popularMangaRequest(page: Int): Request { override fun popularMangaRequest(page: Int): Request {
val url = MDConstants.apiMangaUrl.toHttpUrl().newBuilder().apply { val url = MDConstants.apiMangaUrl.toHttpUrl().newBuilder().apply {
addQueryParameter("order[updatedAt]", "desc") addQueryParameter("order[followedCount]", "desc")
addQueryParameter("limit", MDConstants.mangaLimit.toString()) addQueryParameter("limit", MDConstants.mangaLimit.toString())
addQueryParameter("offset", helper.getMangaListOffset(page)) addQueryParameter("offset", helper.getMangaListOffset(page))
addQueryParameter("includes[]", MDConstants.coverArt) addQueryParameter("includes[]", MDConstants.coverArt)
@ -89,6 +89,29 @@ abstract class MangaDex(override val lang: String, val dexLang: String) :
) { ) {
addQueryParameter("contentRating[]", "pornographic") addQueryParameter("contentRating[]", "pornographic")
} }
if (preferences.getBoolean(
MDConstants.getOriginalLanguageJapanesePref(dexLang),
false
)
) {
addQueryParameter("originalLanguage[]", "ja")
}
// dex has zh and zh-hk for chinese manhua
if (preferences.getBoolean(
MDConstants.getOriginalLanguageChinesePref(dexLang),
false
)
) {
addQueryParameter("originalLanguage[]", "zh")
addQueryParameter("originalLanguage[]", "zh-hk")
}
if (preferences.getBoolean(
MDConstants.getOriginalLanguageKoreanPref(dexLang),
false
)
) {
addQueryParameter("originalLanguage[]", "ko")
}
}.build().toUrl().toString() }.build().toUrl().toString()
return GET( return GET(
url = url, url = url,
@ -144,6 +167,17 @@ abstract class MangaDex(override val lang: String, val dexLang: String) :
if (preferences.getBoolean(MDConstants.getContentRatingPornographicPrefKey(dexLang), false)) { if (preferences.getBoolean(MDConstants.getContentRatingPornographicPrefKey(dexLang), false)) {
addQueryParameter("contentRating[]", "pornographic") addQueryParameter("contentRating[]", "pornographic")
} }
if (preferences.getBoolean(MDConstants.getOriginalLanguageJapanesePref(dexLang), false)) {
addQueryParameter("originalLanguage[]", "ja")
}
// dex has zh and zh-hk for chinese manhua
if (preferences.getBoolean(MDConstants.getOriginalLanguageChinesePref(dexLang), false)) {
addQueryParameter("originalLanguage[]", "zh")
addQueryParameter("originalLanguage[]", "zh-hk")
}
if (preferences.getBoolean(MDConstants.getOriginalLanguageKoreanPref(dexLang), false)) {
addQueryParameter("originalLanguage[]", "ko")
}
mangaIds.forEach { id -> mangaIds.forEach { id ->
addQueryParameter("ids[]", id) addQueryParameter("ids[]", id)
@ -308,15 +342,16 @@ abstract class MangaDex(override val lang: String, val dexLang: String) :
/** /**
* Required because api is paged * Required because api is paged
*/ */
private fun actualChapterListRequest(mangaId: String, offset: Int) = private fun actualChapterListRequest(mangaId: String, offset: Int): Request {
GET( val url = helper.getChapterEndpoint(mangaId, offset, dexLang).toHttpUrlOrNull()!!.newBuilder().apply {
url = helper.getChapterEndpoint(mangaId, offset, dexLang), addQueryParameter("contentRating[]", "safe")
headers = headers, addQueryParameter("contentRating[]", "suggestive")
cache = CacheControl.FORCE_NETWORK addQueryParameter("contentRating[]", "erotica")
) addQueryParameter("contentRating[]", "pornographic")
}.build().toString()
return GET(url, headers = headers, cache = CacheControl.FORCE_NETWORK)
}
override fun chapterListParse(response: Response): List<SChapter> { override fun chapterListParse(response: Response): List<SChapter> {
if (response.isSuccessful.not()) { if (response.isSuccessful.not()) {
throw Exception("HTTP ${response.code}") throw Exception("HTTP ${response.code}")
} }
@ -350,15 +385,15 @@ abstract class MangaDex(override val lang: String, val dexLang: String) :
val now = Date().time val now = Date().time
return chapterListResults.map { helper.createChapter(it) } return chapterListResults.mapNotNull { helper.createChapter(it) }
.filter { it.date_upload <= now && "MangaPlus" != it.scanlator .filter {
&& "Comikey" != it.scanlator} it.date_upload <= now
}
} catch (e: Exception) { } catch (e: Exception) {
Log.e("MangaDex", "error parsing chapter list", e) Log.e("MangaDex", "error parsing chapter list", e)
throw(e) throw(e)
} }
} }
override fun pageListRequest(chapter: SChapter): Request { override fun pageListRequest(chapter: SChapter): Request {
if (!helper.containsUuid(chapter.url)) { if (!helper.containsUuid(chapter.url)) {
throw Exception("Migrate this manga from MangaDex to MangaDex to update it") throw Exception("Migrate this manga from MangaDex to MangaDex to update it")
@ -515,6 +550,48 @@ abstract class MangaDex(override val lang: String, val dexLang: String) :
} }
} }
val originalLanguageJapanesePref = SwitchPreferenceCompat(screen.context).apply {
key = MDConstants.getOriginalLanguageJapanesePref(dexLang)
title = "Japanese"
summary = "If enabled, only shows content that was originally published in Japanese in both latest and browse"
setDefaultValue(false)
setOnPreferenceChangeListener { _, newValue ->
val checkValue = newValue as Boolean
preferences.edit()
.putBoolean(MDConstants.getOriginalLanguageJapanesePref(dexLang), checkValue)
.commit()
}
}
val originalLanguageChinesePref = SwitchPreferenceCompat(screen.context).apply {
key = MDConstants.getOriginalLanguageChinesePref(dexLang)
title = "Chinese"
summary = "If enabled, only shows content that was originally published in Chinese in both latest and browse"
setDefaultValue(false)
setOnPreferenceChangeListener { _, newValue ->
val checkValue = newValue as Boolean
preferences.edit()
.putBoolean(MDConstants.getOriginalLanguageChinesePref(dexLang), checkValue)
.commit()
}
}
val originalLanguageKoreanPref = SwitchPreferenceCompat(screen.context).apply {
key = MDConstants.getOriginalLanguageKoreanPref(dexLang)
title = "Korean"
summary = "If enabled, only shows content that was originally published in Korean in both latest and browse"
setDefaultValue(false)
setOnPreferenceChangeListener { _, newValue ->
val checkValue = newValue as Boolean
preferences.edit()
.putBoolean(MDConstants.getOriginalLanguageKoreanPref(dexLang), checkValue)
.commit()
}
}
screen.addPreference(coverQualityPref) screen.addPreference(coverQualityPref)
screen.addPreference(dataSaverPref) screen.addPreference(dataSaverPref)
screen.addPreference(standardHttpsPortPref) screen.addPreference(standardHttpsPortPref)
@ -522,6 +599,9 @@ abstract class MangaDex(override val lang: String, val dexLang: String) :
screen.addPreference(contentRatingSuggestivePref) screen.addPreference(contentRatingSuggestivePref)
screen.addPreference(contentRatingEroticaPref) screen.addPreference(contentRatingEroticaPref)
screen.addPreference(contentRatingPornographicPref) screen.addPreference(contentRatingPornographicPref)
screen.addPreference(originalLanguageJapanesePref)
screen.addPreference(originalLanguageChinesePref)
screen.addPreference(originalLanguageKoreanPref)
} }
override fun getFilterList(): FilterList = override fun getFilterList(): FilterList =

View File

@ -11,7 +11,7 @@ class MangaDexFilters {
internal fun getMDFilterList(preferences: SharedPreferences, dexLang: String): FilterList { internal fun getMDFilterList(preferences: SharedPreferences, dexLang: String): FilterList {
return FilterList( return FilterList(
OriginalLanguageList(getOriginalLanguage()), OriginalLanguageList(getOriginalLanguage(preferences, dexLang)),
ContentRatingList(getContentRating(preferences, dexLang)), ContentRatingList(getContentRating(preferences, dexLang)),
DemographicList(getDemographics()), DemographicList(getDemographics()),
StatusList(getStatus()), StatusList(getStatus()),
@ -24,8 +24,10 @@ class MangaDexFilters {
private fun getContentRating(preferences: SharedPreferences, dexLang: String) = listOf( private fun getContentRating(preferences: SharedPreferences, dexLang: String) = listOf(
ContentRating("Safe").apply { ContentRating("Safe").apply {
state = state = preferences.getBoolean(
preferences.getBoolean(MDConstants.getContentRatingSafePrefKey(dexLang), true) MDConstants.getContentRatingSafePrefKey(dexLang),
true
)
}, },
ContentRating("Suggestive").apply { ContentRating("Suggestive").apply {
state = preferences.getBoolean( state = preferences.getBoolean(
@ -78,10 +80,25 @@ class MangaDexFilters {
private class OriginalLanguageList(originalLanguage: List<OriginalLanguage>) : private class OriginalLanguageList(originalLanguage: List<OriginalLanguage>) :
Filter.Group<OriginalLanguage>("Original language", originalLanguage) Filter.Group<OriginalLanguage>("Original language", originalLanguage)
private fun getOriginalLanguage() = listOf( private fun getOriginalLanguage(preferences: SharedPreferences, dexLang: String) = listOf(
OriginalLanguage("Japanese (Manga)", "ja"), OriginalLanguage("Japanese (Manga)", "ja").apply {
OriginalLanguage("Chinese (Manhua)", "zh"), state = preferences.getBoolean(
OriginalLanguage("Korean (Manhwa)", "ko"), MDConstants.getOriginalLanguageJapanesePref(dexLang),
false
)
},
OriginalLanguage("Chinese (Manhua)", "zh").apply {
state = preferences.getBoolean(
MDConstants.getOriginalLanguageChinesePref(dexLang),
false
)
},
OriginalLanguage("Korean (Manhwa)", "ko").apply {
state = preferences.getBoolean(
MDConstants.getOriginalLanguageKoreanPref(dexLang),
false
)
},
) )
internal class Tag(val id: String, name: String) : Filter.TriState(name) internal class Tag(val id: String, name: String) : Filter.TriState(name)

View File

@ -172,7 +172,7 @@ class MangaDexHelper() {
title = cleanString(mangaDto.data.attributes.title.asMdMap()["en"] ?: "") title = cleanString(mangaDto.data.attributes.title.asMdMap()["en"] ?: "")
coverFileName?.let { coverFileName?.let {
thumbnail_url = when(coverSuffix != null && coverSuffix != "") { thumbnail_url = when (coverSuffix != null && coverSuffix != "") {
true -> "${MDConstants.cdnUrl}/covers/${mangaDto.data.id}/$coverFileName$coverSuffix" true -> "${MDConstants.cdnUrl}/covers/${mangaDto.data.id}/$coverFileName$coverSuffix"
else -> "${MDConstants.cdnUrl}/covers/${mangaDto.data.id}/$coverFileName" else -> "${MDConstants.cdnUrl}/covers/${mangaDto.data.id}/$coverFileName"
} }
@ -248,7 +248,7 @@ class MangaDexHelper() {
/** /**
* create the SChapter from json * create the SChapter from json
*/ */
fun createChapter(chapterDto: ChapterDto): SChapter { fun createChapter(chapterDto: ChapterDto): SChapter? {
try { try {
val data = chapterDto.data val data = chapterDto.data
val attr = data.attributes val attr = data.attributes
@ -287,6 +287,10 @@ class MangaDexHelper() {
} }
} }
if (attr.externalUrl != null && attr.data.isEmpty()) {
return null
}
// if volume, chapter and title is empty its a oneshot // if volume, chapter and title is empty its a oneshot
if (chapterName.isEmpty()) { if (chapterName.isEmpty()) {
chapterName.add("Oneshot") chapterName.add("Oneshot")

View File

@ -33,4 +33,5 @@ data class ChapterAttributesDto(
val data: List<String>, val data: List<String>,
val dataSaver: List<String>, val dataSaver: List<String>,
val hash: String, val hash: String,
val externalUrl: String?,
) )