Dex fixes (#6856)
* fix some langs * dex bug fixes * add temp cover * local for languages, clean and capitalize demo/rating, fix tags not showing
This commit is contained in:
parent
6191553f89
commit
9a45dc2f8e
@ -5,7 +5,7 @@ ext {
|
|||||||
extName = 'MangaDex'
|
extName = 'MangaDex'
|
||||||
pkgNameSuffix = 'all.mangadex'
|
pkgNameSuffix = 'all.mangadex'
|
||||||
extClass = '.MangaDexFactory'
|
extClass = '.MangaDexFactory'
|
||||||
extVersionCode = 106
|
extVersionCode = 107
|
||||||
libVersion = '1.2'
|
libVersion = '1.2'
|
||||||
containsNsfw = true
|
containsNsfw = true
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,8 @@ import java.text.SimpleDateFormat
|
|||||||
import java.util.Locale
|
import java.util.Locale
|
||||||
import java.util.TimeZone
|
import java.util.TimeZone
|
||||||
|
|
||||||
class MDConstants {
|
object MDConstants {
|
||||||
|
|
||||||
companion object {
|
|
||||||
val uuidRegex =
|
val uuidRegex =
|
||||||
Regex("[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}")
|
Regex("[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}")
|
||||||
|
|
||||||
@ -16,14 +15,16 @@ class MDConstants {
|
|||||||
val atHomePostUrl = "https://api.mangadex.network/report"
|
val atHomePostUrl = "https://api.mangadex.network/report"
|
||||||
val whitespaceRegex = "\\s".toRegex()
|
val whitespaceRegex = "\\s".toRegex()
|
||||||
|
|
||||||
|
val tempCover = "https://i.imgur.com/6TrIues.jpg"
|
||||||
|
|
||||||
val dateFormatter = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss+SSS", Locale.US)
|
val dateFormatter = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss+SSS", Locale.US)
|
||||||
.apply { timeZone = TimeZone.getTimeZone("UTC") }
|
.apply { timeZone = TimeZone.getTimeZone("UTC") }
|
||||||
|
|
||||||
const val prefixIdSearch = "id:"
|
const val prefixIdSearch = "id:"
|
||||||
|
|
||||||
const val dataSaverPrefTitle = "Data saver"
|
const val dataSaverPrefTitle = "Data saver"
|
||||||
const val dataSaverPref = "dataSaver"
|
const val dataSaverPrefSummary = "Enables smaller more compressed images"
|
||||||
|
const val dataSaverPref = "dataSaverV5"
|
||||||
|
|
||||||
const val mdAtHomeTokenLifespan = 10 * 60 * 1000
|
const val mdAtHomeTokenLifespan = 10 * 60 * 1000
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
@ -3,6 +3,8 @@ package eu.kanade.tachiyomi.extension.all.mangadex
|
|||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.content.SharedPreferences
|
import android.content.SharedPreferences
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
|
import androidx.preference.CheckBoxPreference
|
||||||
|
import androidx.preference.PreferenceScreen
|
||||||
import com.github.salomonbrys.kotson.array
|
import com.github.salomonbrys.kotson.array
|
||||||
import com.github.salomonbrys.kotson.get
|
import com.github.salomonbrys.kotson.get
|
||||||
import com.github.salomonbrys.kotson.int
|
import com.github.salomonbrys.kotson.int
|
||||||
@ -20,6 +22,7 @@ import eu.kanade.tachiyomi.source.model.SManga
|
|||||||
import eu.kanade.tachiyomi.source.online.HttpSource
|
import eu.kanade.tachiyomi.source.online.HttpSource
|
||||||
import okhttp3.CacheControl
|
import okhttp3.CacheControl
|
||||||
import okhttp3.Headers
|
import okhttp3.Headers
|
||||||
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
@ -54,12 +57,14 @@ abstract class MangaDex(override val lang: String) : ConfigurableSource, HttpSou
|
|||||||
// POPULAR Manga Section
|
// POPULAR Manga Section
|
||||||
|
|
||||||
override fun popularMangaRequest(page: Int): Request {
|
override fun popularMangaRequest(page: Int): Request {
|
||||||
|
val url = MDConstants.apiMangaUrl.toHttpUrl().newBuilder()
|
||||||
|
.addQueryParameter("order[updatedAt]", "desc")
|
||||||
|
.addQueryParameter("limit", MDConstants.mangaLimit.toString())
|
||||||
|
.addQueryParameter("offset", helper.getMangaListOffset(page))
|
||||||
|
.build().toUrl().toString()
|
||||||
|
|
||||||
return GET(
|
return GET(
|
||||||
url = "${MDConstants.apiMangaUrl}?order[updatedAt]=desc&limit=${MDConstants.mangaLimit}&offset=${
|
url = url,
|
||||||
helper.getMangaListOffset(
|
|
||||||
page
|
|
||||||
)
|
|
||||||
}",
|
|
||||||
headers = headers,
|
headers = headers,
|
||||||
cache = CacheControl.FORCE_NETWORK
|
cache = CacheControl.FORCE_NETWORK
|
||||||
)
|
)
|
||||||
@ -67,7 +72,11 @@ abstract class MangaDex(override val lang: String) : ConfigurableSource, HttpSou
|
|||||||
|
|
||||||
override fun popularMangaParse(response: Response): MangasPage {
|
override fun popularMangaParse(response: Response): MangasPage {
|
||||||
if (response.isSuccessful.not()) {
|
if (response.isSuccessful.not()) {
|
||||||
throw Exception("Error getting popular manga http code: ${response.code}")
|
throw Exception("HTTP ${response.code}")
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.code == 204) {
|
||||||
|
return MangasPage(emptyList(), false)
|
||||||
}
|
}
|
||||||
|
|
||||||
val mangaListResponse = JsonParser.parseString(response.body!!.string()).obj
|
val mangaListResponse = JsonParser.parseString(response.body!!.string()).obj
|
||||||
@ -92,7 +101,7 @@ abstract class MangaDex(override val lang: String) : ConfigurableSource, HttpSou
|
|||||||
return GET(url.toString(), headers, CacheControl.FORCE_NETWORK)
|
return GET(url.toString(), headers, CacheControl.FORCE_NETWORK)
|
||||||
}
|
}
|
||||||
|
|
||||||
val tempUrl = MDConstants.apiMangaUrl.toHttpUrlOrNull()!!.newBuilder()
|
val tempUrl = MDConstants.apiMangaUrl.toHttpUrl().newBuilder()
|
||||||
|
|
||||||
tempUrl.apply {
|
tempUrl.apply {
|
||||||
addQueryParameter("limit", MDConstants.mangaLimit.toString())
|
addQueryParameter("limit", MDConstants.mangaLimit.toString())
|
||||||
@ -124,6 +133,7 @@ abstract class MangaDex(override val lang: String) : ConfigurableSource, HttpSou
|
|||||||
override fun mangaDetailsRequest(manga: SManga): Request {
|
override fun mangaDetailsRequest(manga: SManga): Request {
|
||||||
return GET("${baseUrl}${manga.url}", headers)
|
return GET("${baseUrl}${manga.url}", headers)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get manga details url throws exception if the url is the old format so people migrate
|
* get manga details url throws exception if the url is the old format so people migrate
|
||||||
*/
|
*/
|
||||||
@ -163,16 +173,20 @@ abstract class MangaDex(override val lang: String) : ConfigurableSource, HttpSou
|
|||||||
override fun chapterListParse(response: Response): List<SChapter> {
|
override fun chapterListParse(response: Response): List<SChapter> {
|
||||||
|
|
||||||
if (response.isSuccessful.not()) {
|
if (response.isSuccessful.not()) {
|
||||||
throw Exception("Error getting chapter list http code: ${response.code}")
|
throw Exception("HTTP ${response.code}")
|
||||||
|
}
|
||||||
|
if (response.code == 204) {
|
||||||
|
return emptyList()
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
val chapterListResponse = JsonParser.parseString(response.body!!.string()).obj
|
val chapterListResponse = JsonParser.parseString(response.body!!.string()).obj
|
||||||
|
|
||||||
val chapterListResults = chapterListResponse["results"].array.map { it.obj }.toMutableList()
|
val chapterListResults =
|
||||||
|
chapterListResponse["results"].array.map { it.obj }.toMutableList()
|
||||||
|
|
||||||
val mangaId =
|
val mangaId =
|
||||||
response.request.url.toString().substringBefore("/feed")
|
response.request.url.toString().substringBefore("/feed")
|
||||||
.substringAfter(MDConstants.apiMangaUrl)
|
.substringAfter("${MDConstants.apiMangaUrl}/")
|
||||||
|
|
||||||
val limit = chapterListResponse["limit"].int
|
val limit = chapterListResponse["limit"].int
|
||||||
|
|
||||||
@ -216,7 +230,7 @@ abstract class MangaDex(override val lang: String) : ConfigurableSource, HttpSou
|
|||||||
val host =
|
val host =
|
||||||
helper.getMdAtHomeUrl(atHomeRequestUrl, client, headers, CacheControl.FORCE_NETWORK)
|
helper.getMdAtHomeUrl(atHomeRequestUrl, client, headers, CacheControl.FORCE_NETWORK)
|
||||||
|
|
||||||
val usingDataSaver = preferences.getInt(MDConstants.dataSaverPref, 0) == 1
|
val usingDataSaver = preferences.getBoolean("${MDConstants.dataSaverPref}_$lang", false)
|
||||||
|
|
||||||
// have to add the time, and url to the page because pages timeout within 30mins now
|
// have to add the time, and url to the page because pages timeout within 30mins now
|
||||||
val now = Date().time
|
val now = Date().time
|
||||||
@ -240,22 +254,20 @@ abstract class MangaDex(override val lang: String) : ConfigurableSource, HttpSou
|
|||||||
override fun imageUrlParse(response: Response): String = ""
|
override fun imageUrlParse(response: Response): String = ""
|
||||||
|
|
||||||
// mangadex is mvp no settings yet
|
// mangadex is mvp no settings yet
|
||||||
override fun setupPreferenceScreen(screen: androidx.preference.PreferenceScreen) {
|
override fun setupPreferenceScreen(screen: PreferenceScreen) {
|
||||||
val dataSaverPref = androidx.preference.ListPreference(screen.context).apply {
|
|
||||||
key = MDConstants.dataSaverPref
|
val dataSaverPref = CheckBoxPreference(screen.context).apply {
|
||||||
|
key = "${MDConstants.dataSaverPref}_$lang"
|
||||||
title = MDConstants.dataSaverPrefTitle
|
title = MDConstants.dataSaverPrefTitle
|
||||||
entries = arrayOf("Disable", "Enable")
|
summary = MDConstants.dataSaverPrefSummary
|
||||||
entryValues = arrayOf("0", "1")
|
setDefaultValue(false)
|
||||||
summary = "%s"
|
|
||||||
setDefaultValue("0")
|
|
||||||
|
|
||||||
setOnPreferenceChangeListener { _, newValue ->
|
setOnPreferenceChangeListener { _, newValue ->
|
||||||
val selected = newValue as String
|
val checkValue = newValue as Boolean
|
||||||
val index = this.findIndexOfValue(selected)
|
preferences.edit().putBoolean("${MDConstants.dataSaverPref}_$lang", checkValue)
|
||||||
preferences.edit().putInt(MDConstants.dataSaverPref, index).commit()
|
.commit()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
screen.addPreference(dataSaverPref)
|
screen.addPreference(dataSaverPref)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +48,6 @@ class MangaDexFactory : SourceFactory {
|
|||||||
MangaDexHebrew(),
|
MangaDexHebrew(),
|
||||||
MangaDexHindi(),
|
MangaDexHindi(),
|
||||||
MangaDexNorwegian(),
|
MangaDexNorwegian(),
|
||||||
MangaDexOther()
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -67,12 +66,12 @@ class MangaDexVietnamese : MangaDex("vi")
|
|||||||
class MangaDexGreek : MangaDex("el")
|
class MangaDexGreek : MangaDex("el")
|
||||||
class MangaDexBulgarian : MangaDex("bg")
|
class MangaDexBulgarian : MangaDex("bg")
|
||||||
class MangaDexSpanishSpain : MangaDex("es")
|
class MangaDexSpanishSpain : MangaDex("es")
|
||||||
class MangaDexPortugueseBrazil : MangaDex("pt-BR")
|
class MangaDexPortugueseBrazil : MangaDex("pt-br")
|
||||||
class MangaDexPortuguesePortugal : MangaDex("pt")
|
class MangaDexPortuguesePortugal : MangaDex("pt")
|
||||||
class MangaDexSwedish : MangaDex("sv")
|
class MangaDexSwedish : MangaDex("sv")
|
||||||
class MangaDexArabic : MangaDex("ar")
|
class MangaDexArabic : MangaDex("ar")
|
||||||
class MangaDexDanish : MangaDex("da")
|
class MangaDexDanish : MangaDex("da")
|
||||||
class MangaDexChineseSimp : MangaDex("zh-Hans")
|
class MangaDexChineseSimp : MangaDex("zh")
|
||||||
class MangaDexBengali : MangaDex("bn")
|
class MangaDexBengali : MangaDex("bn")
|
||||||
class MangaDexRomanian : MangaDex("ro")
|
class MangaDexRomanian : MangaDex("ro")
|
||||||
class MangaDexCzech : MangaDex("cs")
|
class MangaDexCzech : MangaDex("cs")
|
||||||
@ -80,17 +79,16 @@ class MangaDexMongolian : MangaDex("mn")
|
|||||||
class MangaDexTurkish : MangaDex("tr")
|
class MangaDexTurkish : MangaDex("tr")
|
||||||
class MangaDexIndonesian : MangaDex("id")
|
class MangaDexIndonesian : MangaDex("id")
|
||||||
class MangaDexKorean : MangaDex("ko")
|
class MangaDexKorean : MangaDex("ko")
|
||||||
class MangaDexSpanishLTAM : MangaDex("es-419")
|
class MangaDexSpanishLTAM : MangaDex("es-la")
|
||||||
class MangaDexPersian : MangaDex("fa")
|
class MangaDexPersian : MangaDex("fa")
|
||||||
class MangaDexMalay : MangaDex("ms")
|
class MangaDexMalay : MangaDex("ms")
|
||||||
class MangaDexThai : MangaDex("th")
|
class MangaDexThai : MangaDex("th")
|
||||||
class MangaDexCatalan : MangaDex("ca")
|
class MangaDexCatalan : MangaDex("ca")
|
||||||
class MangaDexFilipino : MangaDex("fil")
|
class MangaDexFilipino : MangaDex("fi")
|
||||||
class MangaDexChineseTrad : MangaDex("zh-Hant")
|
class MangaDexChineseTrad : MangaDex("zh-hk")
|
||||||
class MangaDexUkrainian : MangaDex("uk")
|
class MangaDexUkrainian : MangaDex("uk")
|
||||||
class MangaDexBurmese : MangaDex("my")
|
class MangaDexBurmese : MangaDex("my")
|
||||||
class MangaDexLithuanian : MangaDex("lt")
|
class MangaDexLithuanian : MangaDex("lt")
|
||||||
class MangaDexHebrew : MangaDex("he")
|
class MangaDexHebrew : MangaDex("he")
|
||||||
class MangaDexHindi : MangaDex("hi")
|
class MangaDexHindi : MangaDex("hi")
|
||||||
class MangaDexNorwegian : MangaDex("no")
|
class MangaDexNorwegian : MangaDex("no")
|
||||||
class MangaDexOther : MangaDex("other")
|
|
||||||
|
@ -65,6 +65,7 @@ class MangaDexFilters {
|
|||||||
internal class Tag(val id: String, name: String) : Filter.TriState(name)
|
internal class Tag(val id: String, name: String) : Filter.TriState(name)
|
||||||
private class TagList(tags: List<Tag>) : Filter.Group<Tag>("Tags", tags)
|
private class TagList(tags: List<Tag>) : Filter.Group<Tag>("Tags", tags)
|
||||||
|
|
||||||
|
// to get all tags from dex https://api.mangadex.org/manga/tag
|
||||||
internal fun getTags() = listOf(
|
internal fun getTags() = listOf(
|
||||||
Tag("391b0423-d847-456f-aff0-8b0cfc03066b", "Action"),
|
Tag("391b0423-d847-456f-aff0-8b0cfc03066b", "Action"),
|
||||||
Tag("f4122d1c-3b44-44d0-9936-ff7502c39ad3", "Adaptation"),
|
Tag("f4122d1c-3b44-44d0-9936-ff7502c39ad3", "Adaptation"),
|
||||||
|
@ -18,6 +18,7 @@ import okhttp3.OkHttpClient
|
|||||||
import okhttp3.Request
|
import okhttp3.Request
|
||||||
import org.jsoup.parser.Parser
|
import org.jsoup.parser.Parser
|
||||||
import java.util.Date
|
import java.util.Date
|
||||||
|
import java.util.Locale
|
||||||
|
|
||||||
class MangaDexHelper() {
|
class MangaDexHelper() {
|
||||||
|
|
||||||
@ -29,15 +30,15 @@ class MangaDexHelper() {
|
|||||||
fun getUUIDFromUrl(url: String) = url.substringAfterLast("/")
|
fun getUUIDFromUrl(url: String) = url.substringAfterLast("/")
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* get the manga feed url
|
* get chapters for manga (aka manga/$id/feed endpoint)
|
||||||
*/
|
*/
|
||||||
fun getChapterEndpoint(mangaId: String, offset: Int, langCode: String) =
|
fun getChapterEndpoint(mangaId: String, offset: Int, langCode: String) =
|
||||||
"${MDConstants.apiMangaUrl}/$mangaId/feed?limit=500&offset=$offset&locales[]=$langCode"
|
"${MDConstants.apiMangaUrl}/$mangaId/feed?limit=500&offset=$offset&locales[]=$langCode"
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the manga id is a valid uuid
|
* Check if the manga url is a valid uuid
|
||||||
*/
|
*/
|
||||||
fun containsUuid(id: String) = id.contains(MDConstants.uuidRegex)
|
fun containsUuid(url: String) = url.contains(MDConstants.uuidRegex)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the manga offset pages are 1 based, so subtract 1
|
* Get the manga offset pages are 1 based, so subtract 1
|
||||||
@ -130,7 +131,7 @@ class MangaDexHelper() {
|
|||||||
return SManga.create().apply {
|
return SManga.create().apply {
|
||||||
url = "/manga/$dexId"
|
url = "/manga/$dexId"
|
||||||
title = cleanString(attr["title"]["en"].string)
|
title = cleanString(attr["title"]["en"].string)
|
||||||
thumbnail_url = ""
|
thumbnail_url = MDConstants.tempCover
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,9 +146,9 @@ class MangaDexHelper() {
|
|||||||
|
|
||||||
// things that will go with the genre tags but aren't actually genre
|
// things that will go with the genre tags but aren't actually genre
|
||||||
val nonGenres = listOf(
|
val nonGenres = listOf(
|
||||||
attr["contentRating"].nullString,
|
(attr["publicationDemographic"]?.nullString ?: "").capitalize(Locale.US),
|
||||||
attr["originalLanguage"]?.nullString,
|
("Content rating: " + (attr["contentRating"].nullString ?: "").capitalize(Locale.US)),
|
||||||
attr["publicationDemographic"]?.nullString
|
Locale(attr["originalLanguage"].nullString ?: "").displayLanguage
|
||||||
)
|
)
|
||||||
|
|
||||||
// get authors ignore if they error, artists are labelled as authors currently
|
// get authors ignore if they error, artists are labelled as authors currently
|
||||||
@ -172,8 +173,8 @@ class MangaDexHelper() {
|
|||||||
val genreList = (
|
val genreList = (
|
||||||
attr["tags"].array
|
attr["tags"].array
|
||||||
.map { it["id"].string }
|
.map { it["id"].string }
|
||||||
.map { dexTag ->
|
.map { dexId ->
|
||||||
tags.firstOrNull { it.name.equals(dexTag, true) }
|
tags.firstOrNull { it.id == dexId }
|
||||||
}.map { it?.name } +
|
}.map { it?.name } +
|
||||||
nonGenres
|
nonGenres
|
||||||
)
|
)
|
||||||
@ -185,7 +186,7 @@ class MangaDexHelper() {
|
|||||||
description = cleanString(attr["description"]["en"].string)
|
description = cleanString(attr["description"]["en"].string)
|
||||||
author = authors.joinToString(", ")
|
author = authors.joinToString(", ")
|
||||||
status = getPublicationStatus(attr["publicationDemographic"].nullString)
|
status = getPublicationStatus(attr["publicationDemographic"].nullString)
|
||||||
thumbnail_url = ""
|
thumbnail_url = MDConstants.tempCover
|
||||||
genre = genreList.joinToString(", ")
|
genre = genreList.joinToString(", ")
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user