Add support to update strategy on global update (#7902)

* Add support to update strategy.

* Add JavaDoc and bump the LIB_VERSION_MAX constant.

* Fix a word typo.

* Store update strategy enum as integer in the DB.

(cherry picked from commit ba533f30ce)

# Conflicts:
#	app/src/main/java/eu/kanade/data/DatabaseAdapter.kt
#	app/src/main/java/eu/kanade/data/manga/MangaMapper.kt
#	app/src/main/java/eu/kanade/data/manga/MangaRepositoryImpl.kt
#	app/src/main/java/eu/kanade/tachiyomi/AppModule.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/BackupManager.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/backup/models/BackupManga.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/database/models/MangaImpl.kt
#	app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt
#	app/src/main/sqldelight/data/mangas.sq
#	app/src/main/sqldelight/migrations/20.sqm
This commit is contained in:
Alessandro Jean
2022-09-25 11:12:36 -03:00
committed by Jobobby04
parent 3da5a2a20d
commit 2d2ee54c99
20 changed files with 103 additions and 15 deletions
@@ -1,6 +1,7 @@
package eu.kanade.data
import com.squareup.sqldelight.ColumnAdapter
import eu.kanade.tachiyomi.source.model.UpdateStrategy
import java.util.Date
val dateAdapter = object : ColumnAdapter<Date, Long> {
@@ -19,6 +20,15 @@ val listOfStringsAdapter = object : ColumnAdapter<List<String>, String> {
override fun encode(value: List<String>) = value.joinToString(separator = listOfStringsSeparator)
}
val updateStrategyAdapter = object : ColumnAdapter<UpdateStrategy, Long> {
private val enumValues by lazy { UpdateStrategy.values() }
override fun decode(databaseValue: Long): UpdateStrategy =
enumValues.getOrElse(databaseValue.toInt()) { UpdateStrategy.ALWAYS_UPDATE }
override fun encode(value: UpdateStrategy): Long = value.ordinal.toLong()
}
// SY -->
private const val listOfStringsAndSeparator = " & "
val listOfStringsAndAdapter = object : ColumnAdapter<List<String>, String> {
@@ -4,6 +4,7 @@ import com.squareup.sqldelight.Query
import com.squareup.sqldelight.db.SqlCursor
import com.squareup.sqldelight.db.SqlDriver
import com.squareup.sqldelight.internal.copyOnWriteList
import eu.kanade.data.updateStrategyAdapter
import eu.kanade.tachiyomi.data.database.models.LibraryManga
import exh.source.MERGED_SOURCE_ID
@@ -27,9 +28,10 @@ private val mapper = { cursor: SqlCursor ->
cover_last_modified = cursor.getLong(16)!!
date_added = cursor.getLong(17)!!
filtered_scanlators = cursor.getString(18)
unreadCount = cursor.getLong(19)!!.toInt()
readCount = cursor.getLong(20)!!.toInt()
category = cursor.getLong(21)!!.toInt()
update_strategy = updateStrategyAdapter.decode(cursor.getLong(19)!!)
unreadCount = cursor.getLong(20)!!.toInt()
readCount = cursor.getLong(21)!!.toInt()
category = cursor.getLong(22)!!.toInt()
}
}
@@ -4,9 +4,10 @@ import eu.kanade.data.listOfStringsAndAdapter
import eu.kanade.domain.chapter.model.Chapter
import eu.kanade.domain.manga.model.Manga
import eu.kanade.tachiyomi.data.database.models.LibraryManga
import eu.kanade.tachiyomi.source.model.UpdateStrategy
val mangaMapper: (Long, Long, String, String?, String?, String?, List<String>?, String, Long, String?, Boolean, Long?, Long?, Boolean, Long, Long, Long, Long, List<String>?) -> Manga =
{ id, source, url, artist, author, description, genre, title, status, thumbnailUrl, favorite, lastUpdate, _, initialized, viewer, chapterFlags, coverLastModified, dateAdded, filteredScanlators ->
val mangaMapper: (Long, Long, String, String?, String?, String?, List<String>?, String, Long, String?, Boolean, Long?, Long?, Boolean, Long, Long, Long, Long, List<String>?, UpdateStrategy) -> Manga =
{ id, source, url, artist, author, description, genre, title, status, thumbnailUrl, favorite, lastUpdate, _, initialized, viewer, chapterFlags, coverLastModified, dateAdded, filteredScanlators, updateStrategy ->
Manga(
id = id,
source = source,
@@ -26,6 +27,7 @@ val mangaMapper: (Long, Long, String, String?, String?, String?, List<String>?,
ogStatus = status,
// SY <--
thumbnailUrl = thumbnailUrl,
updateStrategy = updateStrategy,
initialized = initialized,
// SY -->
filteredScanlators = filteredScanlators,
@@ -33,8 +35,8 @@ val mangaMapper: (Long, Long, String, String?, String?, String?, List<String>?,
)
}
val mangaChapterMapper: (Long, Long, String, String?, String?, String?, List<String>?, String, Long, String?, Boolean, Long?, Long?, Boolean, Long, Long, Long, Long, List<String>?, Long, Long, String, String, String?, Boolean, Boolean, Long, Float, Long, Long, Long) -> Pair<Manga, Chapter> =
{ _id, source, url, artist, author, description, genre, title, status, thumbnailUrl, favorite, lastUpdate, next_update, initialized, viewerFlags, chapterFlags, coverLastModified, dateAdded, filteredScanlators, chapterId, mangaId, chapterUrl, name, scanlator, read, bookmark, lastPageRead, chapterNumber, sourceOrder, dateFetch, dateUpload ->
val mangaChapterMapper: (Long, Long, String, String?, String?, String?, List<String>?, String, Long, String?, Boolean, Long?, Long?, Boolean, Long, Long, Long, Long, UpdateStrategy, List<String>?, Long, Long, String, String, String?, Boolean, Boolean, Long, Float, Long, Long, Long) -> Pair<Manga, Chapter> =
{ _id, source, url, artist, author, description, genre, title, status, thumbnailUrl, favorite, lastUpdate, next_update, initialized, viewerFlags, chapterFlags, coverLastModified, dateAdded, updateStrategy, filteredScanlators, chapterId, mangaId, chapterUrl, name, scanlator, read, bookmark, lastPageRead, chapterNumber, sourceOrder, dateFetch, dateUpload ->
Manga(
id = _id,
source = source,
@@ -54,6 +56,7 @@ val mangaChapterMapper: (Long, Long, String, String?, String?, String?, List<Str
ogStatus = status,
// SY <--
thumbnailUrl = thumbnailUrl,
updateStrategy = updateStrategy,
initialized = initialized,
// SY -->
filteredScanlators = filteredScanlators,
@@ -74,8 +77,8 @@ val mangaChapterMapper: (Long, Long, String, String?, String?, String?, List<Str
)
}
val libraryManga: (Long, Long, String, String?, String?, String?, List<String>?, String, Long, String?, Boolean, Long?, Long?, Boolean, Long, Long, Long, Long, List<String>?, Long, Long, Long) -> LibraryManga =
{ _id, source, url, artist, author, description, genre, title, status, thumbnail_url, favorite, last_update, next_update, initialized, viewer, chapter_flags, cover_last_modified, date_added, filtered_scanlators, unread_count, read_count, category ->
val libraryManga: (Long, Long, String, String?, String?, String?, List<String>?, String, Long, String?, Boolean, Long?, Long?, Boolean, Long, Long, Long, Long, UpdateStrategy, List<String>?, Long, Long, Long) -> LibraryManga =
{ _id, source, url, artist, author, description, genre, title, status, thumbnail_url, favorite, last_update, next_update, initialized, viewer, chapter_flags, cover_last_modified, date_added, update_strategy, filtered_scanlators, unread_count, read_count, category ->
LibraryManga().apply {
this.id = _id
this.source = source
@@ -89,6 +92,7 @@ val libraryManga: (Long, Long, String, String?, String?, String?, List<String>?,
this.thumbnail_url = thumbnail_url
this.favorite = favorite
this.last_update = last_update ?: 0
this.update_strategy = update_strategy
this.initialized = initialized
this.viewer_flags = viewer.toInt()
this.chapter_flags = chapter_flags.toInt()
@@ -4,6 +4,7 @@ import eu.kanade.data.AndroidDatabaseHandler
import eu.kanade.data.DatabaseHandler
import eu.kanade.data.listOfStringsAdapter
import eu.kanade.data.listOfStringsAndAdapter
import eu.kanade.data.updateStrategyAdapter
import eu.kanade.domain.manga.model.Manga
import eu.kanade.domain.manga.model.MangaUpdate
import eu.kanade.domain.manga.repository.MangaRepository
@@ -96,6 +97,10 @@ class MangaRepositoryImpl(
chapterFlags = manga.chapterFlags,
coverLastModified = manga.coverLastModified,
dateAdded = manga.dateAdded,
// SY -->
filteredScanlators = manga.filteredScanlators,
// SY <--
updateStrategy = manga.updateStrategy,
)
mangasQueries.selectLastInsertedRowId()
}
@@ -141,8 +146,11 @@ class MangaRepositoryImpl(
chapterFlags = value.chapterFlags,
coverLastModified = value.coverLastModified,
dateAdded = value.dateAdded,
// SY -->
filteredScanlators = value.filteredScanlators?.let(listOfStringsAndAdapter::encode),
// SY <--
mangaId = value.id,
updateStrategy = value.updateStrategy?.let(updateStrategyAdapter::encode),
)
}
}
@@ -78,6 +78,7 @@ class UpdateManga(
genre = remoteManga.getGenres(),
thumbnailUrl = thumbnailUrl,
status = remoteManga.status.toLong(),
updateStrategy = remoteManga.update_strategy,
initialized = true,
),
)
@@ -8,6 +8,7 @@ import eu.kanade.tachiyomi.data.database.models.MangaImpl
import eu.kanade.tachiyomi.data.library.CustomMangaManager
import eu.kanade.tachiyomi.source.LocalSource
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.model.UpdateStrategy
import eu.kanade.tachiyomi.widget.ExtendedNavigationView
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
@@ -34,6 +35,7 @@ data class Manga(
val ogStatus: Long,
// SY <--
val thumbnailUrl: String?,
val updateStrategy: UpdateStrategy,
val initialized: Boolean,
// SY -->
val filteredScanlators: List<String>?,
@@ -183,6 +185,7 @@ data class Manga(
ogStatus = 0L,
// SY <--
thumbnailUrl = null,
updateStrategy = UpdateStrategy.ALWAYS_UPDATE,
initialized = false,
// SY -->
filteredScanlators = null,
@@ -229,6 +232,7 @@ fun Manga.toDbManga(): DbManga = MangaImpl().also {
it.status = ogStatus.toInt()
// SY <--
it.thumbnail_url = thumbnailUrl
it.update_strategy = updateStrategy
it.initialized = initialized
// SY -->
it.filtered_scanlators = filteredScanlators?.let(listOfStringsAndAdapter::encode)
@@ -255,6 +259,7 @@ fun Manga.toMangaUpdate(): MangaUpdate {
status = ogStatus,
// SY <--
thumbnailUrl = thumbnailUrl,
updateStrategy = updateStrategy,
initialized = initialized,
// SY -->
filteredScanlators = filteredScanlators,
@@ -1,5 +1,7 @@
package eu.kanade.domain.manga.model
import eu.kanade.tachiyomi.source.model.UpdateStrategy
data class MangaUpdate(
val id: Long,
val source: Long? = null,
@@ -17,6 +19,7 @@ data class MangaUpdate(
val genre: List<String>? = null,
val status: Long? = null,
val thumbnailUrl: String? = null,
val updateStrategy: UpdateStrategy? = null,
val initialized: Boolean? = null,
// SY -->
val filteredScanlators: List<String>? = null,
@@ -16,6 +16,7 @@ import eu.kanade.data.dateAdapter
import eu.kanade.data.listOfLongsAdapter
import eu.kanade.data.listOfStringsAdapter
import eu.kanade.data.listOfStringsAndAdapter
import eu.kanade.data.updateStrategyAdapter
import eu.kanade.domain.UnsortedPreferences
import eu.kanade.domain.backup.service.BackupPreferences
import eu.kanade.domain.base.BasePreferences
@@ -95,6 +96,7 @@ class AppModule(val app: Application) : InjektModule {
),
mangasAdapter = Mangas.Adapter(
genreAdapter = listOfStringsAdapter,
update_strategyAdapter = updateStrategyAdapter,
// SY -->
filtered_scanlatorsAdapter = listOfStringsAndAdapter,
// SY <--
@@ -8,7 +8,9 @@ import data.Manga_sync
import data.Mangas
import eu.kanade.data.DatabaseHandler
import eu.kanade.data.exh.mergedMangaReferenceMapper
import eu.kanade.data.listOfStringsAndAdapter
import eu.kanade.data.manga.mangaMapper
import eu.kanade.data.updateStrategyAdapter
import eu.kanade.domain.backup.service.BackupPreferences
import eu.kanade.domain.category.interactor.GetCategories
import eu.kanade.domain.category.model.Category
@@ -564,6 +566,10 @@ class BackupManager(
chapterFlags = manga.chapter_flags.toLong(),
coverLastModified = manga.cover_last_modified,
dateAdded = manga.date_added,
// SY -->
filteredScanlators = manga.filtered_scanlators?.nullIfBlank()?.let(listOfStringsAndAdapter::decode),
// SY <--
updateStrategy = manga.update_strategy,
)
mangasQueries.selectLastInsertedRowId()
}
@@ -588,10 +594,11 @@ class BackupManager(
chapterFlags = manga.chapter_flags.toLong(),
coverLastModified = manga.cover_last_modified,
dateAdded = manga.date_added,
mangaId = manga.id!!,
// SY -->
filteredScanlators = manga.filtered_scanlators,
// SY <--
mangaId = manga.id!!,
updateStrategy = manga.update_strategy.let(updateStrategyAdapter::encode),
)
}
return manga.id!!
@@ -6,6 +6,7 @@ import eu.kanade.tachiyomi.data.database.models.ChapterImpl
import eu.kanade.tachiyomi.data.database.models.MangaImpl
import eu.kanade.tachiyomi.data.database.models.TrackImpl
import eu.kanade.tachiyomi.data.library.CustomMangaManager
import eu.kanade.tachiyomi.source.model.UpdateStrategy
import eu.kanade.tachiyomi.ui.reader.setting.ReadingModeType
import kotlinx.serialization.Serializable
import kotlinx.serialization.protobuf.ProtoNumber
@@ -40,6 +41,7 @@ data class BackupManga(
@ProtoNumber(102) var brokenHistory: List<BrokenBackupHistory> = emptyList(),
@ProtoNumber(103) var viewer_flags: Int? = null,
@ProtoNumber(104) var history: List<BackupHistory> = emptyList(),
@ProtoNumber(105) var updateStrategy: UpdateStrategy = UpdateStrategy.ALWAYS_UPDATE,
// SY specific values
@ProtoNumber(600) var mergedMangaReferences: List<BackupMergedMangaReference> = emptyList(),
@@ -72,6 +74,7 @@ data class BackupManga(
date_added = this@BackupManga.dateAdded
viewer_flags = this@BackupManga.viewer_flags ?: this@BackupManga.viewer
chapter_flags = this@BackupManga.chapterFlags
update_strategy = this@BackupManga.updateStrategy
filtered_scanlators = this@BackupManga.filtered_scanlators
}
}
@@ -130,6 +133,7 @@ data class BackupManga(
viewer = (manga.viewerFlags.toInt() and ReadingModeType.MASK),
viewer_flags = manga.viewerFlags.toInt(),
chapterFlags = manga.chapterFlags.toInt(),
updateStrategy = manga.updateStrategy,
// SY -->
filtered_scanlators = manga.filteredScanlators?.let(listOfStringsAndAdapter::encode),
).also { backupManga ->
@@ -105,6 +105,7 @@ fun Manga.toDomainManga(): DomainManga? {
ogStatus = originalStatus.toLong(),
// SY <--
thumbnailUrl = thumbnail_url,
updateStrategy = update_strategy,
initialized = initialized,
// SY -->
filteredScanlators = filtered_scanlators?.let(listOfStringsAndAdapter::decode)?.nullIfEmpty(),
@@ -3,6 +3,7 @@ package eu.kanade.tachiyomi.data.database.models
import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.data.library.CustomMangaManager
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.model.UpdateStrategy
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import uy.kohesive.injekt.injectLazy
@@ -58,6 +59,8 @@ open class MangaImpl : Manga {
override var date_added: Long = 0
override var update_strategy: UpdateStrategy = UpdateStrategy.ALWAYS_UPDATE
override var initialized: Boolean = false
override var viewer_flags: Int = 0
@@ -52,6 +52,7 @@ import eu.kanade.tachiyomi.data.track.TrackStatus
import eu.kanade.tachiyomi.source.SourceManager
import eu.kanade.tachiyomi.source.UnmeteredSource
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.model.UpdateStrategy
import eu.kanade.tachiyomi.source.online.all.MergedSource
import eu.kanade.tachiyomi.ui.manga.track.TrackItem
import eu.kanade.tachiyomi.util.lang.withIOContext
@@ -435,6 +436,9 @@ class LibraryUpdateService(
MANGA_NON_READ in restrictions && mangaWithNotif.totalChapters > 0 && !mangaWithNotif.hasStarted ->
skippedUpdates.add(mangaWithNotif to getString(R.string.skipped_reason_not_started))
mangaWithNotif.update_strategy != UpdateStrategy.ALWAYS_UPDATE ->
skippedUpdates.add(mangaWithNotif to getString(R.string.skipped_reason_not_always_update))
else -> {
// Convert to the manga that contains new chapters
mangaWithNotif.toDomainManga()?.let { domainManga ->
@@ -38,7 +38,7 @@ internal object ExtensionLoader {
private const val METADATA_HAS_README = "tachiyomi.extension.hasReadme"
private const val METADATA_HAS_CHANGELOG = "tachiyomi.extension.hasChangelog"
const val LIB_VERSION_MIN = 1.2
const val LIB_VERSION_MAX = 1.3
const val LIB_VERSION_MAX = 1.4
private const val PACKAGE_FLAGS = PackageManager.GET_CONFIGURATIONS or PackageManager.GET_SIGNATURES