Browse Source

change Track.last_chapter_read to Float (#5802)

each TrackService can convert it to Int if decimal chapters are not supported
Gauthier 3 years ago
parent
commit
2cd8733212
22 changed files with 63 additions and 37 deletions
  1. 2 4
      app/src/main/java/eu/kanade/tachiyomi/data/backup/full/models/BackupTracking.kt
  2. 2 1
      app/src/main/java/eu/kanade/tachiyomi/data/backup/legacy/serializer/TrackTypeSerializer.kt
  3. 7 1
      app/src/main/java/eu/kanade/tachiyomi/data/database/DbOpenCallback.kt
  4. 1 1
      app/src/main/java/eu/kanade/tachiyomi/data/database/mappers/TrackTypeMapping.kt
  5. 1 1
      app/src/main/java/eu/kanade/tachiyomi/data/database/models/Track.kt
  6. 1 1
      app/src/main/java/eu/kanade/tachiyomi/data/database/models/TrackImpl.kt
  7. 16 1
      app/src/main/java/eu/kanade/tachiyomi/data/database/tables/TrackTable.kt
  8. 2 2
      app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/AnilistApi.kt
  9. 1 1
      app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/AnilistModels.kt
  10. 2 2
      app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiApi.kt
  11. 2 2
      app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/KitsuApi.kt
  12. 1 1
      app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/KitsuModels.kt
  13. 2 2
      app/src/main/java/eu/kanade/tachiyomi/data/track/komga/KomgaApi.kt
  14. 1 1
      app/src/main/java/eu/kanade/tachiyomi/data/track/model/TrackSearch.kt
  15. 3 2
      app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeListApi.kt
  16. 3 2
      app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriApi.kt
  17. 4 4
      app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt
  18. 1 1
      app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/SetTrackChaptersDialog.kt
  19. 1 1
      app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackHolder.kt
  20. 1 1
      app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt
  21. 5 1
      app/src/main/java/eu/kanade/tachiyomi/util/chapter/ChapterTrackSync.kt
  22. 4 4
      app/src/test/java/eu/kanade/tachiyomi/data/backup/BackupTest.kt

+ 2 - 4
app/src/main/java/eu/kanade/tachiyomi/data/backup/full/models/BackupTracking.kt

@@ -32,8 +32,7 @@ data class BackupTracking(
             media_id = [email protected]
             library_id = [email protected]
             title = [email protected]
-            // convert from float to int because of 1.x types
-            last_chapter_read = [email protected]()
+            last_chapter_read = [email protected]
             total_chapters = [email protected]
             score = [email protected]
             status = [email protected]
@@ -51,8 +50,7 @@ data class BackupTracking(
                 // forced not null so its compatible with 1.x backup system
                 libraryId = track.library_id!!,
                 title = track.title,
-                // convert to float for 1.x
-                lastChapterRead = track.last_chapter_read.toFloat(),
+                lastChapterRead = track.last_chapter_read,
                 totalChapters = track.total_chapters,
                 score = track.score,
                 status = track.status,

+ 2 - 1
app/src/main/java/eu/kanade/tachiyomi/data/backup/legacy/serializer/TrackTypeSerializer.kt

@@ -10,6 +10,7 @@ import kotlinx.serialization.encoding.Encoder
 import kotlinx.serialization.json.JsonDecoder
 import kotlinx.serialization.json.JsonEncoder
 import kotlinx.serialization.json.buildJsonObject
+import kotlinx.serialization.json.float
 import kotlinx.serialization.json.int
 import kotlinx.serialization.json.jsonObject
 import kotlinx.serialization.json.jsonPrimitive
@@ -46,7 +47,7 @@ open class TrackBaseSerializer<T : Track> : KSerializer<T> {
             sync_id = jsonObject[SYNC]!!.jsonPrimitive.int
             media_id = jsonObject[MEDIA]!!.jsonPrimitive.int
             library_id = jsonObject[LIBRARY]!!.jsonPrimitive.long
-            last_chapter_read = jsonObject[LAST_READ]!!.jsonPrimitive.int
+            last_chapter_read = jsonObject[LAST_READ]!!.jsonPrimitive.float
             tracking_url = jsonObject[TRACKING_URL]!!.jsonPrimitive.content
         } as T
     }

+ 7 - 1
app/src/main/java/eu/kanade/tachiyomi/data/database/DbOpenCallback.kt

@@ -20,7 +20,7 @@ class DbOpenCallback : SupportSQLiteOpenHelper.Callback(DATABASE_VERSION) {
         /**
          * Version of the database.
          */
-        const val DATABASE_VERSION = 12
+        const val DATABASE_VERSION = 13
     }
 
     override fun onCreate(db: SupportSQLiteDatabase) = with(db) {
@@ -85,6 +85,12 @@ class DbOpenCallback : SupportSQLiteOpenHelper.Callback(DATABASE_VERSION) {
         if (oldVersion < 12) {
             db.execSQL(MangaTable.addNextUpdateCol)
         }
+        if (oldVersion < 13) {
+            db.execSQL(TrackTable.renameTableToTemp)
+            db.execSQL(TrackTable.createTableQuery)
+            db.execSQL(TrackTable.insertFromTempTable)
+            db.execSQL(TrackTable.dropTempTable)
+        }
     }
 
     override fun onConfigure(db: SupportSQLiteDatabase) {

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/data/database/mappers/TrackTypeMapping.kt

@@ -71,7 +71,7 @@ class TrackGetResolver : DefaultGetResolver<Track>() {
         media_id = cursor.getInt(cursor.getColumnIndex(COL_MEDIA_ID))
         library_id = cursor.getLong(cursor.getColumnIndex(COL_LIBRARY_ID))
         title = cursor.getString(cursor.getColumnIndex(COL_TITLE))
-        last_chapter_read = cursor.getInt(cursor.getColumnIndex(COL_LAST_CHAPTER_READ))
+        last_chapter_read = cursor.getFloat(cursor.getColumnIndex(COL_LAST_CHAPTER_READ))
         total_chapters = cursor.getInt(cursor.getColumnIndex(COL_TOTAL_CHAPTERS))
         status = cursor.getInt(cursor.getColumnIndex(COL_STATUS))
         score = cursor.getFloat(cursor.getColumnIndex(COL_SCORE))

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/data/database/models/Track.kt

@@ -16,7 +16,7 @@ interface Track : Serializable {
 
     var title: String
 
-    var last_chapter_read: Int
+    var last_chapter_read: Float
 
     var total_chapters: Int
 

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/data/database/models/TrackImpl.kt

@@ -14,7 +14,7 @@ class TrackImpl : Track {
 
     override lateinit var title: String
 
-    override var last_chapter_read: Int = 0
+    override var last_chapter_read: Float = 0F
 
     override var total_chapters: Int = 0
 

+ 16 - 1
app/src/main/java/eu/kanade/tachiyomi/data/database/tables/TrackTable.kt

@@ -39,7 +39,7 @@ object TrackTable {
             $COL_MEDIA_ID INTEGER NOT NULL,
             $COL_LIBRARY_ID INTEGER,
             $COL_TITLE TEXT NOT NULL,
-            $COL_LAST_CHAPTER_READ INTEGER NOT NULL,
+            $COL_LAST_CHAPTER_READ REAL NOT NULL,
             $COL_TOTAL_CHAPTERS INTEGER NOT NULL,
             $COL_STATUS INTEGER NOT NULL,
             $COL_SCORE FLOAT NOT NULL,
@@ -62,4 +62,19 @@ object TrackTable {
 
     val addFinishDate: String
         get() = "ALTER TABLE $TABLE ADD COLUMN $COL_FINISH_DATE LONG NOT NULL DEFAULT 0"
+
+    val renameTableToTemp: String
+        get() =
+            "ALTER TABLE $TABLE RENAME TO ${TABLE}_tmp"
+
+    val insertFromTempTable: String
+        get() =
+            """
+            |INSERT INTO $TABLE($COL_ID,$COL_MANGA_ID,$COL_SYNC_ID,$COL_MEDIA_ID,$COL_LIBRARY_ID,$COL_TITLE,$COL_LAST_CHAPTER_READ,$COL_TOTAL_CHAPTERS,$COL_STATUS,$COL_SCORE,$COL_TRACKING_URL,$COL_START_DATE,$COL_FINISH_DATE)
+            |SELECT $COL_ID,$COL_MANGA_ID,$COL_SYNC_ID,$COL_MEDIA_ID,$COL_LIBRARY_ID,$COL_TITLE,$COL_LAST_CHAPTER_READ,$COL_TOTAL_CHAPTERS,$COL_STATUS,$COL_SCORE,$COL_TRACKING_URL,$COL_START_DATE,$COL_FINISH_DATE
+            |FROM ${TABLE}_tmp
+        """.trimMargin()
+
+    val dropTempTable: String
+        get() = "DROP TABLE ${TABLE}_tmp"
 }

+ 2 - 2
app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/AnilistApi.kt

@@ -48,7 +48,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
                 put("query", query)
                 putJsonObject("variables") {
                     put("mangaId", track.media_id)
-                    put("progress", track.last_chapter_read)
+                    put("progress", track.last_chapter_read.toInt())
                     put("status", track.toAnilistStatus())
                 }
             }
@@ -89,7 +89,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
                 put("query", query)
                 putJsonObject("variables") {
                     put("listId", track.library_id)
-                    put("progress", track.last_chapter_read)
+                    put("progress", track.last_chapter_read.toInt())
                     put("status", track.toAnilistStatus())
                     put("score", track.score.toInt())
                     put("startedAt", createDate(track.started_reading_date))

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/AnilistModels.kt

@@ -56,7 +56,7 @@ data class ALUserManga(
         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.toFloat()
         library_id = [email protected]_id
         total_chapters = manga.total_chapters
     }

+ 2 - 2
app/src/main/java/eu/kanade/tachiyomi/data/track/bangumi/BangumiApi.kt

@@ -55,7 +55,7 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
 
             // chapter update
             val body = FormBody.Builder()
-                .add("watched_eps", track.last_chapter_read.toString())
+                .add("watched_eps", track.last_chapter_read.toInt().toString())
                 .build()
             authClient.newCall(
                 POST(
@@ -143,7 +143,7 @@ class BangumiApi(private val client: OkHttpClient, interceptor: BangumiIntercept
             } else {
                 json.decodeFromString<Collection>(responseBody).let {
                     track.status = it.status?.id!!
-                    track.last_chapter_read = it.ep_status!!
+                    track.last_chapter_read = it.ep_status!!.toFloat()
                     track.score = it.rating!!
                     track
                 }

+ 2 - 2
app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/KitsuApi.kt

@@ -36,7 +36,7 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
                     put("type", "libraryEntries")
                     putJsonObject("attributes") {
                         put("status", track.toKitsuStatus())
-                        put("progress", track.last_chapter_read)
+                        put("progress", track.last_chapter_read.toInt())
                     }
                     putJsonObject("relationships") {
                         putJsonObject("user") {
@@ -82,7 +82,7 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
                     put("id", track.media_id)
                     putJsonObject("attributes") {
                         put("status", track.toKitsuStatus())
-                        put("progress", track.last_chapter_read)
+                        put("progress", track.last_chapter_read.toInt())
                         put("ratingTwenty", track.toKitsuScore())
                         put("startedAt", KitsuDateHelper.convert(track.started_reading_date))
                         put("finishedAt", KitsuDateHelper.convert(track.finished_reading_date))

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/KitsuModels.kt

@@ -79,7 +79,7 @@ class KitsuLibManga(obj: JsonObject, manga: JsonObject) {
         finished_reading_date = KitsuDateHelper.parse(finishedAt)
         status = toTrackStatus()
         score = ratingTwenty?.let { it.toInt() / 2f } ?: 0f
-        last_chapter_read = progress
+        last_chapter_read = progress.toFloat()
     }
 
     private fun toTrackStatus() = when (status) {

+ 2 - 2
app/src/main/java/eu/kanade/tachiyomi/data/track/komga/KomgaApi.kt

@@ -51,7 +51,7 @@ class KomgaApi(private val client: OkHttpClient) {
                         progress.booksReadCount -> Komga.COMPLETED
                         else -> Komga.READING
                     }
-                    last_chapter_read = progress.lastReadContinuousIndex
+                    last_chapter_read = progress.lastReadContinuousIndex.toFloat()
                 }
             } catch (e: Exception) {
                 Timber.w(e, "Could not get item: $url")
@@ -60,7 +60,7 @@ class KomgaApi(private val client: OkHttpClient) {
         }
 
     suspend fun updateProgress(track: Track): Track {
-        val progress = ReadProgressUpdateDto(track.last_chapter_read)
+        val progress = ReadProgressUpdateDto(track.last_chapter_read.toInt())
         val payload = json.encodeToString(progress)
         client.newCall(
             Request.Builder()

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/data/track/model/TrackSearch.kt

@@ -16,7 +16,7 @@ class TrackSearch : Track {
 
     override lateinit var title: String
 
-    override var last_chapter_read: Int = 0
+    override var last_chapter_read: Float = 0F
 
     override var total_chapters: Int = 0
 

+ 3 - 2
app/src/main/java/eu/kanade/tachiyomi/data/track/myanimelist/MyAnimeListApi.kt

@@ -16,6 +16,7 @@ import kotlinx.coroutines.awaitAll
 import kotlinx.serialization.json.JsonObject
 import kotlinx.serialization.json.boolean
 import kotlinx.serialization.json.contentOrNull
+import kotlinx.serialization.json.float
 import kotlinx.serialization.json.int
 import kotlinx.serialization.json.jsonArray
 import kotlinx.serialization.json.jsonObject
@@ -117,7 +118,7 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
                 .add("status", track.toMyAnimeListStatus() ?: "reading")
                 .add("is_rereading", (track.status == MyAnimeList.REREADING).toString())
                 .add("score", track.score.toString())
-                .add("num_chapters_read", track.last_chapter_read.toString())
+                .add("num_chapters_read", track.last_chapter_read.toInt().toString())
             convertToIsoDate(track.started_reading_date)?.let {
                 formBodyBuilder.add("start_date", it)
             }
@@ -205,7 +206,7 @@ class MyAnimeListApi(private val client: OkHttpClient, interceptor: MyAnimeListI
         return track.apply {
             val isRereading = obj["is_rereading"]!!.jsonPrimitive.boolean
             status = if (isRereading) MyAnimeList.REREADING else getStatus(obj["status"]!!.jsonPrimitive.content)
-            last_chapter_read = obj["num_chapters_read"]!!.jsonPrimitive.int
+            last_chapter_read = obj["num_chapters_read"]!!.jsonPrimitive.float
             score = obj["score"]!!.jsonPrimitive.int.toFloat()
             obj["start_date"]?.let {
                 started_reading_date = parseDate(it.jsonPrimitive.content)

+ 3 - 2
app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriApi.kt

@@ -15,6 +15,7 @@ import kotlinx.serialization.json.JsonArray
 import kotlinx.serialization.json.JsonObject
 import kotlinx.serialization.json.buildJsonObject
 import kotlinx.serialization.json.contentOrNull
+import kotlinx.serialization.json.float
 import kotlinx.serialization.json.int
 import kotlinx.serialization.json.jsonObject
 import kotlinx.serialization.json.jsonPrimitive
@@ -35,7 +36,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
                     put("user_id", user_id)
                     put("target_id", track.media_id)
                     put("target_type", "Manga")
-                    put("chapters", track.last_chapter_read)
+                    put("chapters", track.last_chapter_read.toInt())
                     put("score", track.score.toInt())
                     put("status", track.toShikimoriStatus())
                 }
@@ -89,7 +90,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter
             title = mangas["name"]!!.jsonPrimitive.content
             media_id = obj["id"]!!.jsonPrimitive.int
             total_chapters = mangas["chapters"]!!.jsonPrimitive.int
-            last_chapter_read = obj["chapters"]!!.jsonPrimitive.int
+            last_chapter_read = obj["chapters"]!!.jsonPrimitive.float
             score = (obj["score"]!!.jsonPrimitive.int).toFloat()
             status = toTrackStatus(obj["status"]!!.jsonPrimitive.content)
             tracking_url = baseUrl + mangas["url"]!!.jsonPrimitive.content

+ 4 - 4
app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaPresenter.kt

@@ -878,7 +878,7 @@ class MangaPresenter(
         val track = item.track!!
         track.status = item.service.getStatusList()[index]
         if (track.status == item.service.getCompletionStatus() && track.total_chapters != 0) {
-            track.last_chapter_read = track.total_chapters
+            track.last_chapter_read = track.total_chapters.toFloat()
         }
         updateRemote(track, item.service)
     }
@@ -891,11 +891,11 @@ class MangaPresenter(
 
     fun setTrackerLastChapterRead(item: TrackItem, chapterNumber: Int) {
         val track = item.track!!
-        if (track.last_chapter_read == 0 && track.last_chapter_read < chapterNumber && track.status != item.service.getRereadingStatus()) {
+        if (track.last_chapter_read == 0F && track.last_chapter_read < chapterNumber && track.status != item.service.getRereadingStatus()) {
             track.status = item.service.getReadingStatus()
         }
-        track.last_chapter_read = chapterNumber
-        if (track.total_chapters != 0 && track.last_chapter_read == track.total_chapters) {
+        track.last_chapter_read = chapterNumber.toFloat()
+        if (track.total_chapters != 0 && track.last_chapter_read.toInt() == track.total_chapters) {
             track.status = item.service.getCompletionStatus()
         }
         updateRemote(track, item.service)

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/SetTrackChaptersDialog.kt

@@ -41,7 +41,7 @@ class SetTrackChaptersDialog<T> : DialogController
         val np = pickerView.chaptersPicker
 
         // Set initial value
-        np.value = item.track?.last_chapter_read ?: 0
+        np.value = item.track?.last_chapter_read?.toInt() ?: 0
 
         // Enforce maximum value if tracker has total number of chapters set
         if (item.track != null && item.track.total_chapters > 0) {

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/manga/track/TrackHolder.kt

@@ -55,7 +55,7 @@ class TrackHolder(private val binding: TrackItemBinding, adapter: TrackAdapter)
                 listener.onOpenInBrowserClick(bindingAdapterPosition)
             }
             binding.trackTitle.text = track.title
-            binding.trackChapters.text = track.last_chapter_read.toString()
+            binding.trackChapters.text = track.last_chapter_read.toInt().toString()
             if (track.total_chapters > 0) {
                 binding.trackChapters.text = "${binding.trackChapters.text} / ${track.total_chapters}"
             }

+ 1 - 1
app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderPresenter.kt

@@ -698,7 +698,7 @@ class ReaderPresenter(
         if (!preferences.autoUpdateTrack()) return
         val manga = manga ?: return
 
-        val chapterRead = readerChapter.chapter.chapter_number.toInt()
+        val chapterRead = readerChapter.chapter.chapter_number
 
         val trackManager = Injekt.get<TrackManager>()
 

+ 5 - 1
app/src/main/java/eu/kanade/tachiyomi/util/chapter/ChapterTrackSync.kt

@@ -22,6 +22,10 @@ fun syncChaptersWithTrackServiceTwoWay(db: DatabaseHelper, chapters: List<Chapte
         .forEach { it.read = true }
     db.updateChaptersProgress(sortedChapters).executeAsBlocking()
 
+    // this uses the ordinal index of chapters instead of the chapter_number
+    // it was done that way because Track.last_chapter_read was an Int at the time, and Komga
+    // could have Float for the chapter number
+    // this will be addressed later on
     val localLastRead = when {
         sortedChapters.all { it.read } -> sortedChapters.size
         sortedChapters.any { !it.read } -> sortedChapters.indexOfFirst { !it.read }
@@ -29,7 +33,7 @@ fun syncChaptersWithTrackServiceTwoWay(db: DatabaseHelper, chapters: List<Chapte
     }
 
     // update remote
-    remoteTrack.last_chapter_read = localLastRead
+    remoteTrack.last_chapter_read = localLastRead.toFloat()
 
     launchIO {
         try {

+ 4 - 4
app/src/test/java/eu/kanade/tachiyomi/data/backup/BackupTest.kt

@@ -284,16 +284,16 @@ class BackupTest {
         // Create track and add it to database
         // This tests duplicate errors.
         val track = getSingleTrack(manga)
-        track.last_chapter_read = 5
+        track.last_chapter_read = 5F
         legacyBackupManager.databaseHelper.insertTrack(track).executeAsBlocking()
         var trackDB = legacyBackupManager.databaseHelper.getTracks(manga).executeAsBlocking()
         assertThat(trackDB).hasSize(1)
         assertThat(trackDB[0].last_chapter_read).isEqualTo(5)
-        track.last_chapter_read = 7
+        track.last_chapter_read = 7F
 
         // Create track for different manga to test track not in database
         val track2 = getSingleTrack(manga2)
-        track2.last_chapter_read = 10
+        track2.last_chapter_read = 10F
 
         // Check parser and restore already in database
         var trackList = listOf(track)
@@ -308,7 +308,7 @@ class BackupTest {
         assertThat(trackDB[0].last_chapter_read).isEqualTo(7)
 
         // Check parser and restore already in database with lower chapter_read
-        track.last_chapter_read = 5
+        track.last_chapter_read = 5F
         trackList = listOf(track)
         legacyBackupManager.restoreTrackForManga(manga, trackList)