mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-12-25 03:51:49 +01:00
Added Start/Finished Date Support to AniList
This commit is contained in:
parent
707dfd8c0a
commit
1e3de8a67f
@ -22,6 +22,8 @@ class Anilist(private val context: Context, id: Int) : TrackService(id) {
|
|||||||
|
|
||||||
private val api by lazy { AnilistApi(client, interceptor) }
|
private val api by lazy { AnilistApi(client, interceptor) }
|
||||||
|
|
||||||
|
override val supportsReadingDates: Boolean = true
|
||||||
|
|
||||||
private val scorePreference = preferences.anilistScoreType()
|
private val scorePreference = preferences.anilistScoreType()
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
@ -1,6 +1,9 @@
|
|||||||
package eu.kanade.tachiyomi.data.track.anilist
|
package eu.kanade.tachiyomi.data.track.anilist
|
||||||
|
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
|
import com.afollestad.date.dayOfMonth
|
||||||
|
import com.afollestad.date.month
|
||||||
|
import com.afollestad.date.year
|
||||||
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.jsonObject
|
import com.github.salomonbrys.kotson.jsonObject
|
||||||
@ -11,6 +14,7 @@ import com.google.gson.JsonObject
|
|||||||
import com.google.gson.JsonParser
|
import com.google.gson.JsonParser
|
||||||
import eu.kanade.tachiyomi.data.database.models.Track
|
import eu.kanade.tachiyomi.data.database.models.Track
|
||||||
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
import eu.kanade.tachiyomi.data.track.model.TrackSearch
|
||||||
|
import eu.kanade.tachiyomi.network.await
|
||||||
import eu.kanade.tachiyomi.network.jsonType
|
import eu.kanade.tachiyomi.network.jsonType
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
@ -21,6 +25,7 @@ import okhttp3.RequestBody.Companion.toRequestBody
|
|||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.util.Calendar
|
import java.util.Calendar
|
||||||
|
import java.util.Date
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
|
|
||||||
class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|
class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|
||||||
@ -61,7 +66,9 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|
|||||||
"listId" to track.library_id,
|
"listId" to track.library_id,
|
||||||
"progress" to track.last_chapter_read,
|
"progress" to track.last_chapter_read,
|
||||||
"status" to track.toAnilistStatus(),
|
"status" to track.toAnilistStatus(),
|
||||||
"score" to track.score.toInt()
|
"score" to track.score.toInt(),
|
||||||
|
"startedAt" to createDate(track.started_reading_date),
|
||||||
|
"completedAt" to createDate(track.finished_reading_date)
|
||||||
)
|
)
|
||||||
val payload = jsonObject(
|
val payload = jsonObject(
|
||||||
"query" to updateInLibraryQuery(),
|
"query" to updateInLibraryQuery(),
|
||||||
@ -69,7 +76,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|
|||||||
)
|
)
|
||||||
val body = payload.toString().toRequestBody(MediaType.jsonType())
|
val body = payload.toString().toRequestBody(MediaType.jsonType())
|
||||||
val request = Request.Builder().url(apiUrl).post(body).build()
|
val request = Request.Builder().url(apiUrl).post(body).build()
|
||||||
val response = authClient.newCall(request).execute()
|
val response = authClient.newCall(request).await()
|
||||||
|
|
||||||
track
|
track
|
||||||
}
|
}
|
||||||
@ -86,7 +93,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|
|||||||
)
|
)
|
||||||
val body = payload.toString().toRequestBody(MediaType.jsonType())
|
val body = payload.toString().toRequestBody(MediaType.jsonType())
|
||||||
val request = Request.Builder().url(apiUrl).post(body).build()
|
val request = Request.Builder().url(apiUrl).post(body).build()
|
||||||
val netResponse = authClient.newCall(request).execute()
|
val netResponse = authClient.newCall(request).await()
|
||||||
val response = responseToJson(netResponse)
|
val response = responseToJson(netResponse)
|
||||||
|
|
||||||
val media = response["data"]!!.obj["Page"].obj["media"].array
|
val media = response["data"]!!.obj["Page"].obj["media"].array
|
||||||
@ -108,7 +115,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|
|||||||
)
|
)
|
||||||
val body = payload.toString().toRequestBody(MediaType.jsonType())
|
val body = payload.toString().toRequestBody(MediaType.jsonType())
|
||||||
val request = Request.Builder().url(apiUrl).post(body).build()
|
val request = Request.Builder().url(apiUrl).post(body).build()
|
||||||
val result = authClient.newCall(request).execute()
|
val result = authClient.newCall(request).await()
|
||||||
|
|
||||||
result.let { resp ->
|
result.let { resp ->
|
||||||
val response = responseToJson(resp)
|
val response = responseToJson(resp)
|
||||||
@ -143,7 +150,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|
|||||||
|
|
||||||
val body = payload.toString().toRequestBody(MediaType.jsonType())
|
val body = payload.toString().toRequestBody(MediaType.jsonType())
|
||||||
val request = Request.Builder().url(apiUrl).post(body).build()
|
val request = Request.Builder().url(apiUrl).post(body).build()
|
||||||
val result = authClient.newCall(request).execute()
|
val result = authClient.newCall(request).await()
|
||||||
return@withContext true
|
return@withContext true
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Timber.w(e)
|
Timber.w(e)
|
||||||
@ -168,7 +175,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|
|||||||
)
|
)
|
||||||
val body = payload.toString().toRequestBody(MediaType.jsonType())
|
val body = payload.toString().toRequestBody(MediaType.jsonType())
|
||||||
val request = Request.Builder().url(apiUrl).post(body).build()
|
val request = Request.Builder().url(apiUrl).post(body).build()
|
||||||
val netResponse = authClient.newCall(request).execute()
|
val netResponse = authClient.newCall(request).await()
|
||||||
|
|
||||||
val response = responseToJson(netResponse)
|
val response = responseToJson(netResponse)
|
||||||
val viewer = response["data"]!!.obj["Viewer"].obj
|
val viewer = response["data"]!!.obj["Viewer"].obj
|
||||||
@ -188,18 +195,6 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun jsonToALManga(struct: JsonObject): ALManga {
|
private fun jsonToALManga(struct: JsonObject): ALManga {
|
||||||
val date = try {
|
|
||||||
val date = Calendar.getInstance()
|
|
||||||
date.set(
|
|
||||||
struct["startDate"]["year"].nullInt ?: 0,
|
|
||||||
(struct["startDate"]["month"].nullInt ?: 0) - 1,
|
|
||||||
struct["startDate"]["day"].nullInt ?: 0
|
|
||||||
)
|
|
||||||
date.timeInMillis
|
|
||||||
} catch (_: Exception) {
|
|
||||||
0L
|
|
||||||
}
|
|
||||||
|
|
||||||
return ALManga(
|
return ALManga(
|
||||||
struct["id"].asInt,
|
struct["id"].asInt,
|
||||||
struct["title"]["romaji"].asString,
|
struct["title"]["romaji"].asString,
|
||||||
@ -207,17 +202,47 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|
|||||||
struct["description"].nullString.orEmpty(),
|
struct["description"].nullString.orEmpty(),
|
||||||
struct["type"].asString,
|
struct["type"].asString,
|
||||||
struct["status"].nullString.orEmpty(),
|
struct["status"].nullString.orEmpty(),
|
||||||
date,
|
parseDate(struct, "startDate"),
|
||||||
struct["chapters"].nullInt ?: 0
|
struct["chapters"].nullInt ?: 0
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun parseDate(struct: JsonObject, dateKey: String): Long {
|
||||||
|
return try {
|
||||||
|
val year = struct[dateKey]["year"].nullInt ?: throw Exception()
|
||||||
|
val month = struct[dateKey]["month"].nullInt?.minus(1) ?: throw Exception()
|
||||||
|
val day = struct[dateKey]["day"].nullInt ?: throw Exception()
|
||||||
|
val date = Calendar.getInstance()
|
||||||
|
date.set(year, month, day)
|
||||||
|
date.timeInMillis
|
||||||
|
} catch (_: Exception) {
|
||||||
|
0L
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createDate(dateValue: Long): JsonObject {
|
||||||
|
if (dateValue == 0L) return jsonObject(
|
||||||
|
"year" to null,
|
||||||
|
"month" to null,
|
||||||
|
"day" to null,
|
||||||
|
)
|
||||||
|
val calendar = Calendar.getInstance()
|
||||||
|
calendar.timeInMillis = dateValue
|
||||||
|
return jsonObject(
|
||||||
|
"year" to calendar.year,
|
||||||
|
"month" to calendar.month + 1,
|
||||||
|
"day" to calendar.dayOfMonth,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private fun jsonToALUserManga(struct: JsonObject): ALUserManga {
|
private fun jsonToALUserManga(struct: JsonObject): ALUserManga {
|
||||||
return ALUserManga(
|
return ALUserManga(
|
||||||
struct["id"].asLong,
|
struct["id"].asLong,
|
||||||
struct["status"].asString,
|
struct["status"].asString,
|
||||||
struct["scoreRaw"].asInt,
|
struct["scoreRaw"].asInt,
|
||||||
struct["progress"].asInt,
|
struct["progress"].asInt,
|
||||||
|
parseDate(struct, "startedAt"),
|
||||||
|
parseDate(struct, "completedAt"),
|
||||||
jsonToALManga(struct["media"].obj)
|
jsonToALManga(struct["media"].obj)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -258,8 +283,8 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|
|||||||
|
|
||||||
fun updateInLibraryQuery() =
|
fun updateInLibraryQuery() =
|
||||||
"""
|
"""
|
||||||
|mutation UpdateManga(${'$'}listId: Int, ${'$'}progress: Int, ${'$'}status: MediaListStatus, ${'$'}score: Int) {
|
|mutation UpdateManga(${'$'}listId: Int, ${'$'}progress: Int, ${'$'}status: MediaListStatus, ${'$'}score: Int, ${'$'}startedAt: FuzzyDateInput, ${'$'}completedAt: FuzzyDateInput) {
|
||||||
|SaveMediaListEntry (id: ${'$'}listId, progress: ${'$'}progress, status: ${'$'}status, scoreRaw: ${'$'}score) {
|
|SaveMediaListEntry (id: ${'$'}listId, progress: ${'$'}progress, status: ${'$'}status, scoreRaw: ${'$'}score, startedAt: ${'$'}startedAt, completedAt: ${'$'}completedAt) {
|
||||||
|id
|
|id
|
||||||
|status
|
|status
|
||||||
|progress
|
|progress
|
||||||
@ -302,6 +327,16 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|
|||||||
|status
|
|status
|
||||||
|scoreRaw: score(format: POINT_100)
|
|scoreRaw: score(format: POINT_100)
|
||||||
|progress
|
|progress
|
||||||
|
|startedAt {
|
||||||
|
|year
|
||||||
|
|month
|
||||||
|
|day
|
||||||
|
|}
|
||||||
|
|completedAt {
|
||||||
|
|year
|
||||||
|
|month
|
||||||
|
|day
|
||||||
|
|}
|
||||||
|media {
|
|media {
|
||||||
|id
|
|id
|
||||||
|title {
|
|title {
|
||||||
|
@ -55,6 +55,8 @@ data class ALUserManga(
|
|||||||
val list_status: String,
|
val list_status: String,
|
||||||
val score_raw: Int,
|
val score_raw: Int,
|
||||||
val chapters_read: Int,
|
val chapters_read: Int,
|
||||||
|
val start_date_fuzzy: Long,
|
||||||
|
val completed_date_fuzzy: Long,
|
||||||
val manga: ALManga
|
val manga: ALManga
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@ -62,6 +64,8 @@ data class ALUserManga(
|
|||||||
media_id = manga.media_id
|
media_id = manga.media_id
|
||||||
status = toTrackStatus()
|
status = toTrackStatus()
|
||||||
score = score_raw.toFloat()
|
score = score_raw.toFloat()
|
||||||
|
started_reading_date = start_date_fuzzy
|
||||||
|
finished_reading_date = completed_date_fuzzy
|
||||||
last_chapter_read = chapters_read
|
last_chapter_read = chapters_read
|
||||||
library_id = this@ALUserManga.library_id
|
library_id = this@ALUserManga.library_id
|
||||||
total_chapters = manga.total_chapters
|
total_chapters = manga.total_chapters
|
||||||
|
Loading…
Reference in New Issue
Block a user