Delayed Tracking Update related fix (#8642)

* Delayed Tracking Update related fix

* Lint
This commit is contained in:
AntsyLich 2022-12-02 10:01:24 +06:00 committed by GitHub
parent 3a8b5e1b5e
commit ba91b483a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
11 changed files with 88 additions and 65 deletions

View File

@ -27,7 +27,7 @@ android {
applicationId = "eu.kanade.tachiyomi" applicationId = "eu.kanade.tachiyomi"
minSdk = AndroidConfig.minSdk minSdk = AndroidConfig.minSdk
targetSdk = AndroidConfig.targetSdk targetSdk = AndroidConfig.targetSdk
versionCode = 91 versionCode = 92
versionName = "0.14.2" versionName = "0.14.2"
buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"") buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"")

View File

@ -9,6 +9,10 @@ class TrackRepositoryImpl(
private val handler: DatabaseHandler, private val handler: DatabaseHandler,
) : TrackRepository { ) : TrackRepository {
override suspend fun getTrackById(id: Long): Track? {
return handler.awaitOneOrNull { manga_syncQueries.getTrackById(id, trackMapper) }
}
override suspend fun getTracksByMangaId(mangaId: Long): List<Track> { override suspend fun getTracksByMangaId(mangaId: Long): List<Track> {
return handler.awaitList { return handler.awaitList {
manga_syncQueries.getTracksByMangaId(mangaId, trackMapper) manga_syncQueries.getTracksByMangaId(mangaId, trackMapper)

View File

@ -10,6 +10,15 @@ class GetTracks(
private val trackRepository: TrackRepository, private val trackRepository: TrackRepository,
) { ) {
suspend fun awaitOne(id: Long): Track? {
return try {
trackRepository.getTrackById(id)
} catch (e: Exception) {
logcat(LogPriority.ERROR, e)
null
}
}
suspend fun await(mangaId: Long): List<Track> { suspend fun await(mangaId: Long): List<Track> {
return try { return try {
trackRepository.getTracksByMangaId(mangaId) trackRepository.getTracksByMangaId(mangaId)

View File

@ -5,6 +5,8 @@ import kotlinx.coroutines.flow.Flow
interface TrackRepository { interface TrackRepository {
suspend fun getTrackById(id: Long): Track?
suspend fun getTracksByMangaId(mangaId: Long): List<Track> suspend fun getTracksByMangaId(mangaId: Long): List<Track>
fun getTracksAsFlow(): Flow<List<Track>> fun getTracksAsFlow(): Flow<List<Track>>

View File

@ -1,4 +1,4 @@
package eu.kanade.tachiyomi.data.track.job package eu.kanade.domain.track.service
import android.content.Context import android.content.Context
import androidx.work.BackoffPolicy import androidx.work.BackoffPolicy
@ -9,10 +9,10 @@ import androidx.work.NetworkType
import androidx.work.OneTimeWorkRequestBuilder import androidx.work.OneTimeWorkRequestBuilder
import androidx.work.WorkManager import androidx.work.WorkManager
import androidx.work.WorkerParameters import androidx.work.WorkerParameters
import eu.kanade.domain.manga.interactor.GetManga
import eu.kanade.domain.track.interactor.GetTracks import eu.kanade.domain.track.interactor.GetTracks
import eu.kanade.domain.track.interactor.InsertTrack import eu.kanade.domain.track.interactor.InsertTrack
import eu.kanade.domain.track.model.toDbTrack import eu.kanade.domain.track.model.toDbTrack
import eu.kanade.domain.track.store.DelayedTrackingStore
import eu.kanade.tachiyomi.data.track.TrackManager import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.util.lang.withIOContext import eu.kanade.tachiyomi.util.lang.withIOContext
import eu.kanade.tachiyomi.util.system.logcat import eu.kanade.tachiyomi.util.system.logcat
@ -25,7 +25,6 @@ class DelayedTrackingUpdateJob(context: Context, workerParams: WorkerParameters)
CoroutineWorker(context, workerParams) { CoroutineWorker(context, workerParams) {
override suspend fun doWork(): Result { override suspend fun doWork(): Result {
val getManga = Injekt.get<GetManga>()
val getTracks = Injekt.get<GetTracks>() val getTracks = Injekt.get<GetTracks>()
val insertTrack = Injekt.get<InsertTrack>() val insertTrack = Injekt.get<InsertTrack>()
@ -34,10 +33,11 @@ class DelayedTrackingUpdateJob(context: Context, workerParams: WorkerParameters)
withIOContext { withIOContext {
val tracks = delayedTrackingStore.getItems().mapNotNull { val tracks = delayedTrackingStore.getItems().mapNotNull {
val manga = getManga.await(it.mangaId) ?: return@withIOContext val track = getTracks.awaitOne(it.trackId)
getTracks.await(manga.id) if (track == null) {
.find { track -> track.id == it.trackId } delayedTrackingStore.remove(it.trackId)
?.copy(lastChapterRead = it.lastChapterRead.toDouble()) }
track
} }
tracks.forEach { track -> tracks.forEach { track ->
@ -47,7 +47,7 @@ class DelayedTrackingUpdateJob(context: Context, workerParams: WorkerParameters)
service.update(track.toDbTrack(), true) service.update(track.toDbTrack(), true)
insertTrack.await(track) insertTrack.await(track)
} }
delayedTrackingStore.remove(track) delayedTrackingStore.remove(track.id)
} catch (e: Exception) { } catch (e: Exception) {
logcat(LogPriority.ERROR, e) logcat(LogPriority.ERROR, e)
} }

View File

@ -0,0 +1,46 @@
package eu.kanade.domain.track.store
import android.content.Context
import androidx.core.content.edit
import eu.kanade.domain.track.model.Track
import eu.kanade.tachiyomi.util.system.logcat
import logcat.LogPriority
class DelayedTrackingStore(context: Context) {
/**
* Preference file where queued tracking updates are stored.
*/
private val preferences = context.getSharedPreferences("tracking_queue", Context.MODE_PRIVATE)
fun addItem(track: Track) {
val trackId = track.id.toString()
val lastChapterRead = preferences.getFloat(trackId, 0f)
if (track.lastChapterRead > lastChapterRead) {
logcat(LogPriority.DEBUG) { "Queuing track item: $trackId, last chapter read: ${track.lastChapterRead}" }
preferences.edit {
putFloat(trackId, track.lastChapterRead.toFloat())
}
}
}
fun remove(trackId: Long) {
preferences.edit {
remove(trackId.toString())
}
}
fun getItems(): List<DelayedTrackingItem> {
return preferences.all.mapNotNull {
DelayedTrackingItem(
trackId = it.key.toLong(),
lastChapterRead = it.value.toString().toFloat(),
)
}
}
data class DelayedTrackingItem(
val trackId: Long,
val lastChapterRead: Float,
)
}

View File

@ -20,6 +20,7 @@ import eu.kanade.domain.download.service.DownloadPreferences
import eu.kanade.domain.library.service.LibraryPreferences import eu.kanade.domain.library.service.LibraryPreferences
import eu.kanade.domain.source.service.SourcePreferences import eu.kanade.domain.source.service.SourcePreferences
import eu.kanade.domain.track.service.TrackPreferences import eu.kanade.domain.track.service.TrackPreferences
import eu.kanade.domain.track.store.DelayedTrackingStore
import eu.kanade.domain.ui.UiPreferences import eu.kanade.domain.ui.UiPreferences
import eu.kanade.tachiyomi.core.preference.AndroidPreferenceStore import eu.kanade.tachiyomi.core.preference.AndroidPreferenceStore
import eu.kanade.tachiyomi.core.preference.PreferenceStore import eu.kanade.tachiyomi.core.preference.PreferenceStore
@ -33,7 +34,6 @@ import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.data.download.DownloadProvider import eu.kanade.tachiyomi.data.download.DownloadProvider
import eu.kanade.tachiyomi.data.saver.ImageSaver import eu.kanade.tachiyomi.data.saver.ImageSaver
import eu.kanade.tachiyomi.data.track.TrackManager import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.data.track.job.DelayedTrackingStore
import eu.kanade.tachiyomi.extension.ExtensionManager import eu.kanade.tachiyomi.extension.ExtensionManager
import eu.kanade.tachiyomi.network.JavaScriptEngine import eu.kanade.tachiyomi.network.JavaScriptEngine
import eu.kanade.tachiyomi.network.NetworkHelper import eu.kanade.tachiyomi.network.NetworkHelper

View File

@ -36,7 +36,6 @@ object Migrations {
/** /**
* Performs a migration when the application is updated. * Performs a migration when the application is updated.
* *
* @param preferences Preferences of the application.
* @return true if a migration is performed, false otherwise. * @return true if a migration is performed, false otherwise.
*/ */
fun upgrade( fun upgrade(
@ -339,6 +338,16 @@ object Migrations {
} }
} }
} }
if (oldVersion < 92) {
val trackingQueuePref = context.getSharedPreferences("tracking_queue", Context.MODE_PRIVATE)
trackingQueuePref.all.forEach {
val (_, lastChapterRead) = it.value.toString().split(":")
trackingQueuePref.edit {
remove(it.key)
putFloat(it.key, lastChapterRead.toFloat())
}
}
}
return true return true
} }

View File

@ -1,52 +0,0 @@
package eu.kanade.tachiyomi.data.track.job
import android.content.Context
import androidx.core.content.edit
import eu.kanade.domain.track.model.Track
import eu.kanade.tachiyomi.util.system.logcat
import logcat.LogPriority
class DelayedTrackingStore(context: Context) {
/**
* Preference file where queued tracking updates are stored.
*/
private val preferences = context.getSharedPreferences("tracking_queue", Context.MODE_PRIVATE)
fun addItem(track: Track) {
val trackId = track.id.toString()
val (_, lastChapterRead) = preferences.getString(trackId, "0:0.0")!!.split(":")
if (track.lastChapterRead > lastChapterRead.toFloat()) {
val value = "${track.mangaId}:${track.lastChapterRead}"
logcat(LogPriority.DEBUG) { "Queuing track item: $trackId, $value" }
preferences.edit {
putString(trackId, value)
}
}
}
fun remove(track: Track) {
preferences.edit {
remove(track.id.toString())
}
}
@Suppress("UNCHECKED_CAST")
fun getItems(): List<DelayedTrackingItem> {
return (preferences.all as Map<String, String>).entries
.map {
val (mangaId, lastChapterRead) = it.value.split(":")
DelayedTrackingItem(
trackId = it.key.toLong(),
mangaId = mangaId.toLong(),
lastChapterRead = lastChapterRead.toFloat(),
)
}
}
data class DelayedTrackingItem(
val trackId: Long,
val mangaId: Long,
val lastChapterRead: Float,
)
}

View File

@ -21,7 +21,9 @@ import eu.kanade.domain.manga.model.toDbManga
import eu.kanade.domain.track.interactor.GetTracks import eu.kanade.domain.track.interactor.GetTracks
import eu.kanade.domain.track.interactor.InsertTrack import eu.kanade.domain.track.interactor.InsertTrack
import eu.kanade.domain.track.model.toDbTrack import eu.kanade.domain.track.model.toDbTrack
import eu.kanade.domain.track.service.DelayedTrackingUpdateJob
import eu.kanade.domain.track.service.TrackPreferences import eu.kanade.domain.track.service.TrackPreferences
import eu.kanade.domain.track.store.DelayedTrackingStore
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.database.models.toDomainChapter import eu.kanade.tachiyomi.data.database.models.toDomainChapter
import eu.kanade.tachiyomi.data.database.models.toDomainManga import eu.kanade.tachiyomi.data.database.models.toDomainManga
@ -32,8 +34,6 @@ import eu.kanade.tachiyomi.data.saver.Image
import eu.kanade.tachiyomi.data.saver.ImageSaver import eu.kanade.tachiyomi.data.saver.ImageSaver
import eu.kanade.tachiyomi.data.saver.Location import eu.kanade.tachiyomi.data.saver.Location
import eu.kanade.tachiyomi.data.track.TrackManager import eu.kanade.tachiyomi.data.track.TrackManager
import eu.kanade.tachiyomi.data.track.job.DelayedTrackingStore
import eu.kanade.tachiyomi.data.track.job.DelayedTrackingUpdateJob
import eu.kanade.tachiyomi.source.SourceManager import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.model.Page import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource

View File

@ -25,6 +25,11 @@ getTracks:
SELECT * SELECT *
FROM manga_sync; FROM manga_sync;
getTrackById:
SELECT *
FROM manga_sync
WHERE _id = :id;
getTracksByMangaId: getTracksByMangaId:
SELECT * SELECT *
FROM manga_sync FROM manga_sync