Added Start/Finished Date Support to AniList

This commit is contained in:
Jays2Kings 2021-03-22 01:07:23 -04:00
parent 707dfd8c0a
commit 1e3de8a67f
3 changed files with 62 additions and 21 deletions

View File

@ -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 {

View File

@ -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 {

View File

@ -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