Fix Mangadex Login, Fix Mangadex tracking, Set Mangadex track status to Reading on tracked
This commit is contained in:
@@ -28,6 +28,7 @@ import okhttp3.Headers
|
||||
import okhttp3.OkHttpClient
|
||||
import okhttp3.Request
|
||||
import okhttp3.Response
|
||||
import okio.EOFException
|
||||
|
||||
class FollowsHandler(val client: OkHttpClient, val headers: Headers, val preferences: PreferencesHelper, private val useLowQualityCovers: Boolean) {
|
||||
|
||||
@@ -75,7 +76,6 @@ class FollowsHandler(val client: OkHttpClient, val headers: Headers, val prefere
|
||||
/**
|
||||
* fetch follow status used when fetching status for 1 manga
|
||||
*/
|
||||
|
||||
private fun followStatusParse(response: Response): Track {
|
||||
val followsPageResult = try {
|
||||
response.parseAs<FollowsIndividualSerializer>(MdUtil.jsonParser)
|
||||
@@ -84,15 +84,11 @@ class FollowsHandler(val client: OkHttpClient, val headers: Headers, val prefere
|
||||
throw e
|
||||
}
|
||||
|
||||
if (followsPageResult.data == null) {
|
||||
throw Exception("Invalid response ${followsPageResult.code}")
|
||||
}
|
||||
|
||||
val track = Track.create(TrackManager.MDLIST)
|
||||
if (followsPageResult.code == 404) {
|
||||
track.status = FollowStatus.UNFOLLOWED.int
|
||||
} else {
|
||||
val follow = followsPageResult.data
|
||||
val follow = followsPageResult.data ?: throw Exception("Invalid response ${followsPageResult.code}")
|
||||
track.status = follow.followType
|
||||
if (follow.chapter.isNotBlank()) {
|
||||
track.last_chapter_read = follow.chapter.toFloat().floor()
|
||||
@@ -153,7 +149,7 @@ class FollowsHandler(val client: OkHttpClient, val headers: Headers, val prefere
|
||||
.await()
|
||||
}
|
||||
|
||||
withIOContext { response.body?.string().isNullOrEmpty() }
|
||||
response.succeeded()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,11 +168,7 @@ class FollowsHandler(val client: OkHttpClient, val headers: Headers, val prefere
|
||||
)
|
||||
).await()
|
||||
|
||||
withIOContext {
|
||||
response.body?.string()
|
||||
.also { xLogD(it) }
|
||||
.let { it != null && it.isEmpty() }
|
||||
}
|
||||
response.succeeded()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,10 +180,21 @@ class FollowsHandler(val client: OkHttpClient, val headers: Headers, val prefere
|
||||
"${MdUtil.baseUrl}/ajax/actions.ajax.php?function=manga_rating&id=$mangaID&rating=${track.score.toInt()}",
|
||||
headers
|
||||
)
|
||||
)
|
||||
.await()
|
||||
).await()
|
||||
|
||||
withIOContext { response.body?.string().isNullOrEmpty() }
|
||||
response.succeeded()
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun Response.succeeded() = withIOContext {
|
||||
try {
|
||||
body?.string().let { body ->
|
||||
(body != null && body.isEmpty()).also {
|
||||
if (!it) xLogD(body)
|
||||
}
|
||||
}
|
||||
} catch (e: EOFException) {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import exh.md.handlers.serializers.ApiCovers
|
||||
import exh.md.handlers.serializers.ApiMangaSerializer
|
||||
import exh.md.utils.MdUtil
|
||||
import exh.metadata.metadata.MangaDexSearchMetadata
|
||||
import kotlinx.coroutines.async
|
||||
import okhttp3.CacheControl
|
||||
import okhttp3.Headers
|
||||
import okhttp3.OkHttpClient
|
||||
@@ -30,7 +31,7 @@ class MangaHandler(val client: OkHttpClient, val headers: Headers, val lang: Str
|
||||
// TODO make use of this
|
||||
suspend fun fetchMangaAndChapterDetails(manga: MangaInfo, sourceId: Long): Pair<MangaInfo, List<ChapterInfo>> {
|
||||
return withIOContext {
|
||||
val apiNetworkManga = client.newCall(apiRequest(manga)).await().parseAs<ApiMangaSerializer>()
|
||||
val apiNetworkManga = client.newCall(apiRequest(manga)).await().parseAs<ApiMangaSerializer>(MdUtil.jsonParser)
|
||||
val covers = getCovers(manga, forceLatestCovers)
|
||||
val parser = ApiMangaParser(lang)
|
||||
|
||||
@@ -120,17 +121,22 @@ class MangaHandler(val client: OkHttpClient, val headers: Headers, val lang: Str
|
||||
}
|
||||
|
||||
suspend fun getTrackingInfo(track: Track, useLowQualityCovers: Boolean): Pair<Track, MangaDexSearchMetadata> {
|
||||
val mangaUrl = MdUtil.mapMdIdToMangaUrl(MdUtil.getMangaId(track.tracking_url).toInt())
|
||||
val manga = MangaInfo(mangaUrl, track.title)
|
||||
val response = client.newCall(apiRequest(manga)).await()
|
||||
val metadata = MangaDexSearchMetadata()
|
||||
ApiMangaParser(lang).parseIntoMetadata(metadata, response, emptyList())
|
||||
val remoteTrack = FollowsHandler(client, headers, Injekt.get(), useLowQualityCovers).fetchTrackingInfo(track.tracking_url)
|
||||
return remoteTrack to metadata
|
||||
return withIOContext {
|
||||
val metadata = async {
|
||||
val mangaUrl = MdUtil.mapMdIdToMangaUrl(MdUtil.getMangaId(track.tracking_url).toInt())
|
||||
val manga = MangaInfo(mangaUrl, track.title)
|
||||
val response = client.newCall(apiRequest(manga)).await()
|
||||
val metadata = MangaDexSearchMetadata()
|
||||
ApiMangaParser(lang).parseIntoMetadata(metadata, response, emptyList())
|
||||
metadata
|
||||
}
|
||||
val remoteTrack = async { FollowsHandler(client, headers, Injekt.get(), useLowQualityCovers).fetchTrackingInfo(track.tracking_url) }
|
||||
remoteTrack.await() to metadata.await()
|
||||
}
|
||||
}
|
||||
|
||||
private fun randomMangaRequest(): Request {
|
||||
return GET(MdUtil.baseUrl + MdUtil.randMangaPage, cache = CacheControl.Builder().noCache().build())
|
||||
return GET(MdUtil.baseUrl + MdUtil.randMangaPage, cache = CacheControl.FORCE_NETWORK)
|
||||
}
|
||||
|
||||
private fun apiRequest(manga: MangaInfo): Request {
|
||||
|
||||
@@ -11,7 +11,7 @@ data class FollowsPageSerializer(
|
||||
@Serializable
|
||||
data class FollowsIndividualSerializer(
|
||||
val code: Int,
|
||||
val data: FollowPage?
|
||||
val data: FollowPage? = null
|
||||
)
|
||||
|
||||
@Serializable
|
||||
|
||||
@@ -31,6 +31,7 @@ class MdUtil {
|
||||
const val apiChapterSuffix = "?mark_read=0"
|
||||
const val groupSearchUrl = "$baseUrl/groups/0/1/"
|
||||
const val followsAllApi = "/v2/user/me/followed-manga"
|
||||
const val isLoggedInApi = "/v2/user/me"
|
||||
const val followsMangaApi = "/v2/user/me/manga/"
|
||||
const val apiCovers = "/covers"
|
||||
const val reportUrl = "https://api.mangadex.network/report"
|
||||
@@ -51,10 +52,16 @@ class MdUtil {
|
||||
val englishDescriptionTags = listOf(
|
||||
"[b][u]English:",
|
||||
"[b][u]English",
|
||||
"English:",
|
||||
"English :",
|
||||
"[English]:",
|
||||
"English Translaton:",
|
||||
"[B][ENG][/B]"
|
||||
)
|
||||
|
||||
val bbCodeToRemove = listOf(
|
||||
"list", "*", "hr", "u", "b", "i", "s", "center", "spoiler="
|
||||
)
|
||||
val descriptionLanguages = listOf(
|
||||
"=FRANCAIS=",
|
||||
"[b] Spanish: [/ b]",
|
||||
@@ -78,19 +85,23 @@ class MdUtil {
|
||||
"\r\n\r\nItalian\r\n",
|
||||
"Arabic /",
|
||||
"Descriptions in Other Languages",
|
||||
"Español /",
|
||||
"Español:",
|
||||
"Espanol",
|
||||
"[Españ",
|
||||
"Españ",
|
||||
"Farsi/",
|
||||
"Français",
|
||||
"French - ",
|
||||
"Francois",
|
||||
"French:",
|
||||
"French/",
|
||||
"French /",
|
||||
"German/",
|
||||
"German /",
|
||||
"Hindi /",
|
||||
"Bahasa Indonesia",
|
||||
"Indonesia:",
|
||||
"Indonesian:",
|
||||
"Indonesian :",
|
||||
"Indo:",
|
||||
"[u]Indonesian",
|
||||
"Italian / ",
|
||||
@@ -98,9 +109,16 @@ class MdUtil {
|
||||
"Italian/",
|
||||
"Italiano",
|
||||
"Italian:",
|
||||
"Italian summary:",
|
||||
"Japanese /",
|
||||
"Original Japanese",
|
||||
"Official Japanese Translation",
|
||||
"Official Chinese Translation",
|
||||
"Official French Translation",
|
||||
"Official Indonesian Translation",
|
||||
"Links:",
|
||||
"Pasta-Pizza-Mandolino/Italiano",
|
||||
"Persian/فارسی",
|
||||
"Persian /فارسی",
|
||||
"Polish /",
|
||||
"Polish Summary /",
|
||||
@@ -108,6 +126,8 @@ class MdUtil {
|
||||
"Polski",
|
||||
"Português",
|
||||
"Portuguese (BR)",
|
||||
"PT/BR:",
|
||||
"Pt/Br:",
|
||||
"Pt-Br:",
|
||||
"Portuguese /",
|
||||
"[right]",
|
||||
@@ -115,6 +135,8 @@ class MdUtil {
|
||||
"Résume Français",
|
||||
"RÉSUMÉ FRANCAIS :",
|
||||
"RUS:",
|
||||
"Ru/Pyc",
|
||||
"\\r\\nRUS\\r\\n",
|
||||
"Russia/",
|
||||
"Russian /",
|
||||
"Spanish:",
|
||||
@@ -162,23 +184,22 @@ class MdUtil {
|
||||
fun removeTimeParamUrl(url: String): String = url.substringBeforeLast("?")
|
||||
|
||||
fun cleanString(string: String): String {
|
||||
var cleanedString = string
|
||||
|
||||
bbCodeToRemove.forEach {
|
||||
cleanedString = cleanedString.replace("[$it]", "", true)
|
||||
.replace("[/$it]", "", true)
|
||||
}
|
||||
|
||||
val bbRegex =
|
||||
"""\[(\w+)[^]]*](.*?)\[/\1]""".toRegex()
|
||||
var intermediate = string
|
||||
.replace("[list]", "", true)
|
||||
.replace("[/list]", "", true)
|
||||
.replace("[*]", "")
|
||||
.replace("[hr]", "", true)
|
||||
.replace("[u]", "", true)
|
||||
.replace("[/u]", "", true)
|
||||
.replace("[b]", "", true)
|
||||
.replace("[/b]", "", true)
|
||||
|
||||
// Recursively remove nested bbcode
|
||||
while (bbRegex.containsMatchIn(intermediate)) {
|
||||
intermediate = intermediate.replace(bbRegex, "$2")
|
||||
while (bbRegex.containsMatchIn(cleanedString)) {
|
||||
cleanedString = cleanedString.replace(bbRegex, "$2")
|
||||
}
|
||||
return Parser.unescapeEntities(intermediate, false)
|
||||
|
||||
return Parser.unescapeEntities(cleanedString, false)
|
||||
}
|
||||
|
||||
fun cleanDescription(string: String): String {
|
||||
|
||||
Reference in New Issue
Block a user