change Track.last_chapter_read to Float (#5802)

each TrackService can convert it to Int if decimal chapters are not supported
This commit is contained in:
Gauthier 2021-08-28 22:37:45 +08:00 committed by GitHub
parent 4b2a9bc621
commit 2cd8733212
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
22 changed files with 63 additions and 37 deletions

View file

@ -32,8 +32,7 @@ data class BackupTracking(
media_id = this@BackupTracking.mediaId
library_id = this@BackupTracking.libraryId
title = this@BackupTracking.title
// convert from float to int because of 1.x types
last_chapter_read = this@BackupTracking.lastChapterRead.toInt()
last_chapter_read = this@BackupTracking.lastChapterRead
total_chapters = this@BackupTracking.totalChapters
score = this@BackupTracking.score
status = this@BackupTracking.status
@ -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,

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -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 = this@ALUserManga.library_id
total_chapters = manga.total_chapters
}

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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