mirror of
https://github.com/null2264/yokai.git
synced 2025-06-21 10:44:42 +00:00
Add support to update strategy on global update
+ Requests: add `GET(HttpUrl)` overload Starting line for Extensions on 1.5
This commit is contained in:
parent
f411eafef9
commit
34869c20bb
12 changed files with 124 additions and 14 deletions
|
@ -5,6 +5,7 @@ import eu.kanade.tachiyomi.data.database.models.Manga
|
|||
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 kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
|
||||
|
@ -38,6 +39,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(602) var customStatus: Int = 0,
|
||||
|
@ -69,6 +71,7 @@ data class BackupManga(
|
|||
).takeIf { it != 0 }
|
||||
?: -1
|
||||
chapter_flags = this@BackupManga.chapterFlags
|
||||
update_strategy = this@BackupManga.updateStrategy
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,6 +125,7 @@ data class BackupManga(
|
|||
viewer = manga.readingModeType,
|
||||
viewer_flags = manga.viewer_flags.takeIf { it != -1 } ?: 0,
|
||||
chapterFlags = manga.chapter_flags,
|
||||
updateStrategy = manga.update_strategy,
|
||||
).also { backupManga ->
|
||||
customMangaManager?.getManga(manga)?.let {
|
||||
backupManga.customTitle = it.title
|
||||
|
|
|
@ -0,0 +1,41 @@
|
|||
package eu.kanade.tachiyomi.data.database
|
||||
|
||||
import eu.kanade.tachiyomi.source.model.UpdateStrategy
|
||||
import java.util.Date
|
||||
|
||||
val dateAdapter = object : ColumnAdapter<Date, Long> {
|
||||
override fun decode(databaseValue: Long): Date = Date(databaseValue)
|
||||
override fun encode(value: Date): Long = value.time
|
||||
}
|
||||
|
||||
private const val listOfStringsSeparator = ", "
|
||||
val listOfStringsAdapter = object : ColumnAdapter<List<String>, String> {
|
||||
override fun decode(databaseValue: String) =
|
||||
if (databaseValue.isEmpty()) {
|
||||
emptyList()
|
||||
} else {
|
||||
databaseValue.split(listOfStringsSeparator)
|
||||
}
|
||||
override fun encode(value: List<String>) = value.joinToString(separator = listOfStringsSeparator)
|
||||
}
|
||||
|
||||
val updateStrategyAdapter = object : ColumnAdapter<UpdateStrategy, Int> {
|
||||
private val enumValues by lazy { UpdateStrategy.values() }
|
||||
|
||||
override fun decode(databaseValue: Int): UpdateStrategy =
|
||||
enumValues.getOrElse(databaseValue) { UpdateStrategy.ALWAYS_UPDATE }
|
||||
|
||||
override fun encode(value: UpdateStrategy): Int = value.ordinal
|
||||
}
|
||||
|
||||
interface ColumnAdapter<T : Any, S> {
|
||||
/**
|
||||
* @return [databaseValue] decoded as type [T].
|
||||
*/
|
||||
fun decode(databaseValue: S): T
|
||||
|
||||
/**
|
||||
* @return [value] encoded as database type [S].
|
||||
*/
|
||||
fun encode(value: T): S
|
||||
}
|
|
@ -20,7 +20,7 @@ class DbOpenCallback : SupportSQLiteOpenHelper.Callback(DATABASE_VERSION) {
|
|||
/**
|
||||
* Version of the database.
|
||||
*/
|
||||
const val DATABASE_VERSION = 15
|
||||
const val DATABASE_VERSION = 16
|
||||
}
|
||||
|
||||
override fun onOpen(db: SupportSQLiteDatabase) {
|
||||
|
@ -109,6 +109,9 @@ class DbOpenCallback : SupportSQLiteOpenHelper.Callback(DATABASE_VERSION) {
|
|||
db.execSQL(TrackTable.insertFromTempTable)
|
||||
db.execSQL(TrackTable.dropTempTable)
|
||||
}
|
||||
if (oldVersion < 16) {
|
||||
db.execSQL(MangaTable.addUpdateStrategy)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onConfigure(db: SupportSQLiteDatabase) {
|
||||
|
|
|
@ -27,9 +27,11 @@ import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_SOURCE
|
|||
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_STATUS
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_THUMBNAIL_URL
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_TITLE
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_UPDATE_STRATEGY
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_URL
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable.COL_VIEWER
|
||||
import eu.kanade.tachiyomi.data.database.tables.MangaTable.TABLE
|
||||
import eu.kanade.tachiyomi.data.database.updateStrategyAdapter
|
||||
|
||||
class MangaTypeMapping : SQLiteTypeMapping<Manga>(
|
||||
MangaPutResolver(),
|
||||
|
@ -68,6 +70,7 @@ class MangaPutResolver : DefaultPutResolver<Manga>() {
|
|||
put(COL_CHAPTER_FLAGS, obj.chapter_flags)
|
||||
put(COL_DATE_ADDED, obj.date_added)
|
||||
put(COL_FILTERED_SCANLATORS, obj.filtered_scanlators)
|
||||
put(COL_UPDATE_STRATEGY, obj.update_strategy.let(updateStrategyAdapter::encode))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,6 +94,9 @@ interface BaseMangaGetResolver {
|
|||
hide_title = cursor.getInt(cursor.getColumnIndex(COL_HIDE_TITLE)) == 1
|
||||
date_added = cursor.getLong(cursor.getColumnIndex(COL_DATE_ADDED))
|
||||
filtered_scanlators = cursor.getString(cursor.getColumnIndex(COL_FILTERED_SCANLATORS))
|
||||
update_strategy = cursor.getInt(cursor.getColumnIndex(COL_UPDATE_STRATEGY)).let(
|
||||
updateStrategyAdapter::decode,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ import eu.kanade.tachiyomi.data.download.DownloadManager
|
|||
import eu.kanade.tachiyomi.data.download.DownloadProvider
|
||||
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.injectLazy
|
||||
|
||||
open class MangaImpl : Manga {
|
||||
|
@ -68,6 +69,8 @@ open class MangaImpl : Manga {
|
|||
|
||||
override var date_added: Long = 0
|
||||
|
||||
override var update_strategy: UpdateStrategy = UpdateStrategy.ALWAYS_UPDATE
|
||||
|
||||
override var filtered_scanlators: String? = null
|
||||
|
||||
lateinit var ogTitle: String
|
||||
|
|
|
@ -46,6 +46,8 @@ object MangaTable {
|
|||
|
||||
const val COL_FILTERED_SCANLATORS = "filtered_scanlators"
|
||||
|
||||
const val COL_UPDATE_STRATEGY = "update_strategy"
|
||||
|
||||
val createTableQuery: String
|
||||
get() =
|
||||
"""CREATE TABLE $TABLE(
|
||||
|
@ -66,7 +68,8 @@ object MangaTable {
|
|||
$COL_HIDE_TITLE INTEGER NOT NULL,
|
||||
$COL_CHAPTER_FLAGS INTEGER NOT NULL,
|
||||
$COL_DATE_ADDED LONG,
|
||||
$COL_FILTERED_SCANLATORS TEXT
|
||||
$COL_FILTERED_SCANLATORS TEXT,
|
||||
$COL_UPDATE_STRATEGY INTEGER AS UpdateStrategy NOT NULL DEFAULT 0
|
||||
|
||||
)"""
|
||||
|
||||
|
@ -85,4 +88,7 @@ object MangaTable {
|
|||
|
||||
val addFilteredScanlators: String
|
||||
get() = "ALTER TABLE $TABLE ADD COLUMN $COL_FILTERED_SCANLATORS TEXT"
|
||||
|
||||
val addUpdateStrategy: String
|
||||
get() = "ALTER TABLE $TABLE ADD COLUMN $COL_UPDATE_STRATEGY INTEGER NOT NULL DEFAULT 0"
|
||||
}
|
||||
|
|
|
@ -31,6 +31,7 @@ import eu.kanade.tachiyomi.extension.ExtensionUpdateJob
|
|||
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.HttpSource
|
||||
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
||||
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithTrackServiceTwoWay
|
||||
|
@ -300,18 +301,24 @@ class LibraryUpdateService(
|
|||
private fun filterMangaToUpdate(mangaToAdd: List<LibraryManga>): List<LibraryManga> {
|
||||
val restrictions = preferences.libraryUpdateMangaRestriction().get()
|
||||
return mangaToAdd.filter { manga ->
|
||||
return@filter if (MANGA_NON_COMPLETED in restrictions && manga.status == SManga.COMPLETED) {
|
||||
skippedUpdates[manga] = getString(R.string.skipped_reason_completed)
|
||||
false
|
||||
} else if (MANGA_HAS_UNREAD in restrictions && manga.unread != 0) {
|
||||
skippedUpdates[manga] = getString(R.string.skipped_reason_not_caught_up)
|
||||
false
|
||||
} else if (MANGA_NON_READ in restrictions && manga.totalChapters > 0 && !manga.hasRead) {
|
||||
skippedUpdates[manga] = getString(R.string.skipped_reason_not_started)
|
||||
false
|
||||
} else {
|
||||
true
|
||||
when {
|
||||
MANGA_NON_COMPLETED in restrictions && manga.status == SManga.COMPLETED -> {
|
||||
skippedUpdates[manga] = getString(R.string.skipped_reason_completed)
|
||||
}
|
||||
MANGA_HAS_UNREAD in restrictions && manga.unread != 0 -> {
|
||||
skippedUpdates[manga] = getString(R.string.skipped_reason_not_caught_up)
|
||||
}
|
||||
MANGA_NON_READ in restrictions && manga.totalChapters > 0 && !manga.hasRead -> {
|
||||
skippedUpdates[manga] = getString(R.string.skipped_reason_not_started)
|
||||
}
|
||||
manga.update_strategy != UpdateStrategy.ALWAYS_UPDATE -> {
|
||||
skippedUpdates[manga] = getString(R.string.skipped_reason_not_always_update)
|
||||
}
|
||||
else -> {
|
||||
return@filter true
|
||||
}
|
||||
}
|
||||
return@filter false
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -39,7 +39,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
|
||||
|
||||
|
|
|
@ -3,6 +3,8 @@ package eu.kanade.tachiyomi.network
|
|||
import okhttp3.CacheControl
|
||||
import okhttp3.FormBody
|
||||
import okhttp3.Headers
|
||||
import okhttp3.HttpUrl
|
||||
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||
import okhttp3.Request
|
||||
import okhttp3.RequestBody
|
||||
import java.util.concurrent.TimeUnit.MINUTES
|
||||
|
@ -15,6 +17,17 @@ fun GET(
|
|||
url: String,
|
||||
headers: Headers = DEFAULT_HEADERS,
|
||||
cache: CacheControl = DEFAULT_CACHE_CONTROL,
|
||||
): Request {
|
||||
return GET(url.toHttpUrl(), headers, cache)
|
||||
}
|
||||
|
||||
/**
|
||||
* @since extensions-lib 1.4
|
||||
*/
|
||||
fun GET(
|
||||
url: HttpUrl,
|
||||
headers: Headers = DEFAULT_HEADERS,
|
||||
cache: CacheControl = DEFAULT_CACHE_CONTROL,
|
||||
): Request {
|
||||
return Request.Builder()
|
||||
.url(url)
|
||||
|
|
|
@ -21,6 +21,8 @@ interface SManga : Serializable {
|
|||
|
||||
var thumbnail_url: String?
|
||||
|
||||
var update_strategy: UpdateStrategy
|
||||
|
||||
var initialized: Boolean
|
||||
|
||||
val originalTitle: String
|
||||
|
@ -59,6 +61,8 @@ interface SManga : Serializable {
|
|||
|
||||
status = other.originalStatus
|
||||
|
||||
update_strategy = other.update_strategy
|
||||
|
||||
if (!initialized) {
|
||||
initialized = other.initialized
|
||||
}
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
package eu.kanade.tachiyomi.source.model
|
||||
|
||||
/**
|
||||
* Define the update strategy for a single [SManga].
|
||||
* The strategy used will only take effect on the library update.
|
||||
*
|
||||
* @since extensions-lib 1.4
|
||||
*/
|
||||
enum class UpdateStrategy {
|
||||
/**
|
||||
* Series marked as always update will be included in the library
|
||||
* update if they aren't excluded by additional restrictions.
|
||||
*/
|
||||
ALWAYS_UPDATE,
|
||||
|
||||
/**
|
||||
* Series marked as only fetch once will be automatically skipped
|
||||
* during library updates. Useful for cases where the series is previously
|
||||
* known to be finished and have only a single chapter, for example.
|
||||
*/
|
||||
ONLY_FETCH_ONCE,
|
||||
}
|
|
@ -211,6 +211,7 @@
|
|||
<string name="skipped_reason_completed">Skipped because series is complete</string>
|
||||
<string name="skipped_reason_not_caught_up">Skipped because there are unread chapters</string>
|
||||
<string name="skipped_reason_not_started">Skipped because no chapters are read</string>
|
||||
<string name="skipped_reason_not_always_update">Skipped because series does not require updates</string>
|
||||
<string name="channel_errors">Errors</string>
|
||||
<string name="channel_skipped">Skipped</string>
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue