mirror of
https://github.com/Suwayomi/Suwayomi-Server.git
synced 2026-07-13 07:44:34 -05:00
Feature/streamline settings (#1614)
* Cleanup graphql setting mutation
* Validate values read from config
* Generate server-reference.conf files from ServerConfig
* Remove unnecessary enum value handling in config value update
Commit df0078b725 introduced the usage of config4k, which handles enums automatically. Thus, this handling is outdated and not needed anymore
* Generate gql SettingsType from ServerConfig
* Extract settings backup logic
* Generate settings backup files
* Move "group" arg to second position
To make it easier to detect and have it at the same position consistently for all settings.
* Remove setting generation from compilation
* Extract setting generation code into new module
* Extract pure setting generation code into new module
* Remove generated settings files from src tree
* Force each setting to set a default value
This commit is contained in:
@@ -31,13 +31,12 @@ import suwayomi.tachidesk.manga.impl.Chapter
|
||||
import suwayomi.tachidesk.manga.impl.Manga
|
||||
import suwayomi.tachidesk.manga.impl.Source
|
||||
import suwayomi.tachidesk.manga.impl.backup.BackupFlags
|
||||
import suwayomi.tachidesk.manga.impl.backup.proto.handlers.BackupSettingsHandler
|
||||
import suwayomi.tachidesk.manga.impl.backup.proto.models.Backup
|
||||
import suwayomi.tachidesk.manga.impl.backup.proto.models.BackupCategory
|
||||
import suwayomi.tachidesk.manga.impl.backup.proto.models.BackupChapter
|
||||
import suwayomi.tachidesk.manga.impl.backup.proto.models.BackupHistory
|
||||
import suwayomi.tachidesk.manga.impl.backup.proto.models.BackupManga
|
||||
import suwayomi.tachidesk.manga.impl.backup.proto.models.BackupServerSettings
|
||||
import suwayomi.tachidesk.manga.impl.backup.proto.models.BackupServerSettings.BackupSettingsDownloadConversionType
|
||||
import suwayomi.tachidesk.manga.impl.backup.proto.models.BackupSource
|
||||
import suwayomi.tachidesk.manga.impl.backup.proto.models.BackupTracking
|
||||
import suwayomi.tachidesk.manga.impl.track.Track
|
||||
@@ -97,15 +96,11 @@ object ProtoBackupExport : ProtoBackupBase() {
|
||||
}
|
||||
}
|
||||
|
||||
val (hour, minute) =
|
||||
val (backupHour, backupMinute) =
|
||||
serverConfig.backupTime.value
|
||||
.split(":")
|
||||
.map { it.toInt() }
|
||||
val backupHour = hour.coerceAtLeast(0).coerceAtMost(23)
|
||||
val backupMinute = minute.coerceAtLeast(0).coerceAtMost(59)
|
||||
val backupInterval =
|
||||
serverConfig.backupInterval.value.days
|
||||
.coerceAtLeast(1.days)
|
||||
val backupInterval = serverConfig.backupInterval.value.days
|
||||
|
||||
// trigger last backup in case the server wasn't running on the scheduled time
|
||||
val lastAutomatedBackup = preferences.getLong(LAST_AUTOMATED_BACKUP_KEY, 0)
|
||||
@@ -193,7 +188,7 @@ object ProtoBackupExport : ProtoBackupBase() {
|
||||
backupCategories(flags),
|
||||
backupExtensionInfo(databaseManga, flags),
|
||||
backupGlobalMeta(flags),
|
||||
backupServerSettings(flags),
|
||||
BackupSettingsHandler.backup(flags),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -378,102 +373,4 @@ object ProtoBackupExport : ProtoBackupBase() {
|
||||
|
||||
return GlobalMeta.getMetaMap()
|
||||
}
|
||||
|
||||
private fun backupServerSettings(flags: BackupFlags): BackupServerSettings? {
|
||||
if (!flags.includeServerSettings) {
|
||||
return null
|
||||
}
|
||||
|
||||
return BackupServerSettings(
|
||||
ip = serverConfig.ip.value,
|
||||
port = serverConfig.port.value,
|
||||
// socks
|
||||
socksProxyEnabled = serverConfig.socksProxyEnabled.value,
|
||||
socksProxyVersion = serverConfig.socksProxyVersion.value,
|
||||
socksProxyHost = serverConfig.socksProxyHost.value,
|
||||
socksProxyPort = serverConfig.socksProxyPort.value,
|
||||
socksProxyUsername = serverConfig.socksProxyUsername.value,
|
||||
socksProxyPassword = serverConfig.socksProxyPassword.value,
|
||||
// webUI
|
||||
webUIFlavor = serverConfig.webUIFlavor.value,
|
||||
initialOpenInBrowserEnabled = serverConfig.initialOpenInBrowserEnabled.value,
|
||||
webUIInterface = serverConfig.webUIInterface.value,
|
||||
electronPath = serverConfig.electronPath.value,
|
||||
webUIChannel = serverConfig.webUIChannel.value,
|
||||
webUIUpdateCheckInterval = serverConfig.webUIUpdateCheckInterval.value,
|
||||
// downloader
|
||||
downloadAsCbz = serverConfig.downloadAsCbz.value,
|
||||
downloadsPath = serverConfig.downloadsPath.value,
|
||||
autoDownloadNewChapters = serverConfig.autoDownloadNewChapters.value,
|
||||
excludeEntryWithUnreadChapters = serverConfig.excludeEntryWithUnreadChapters.value,
|
||||
autoDownloadAheadLimit = 0, // deprecated
|
||||
autoDownloadNewChaptersLimit = serverConfig.autoDownloadNewChaptersLimit.value,
|
||||
autoDownloadIgnoreReUploads = serverConfig.autoDownloadIgnoreReUploads.value,
|
||||
downloadConversions =
|
||||
serverConfig.downloadConversions.value.map {
|
||||
BackupSettingsDownloadConversionType(
|
||||
it.key,
|
||||
it.value.target,
|
||||
it.value.compressionLevel,
|
||||
)
|
||||
},
|
||||
// extension
|
||||
extensionRepos = serverConfig.extensionRepos.value,
|
||||
// requests
|
||||
maxSourcesInParallel = serverConfig.maxSourcesInParallel.value,
|
||||
// updater
|
||||
excludeUnreadChapters = serverConfig.excludeUnreadChapters.value,
|
||||
excludeNotStarted = serverConfig.excludeNotStarted.value,
|
||||
excludeCompleted = serverConfig.excludeCompleted.value,
|
||||
globalUpdateInterval = serverConfig.globalUpdateInterval.value,
|
||||
updateMangas = serverConfig.updateMangas.value,
|
||||
// Authentication
|
||||
authMode = serverConfig.authMode.value,
|
||||
jwtAudience = serverConfig.jwtAudience.value,
|
||||
jwtTokenExpiry = serverConfig.jwtTokenExpiry.value,
|
||||
jwtRefreshExpiry = serverConfig.jwtRefreshExpiry.value,
|
||||
authUsername = serverConfig.authUsername.value,
|
||||
authPassword = serverConfig.authPassword.value,
|
||||
basicAuthEnabled = false,
|
||||
basicAuthUsername = null,
|
||||
basicAuthPassword = null,
|
||||
// misc
|
||||
debugLogsEnabled = serverConfig.debugLogsEnabled.value,
|
||||
gqlDebugLogsEnabled = false, // deprecated
|
||||
systemTrayEnabled = serverConfig.systemTrayEnabled.value,
|
||||
maxLogFiles = serverConfig.maxLogFiles.value,
|
||||
maxLogFileSize = serverConfig.maxLogFileSize.value,
|
||||
maxLogFolderSize = serverConfig.maxLogFolderSize.value,
|
||||
// backup
|
||||
backupPath = serverConfig.backupPath.value,
|
||||
backupTime = serverConfig.backupTime.value,
|
||||
backupInterval = serverConfig.backupInterval.value,
|
||||
backupTTL = serverConfig.backupTTL.value,
|
||||
// local source
|
||||
localSourcePath = serverConfig.localSourcePath.value,
|
||||
// cloudflare bypass
|
||||
flareSolverrEnabled = serverConfig.flareSolverrEnabled.value,
|
||||
flareSolverrUrl = serverConfig.flareSolverrUrl.value,
|
||||
flareSolverrTimeout = serverConfig.flareSolverrTimeout.value,
|
||||
flareSolverrSessionName = serverConfig.flareSolverrSessionName.value,
|
||||
flareSolverrSessionTtl = serverConfig.flareSolverrSessionTtl.value,
|
||||
flareSolverrAsResponseFallback = serverConfig.flareSolverrAsResponseFallback.value,
|
||||
// opds
|
||||
opdsUseBinaryFileSizes = serverConfig.opdsUseBinaryFileSizes.value,
|
||||
opdsItemsPerPage = serverConfig.opdsItemsPerPage.value,
|
||||
opdsEnablePageReadProgress = serverConfig.opdsEnablePageReadProgress.value,
|
||||
opdsMarkAsReadOnDownload = serverConfig.opdsMarkAsReadOnDownload.value,
|
||||
opdsShowOnlyUnreadChapters = serverConfig.opdsShowOnlyUnreadChapters.value,
|
||||
opdsShowOnlyDownloadedChapters = serverConfig.opdsShowOnlyDownloadedChapters.value,
|
||||
opdsChapterSortOrder = serverConfig.opdsChapterSortOrder.value,
|
||||
// koreader sync
|
||||
koreaderSyncServerUrl = serverConfig.koreaderSyncServerUrl.value,
|
||||
koreaderSyncUsername = serverConfig.koreaderSyncUsername.value,
|
||||
koreaderSyncUserkey = serverConfig.koreaderSyncUserkey.value,
|
||||
koreaderSyncDeviceId = serverConfig.koreaderSyncDeviceId.value,
|
||||
koreaderSyncChecksumMethod = serverConfig.koreaderSyncChecksumMethod.value,
|
||||
koreaderSyncStrategy = serverConfig.koreaderSyncStrategy.value,
|
||||
koreaderSyncPercentageTolerance = serverConfig.koreaderSyncPercentageTolerance.value,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,8 +31,6 @@ import org.jetbrains.exposed.sql.statements.BatchUpdateStatement
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
import org.jetbrains.exposed.sql.update
|
||||
import suwayomi.tachidesk.global.impl.GlobalMeta
|
||||
import suwayomi.tachidesk.graphql.mutations.SettingsMutation
|
||||
import suwayomi.tachidesk.graphql.types.AuthMode
|
||||
import suwayomi.tachidesk.graphql.types.toStatus
|
||||
import suwayomi.tachidesk.manga.impl.Category
|
||||
import suwayomi.tachidesk.manga.impl.Category.modifyCategoriesMetas
|
||||
@@ -43,12 +41,12 @@ import suwayomi.tachidesk.manga.impl.Manga.modifyMangasMetas
|
||||
import suwayomi.tachidesk.manga.impl.Source.modifySourceMetas
|
||||
import suwayomi.tachidesk.manga.impl.backup.proto.ProtoBackupValidator.ValidationResult
|
||||
import suwayomi.tachidesk.manga.impl.backup.proto.ProtoBackupValidator.validate
|
||||
import suwayomi.tachidesk.manga.impl.backup.proto.handlers.BackupSettingsHandler
|
||||
import suwayomi.tachidesk.manga.impl.backup.proto.models.Backup
|
||||
import suwayomi.tachidesk.manga.impl.backup.proto.models.BackupCategory
|
||||
import suwayomi.tachidesk.manga.impl.backup.proto.models.BackupChapter
|
||||
import suwayomi.tachidesk.manga.impl.backup.proto.models.BackupHistory
|
||||
import suwayomi.tachidesk.manga.impl.backup.proto.models.BackupManga
|
||||
import suwayomi.tachidesk.manga.impl.backup.proto.models.BackupServerSettings
|
||||
import suwayomi.tachidesk.manga.impl.backup.proto.models.BackupSource
|
||||
import suwayomi.tachidesk.manga.impl.backup.proto.models.BackupTracking
|
||||
import suwayomi.tachidesk.manga.impl.track.tracker.TrackerManager
|
||||
@@ -58,7 +56,6 @@ import suwayomi.tachidesk.manga.model.dataclass.TrackRecordDataClass
|
||||
import suwayomi.tachidesk.manga.model.table.ChapterTable
|
||||
import suwayomi.tachidesk.manga.model.table.MangaTable
|
||||
import suwayomi.tachidesk.server.database.dbTransaction
|
||||
import suwayomi.tachidesk.server.serverConfig
|
||||
import java.io.InputStream
|
||||
import java.util.Date
|
||||
import java.util.Timer
|
||||
@@ -215,7 +212,7 @@ object ProtoBackupImport : ProtoBackupBase() {
|
||||
BackupRestoreState.RestoringSettings(restoreCategories + restoreMeta + restoreSettings, restoreAmount),
|
||||
)
|
||||
|
||||
restoreServerSettings(backup.serverSettings)
|
||||
BackupSettingsHandler.restore(backup.serverSettings)
|
||||
|
||||
// Store source mapping for error messages
|
||||
val sourceMapping = backup.getSourceMap()
|
||||
@@ -522,21 +519,5 @@ object ProtoBackupImport : ProtoBackupBase() {
|
||||
modifySourceMetas(backupSources.associateBy { it.sourceId }.mapValues { it.value.meta })
|
||||
}
|
||||
|
||||
private fun restoreServerSettings(backupServerSettings: BackupServerSettings?) {
|
||||
if (backupServerSettings == null) {
|
||||
return
|
||||
}
|
||||
|
||||
SettingsMutation().updateSettings(
|
||||
backupServerSettings.copy(
|
||||
// legacy settings cannot overwrite new settings
|
||||
basicAuthEnabled =
|
||||
backupServerSettings.basicAuthEnabled.takeIf {
|
||||
serverConfig.authMode.value == AuthMode.NONE
|
||||
},
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
private fun TrackRecordDataClass.forComparison() = this.copy(id = 0, mangaId = 0)
|
||||
}
|
||||
|
||||
@@ -1,95 +0,0 @@
|
||||
package suwayomi.tachidesk.manga.impl.backup.proto.models
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
import org.jetbrains.exposed.sql.SortOrder
|
||||
import suwayomi.tachidesk.graphql.types.AuthMode
|
||||
import suwayomi.tachidesk.graphql.types.KoreaderSyncChecksumMethod
|
||||
import suwayomi.tachidesk.graphql.types.KoreaderSyncStrategy
|
||||
import suwayomi.tachidesk.graphql.types.Settings
|
||||
import suwayomi.tachidesk.graphql.types.SettingsDownloadConversion
|
||||
import suwayomi.tachidesk.graphql.types.WebUIChannel
|
||||
import suwayomi.tachidesk.graphql.types.WebUIFlavor
|
||||
import suwayomi.tachidesk.graphql.types.WebUIInterface
|
||||
import kotlin.time.Duration
|
||||
|
||||
@Serializable
|
||||
data class BackupServerSettings(
|
||||
@ProtoNumber(1) override var ip: String,
|
||||
@ProtoNumber(2) override var port: Int,
|
||||
@ProtoNumber(3) override var socksProxyEnabled: Boolean,
|
||||
@ProtoNumber(4) override var socksProxyVersion: Int,
|
||||
@ProtoNumber(5) override var socksProxyHost: String,
|
||||
@ProtoNumber(6) override var socksProxyPort: String,
|
||||
@ProtoNumber(7) override var socksProxyUsername: String,
|
||||
@ProtoNumber(8) override var socksProxyPassword: String,
|
||||
@ProtoNumber(9) override var webUIFlavor: WebUIFlavor,
|
||||
@ProtoNumber(10) override var initialOpenInBrowserEnabled: Boolean,
|
||||
@ProtoNumber(11) override var webUIInterface: WebUIInterface,
|
||||
@ProtoNumber(12) override var electronPath: String,
|
||||
@ProtoNumber(13) override var webUIChannel: WebUIChannel,
|
||||
@ProtoNumber(14) override var webUIUpdateCheckInterval: Double,
|
||||
@ProtoNumber(15) override var downloadAsCbz: Boolean,
|
||||
@ProtoNumber(16) override var downloadsPath: String,
|
||||
@ProtoNumber(17) override var autoDownloadNewChapters: Boolean,
|
||||
@ProtoNumber(18) override var excludeEntryWithUnreadChapters: Boolean,
|
||||
@ProtoNumber(19) override var autoDownloadAheadLimit: Int,
|
||||
@ProtoNumber(20) override var autoDownloadNewChaptersLimit: Int,
|
||||
@ProtoNumber(21) override var autoDownloadIgnoreReUploads: Boolean,
|
||||
@ProtoNumber(22) override var extensionRepos: List<String>,
|
||||
@ProtoNumber(23) override var maxSourcesInParallel: Int,
|
||||
@ProtoNumber(24) override var excludeUnreadChapters: Boolean,
|
||||
@ProtoNumber(25) override var excludeNotStarted: Boolean,
|
||||
@ProtoNumber(26) override var excludeCompleted: Boolean,
|
||||
@ProtoNumber(27) override var globalUpdateInterval: Double,
|
||||
@ProtoNumber(28) override var updateMangas: Boolean,
|
||||
@ProtoNumber(29) override var basicAuthEnabled: Boolean?,
|
||||
@ProtoNumber(30) override var authUsername: String,
|
||||
@ProtoNumber(31) override var authPassword: String,
|
||||
@ProtoNumber(32) override var debugLogsEnabled: Boolean,
|
||||
@ProtoNumber(33) override var gqlDebugLogsEnabled: Boolean,
|
||||
@ProtoNumber(34) override var systemTrayEnabled: Boolean,
|
||||
@ProtoNumber(35) override var maxLogFiles: Int,
|
||||
@ProtoNumber(36) override var maxLogFileSize: String,
|
||||
@ProtoNumber(37) override var maxLogFolderSize: String,
|
||||
@ProtoNumber(38) override var backupPath: String,
|
||||
@ProtoNumber(39) override var backupTime: String,
|
||||
@ProtoNumber(40) override var backupInterval: Int,
|
||||
@ProtoNumber(41) override var backupTTL: Int,
|
||||
@ProtoNumber(42) override var localSourcePath: String,
|
||||
@ProtoNumber(43) override var flareSolverrEnabled: Boolean,
|
||||
@ProtoNumber(44) override var flareSolverrUrl: String,
|
||||
@ProtoNumber(45) override var flareSolverrTimeout: Int,
|
||||
@ProtoNumber(46) override var flareSolverrSessionName: String,
|
||||
@ProtoNumber(47) override var flareSolverrSessionTtl: Int,
|
||||
@ProtoNumber(48) override var flareSolverrAsResponseFallback: Boolean,
|
||||
@ProtoNumber(49) override var opdsUseBinaryFileSizes: Boolean,
|
||||
@ProtoNumber(50) override var opdsItemsPerPage: Int,
|
||||
@ProtoNumber(51) override var opdsEnablePageReadProgress: Boolean,
|
||||
@ProtoNumber(52) override var opdsMarkAsReadOnDownload: Boolean,
|
||||
@ProtoNumber(53) override var opdsShowOnlyUnreadChapters: Boolean,
|
||||
@ProtoNumber(54) override var opdsShowOnlyDownloadedChapters: Boolean,
|
||||
@ProtoNumber(55) override var opdsChapterSortOrder: SortOrder,
|
||||
@ProtoNumber(56) override var authMode: AuthMode,
|
||||
@ProtoNumber(57) override val downloadConversions: List<BackupSettingsDownloadConversionType>?,
|
||||
@ProtoNumber(58) override var jwtAudience: String?,
|
||||
@ProtoNumber(59) override var koreaderSyncServerUrl: String,
|
||||
@ProtoNumber(60) override var koreaderSyncUsername: String,
|
||||
@ProtoNumber(61) override var koreaderSyncUserkey: String,
|
||||
@ProtoNumber(62) override var koreaderSyncDeviceId: String,
|
||||
@ProtoNumber(63) override var koreaderSyncChecksumMethod: KoreaderSyncChecksumMethod,
|
||||
@ProtoNumber(64) override var koreaderSyncStrategy: KoreaderSyncStrategy,
|
||||
@ProtoNumber(65) override var koreaderSyncPercentageTolerance: Double,
|
||||
@ProtoNumber(66) override var jwtTokenExpiry: Duration?,
|
||||
@ProtoNumber(67) override var jwtRefreshExpiry: Duration?,
|
||||
// Deprecated settings
|
||||
@ProtoNumber(99991) override var basicAuthUsername: String?,
|
||||
@ProtoNumber(99992) override var basicAuthPassword: String?,
|
||||
) : Settings {
|
||||
@Serializable
|
||||
class BackupSettingsDownloadConversionType(
|
||||
@ProtoNumber(1) override val mimeType: String,
|
||||
@ProtoNumber(2) override val target: String,
|
||||
@ProtoNumber(3) override val compressionLevel: Double?,
|
||||
) : SettingsDownloadConversion
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
package suwayomi.tachidesk.manga.impl.backup.proto.models
|
||||
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.protobuf.ProtoNumber
|
||||
import suwayomi.tachidesk.graphql.types.SettingsDownloadConversion
|
||||
|
||||
@Serializable
|
||||
class BackupSettingsDownloadConversionType(
|
||||
@ProtoNumber(1) override val mimeType: String,
|
||||
@ProtoNumber(2) override val target: String,
|
||||
@ProtoNumber(3) override val compressionLevel: Double?,
|
||||
) : SettingsDownloadConversion
|
||||
@@ -261,7 +261,7 @@ object DownloadManager {
|
||||
"Failed: ${downloadQueue.size - availableDownloads.size}"
|
||||
}
|
||||
|
||||
if (runningDownloaders.size < serverConfig.maxSourcesInParallel.value.coerceAtLeast(1)) {
|
||||
if (runningDownloaders.size < serverConfig.maxSourcesInParallel.value) {
|
||||
availableDownloads
|
||||
.asSequence()
|
||||
.map { it.manga.sourceId }
|
||||
|
||||
@@ -14,6 +14,7 @@ import org.apache.commons.compress.archivers.zip.ZipArchiveEntry
|
||||
import org.jetbrains.exposed.sql.selectAll
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
import org.jetbrains.exposed.sql.update
|
||||
import suwayomi.tachidesk.graphql.types.DownloadConversion
|
||||
import suwayomi.tachidesk.manga.impl.Page
|
||||
import suwayomi.tachidesk.manga.impl.chapter.getChapterDownloadReady
|
||||
import suwayomi.tachidesk.manga.impl.download.model.DownloadChapter
|
||||
@@ -25,7 +26,6 @@ import suwayomi.tachidesk.manga.impl.util.getChapterDownloadPath
|
||||
import suwayomi.tachidesk.manga.impl.util.storage.ImageResponse
|
||||
import suwayomi.tachidesk.manga.model.table.ChapterTable
|
||||
import suwayomi.tachidesk.manga.model.table.MangaTable
|
||||
import suwayomi.tachidesk.server.ServerConfig
|
||||
import suwayomi.tachidesk.server.serverConfig
|
||||
import suwayomi.tachidesk.util.ConversionUtil
|
||||
import java.io.File
|
||||
@@ -261,7 +261,7 @@ abstract class ChaptersFilesProvider<Type : FileType>(
|
||||
|
||||
private fun convertPage(
|
||||
page: File,
|
||||
conversion: ServerConfig.DownloadConversion,
|
||||
conversion: DownloadConversion,
|
||||
) {
|
||||
val (targetMime, compressionLevel) = conversion
|
||||
|
||||
|
||||
@@ -96,8 +96,7 @@ class Updater : IUpdater {
|
||||
serverConfig.subscribeTo(serverConfig.globalUpdateInterval, ::scheduleUpdateTask)
|
||||
serverConfig.subscribeTo(
|
||||
serverConfig.maxSourcesInParallel,
|
||||
{ value ->
|
||||
val newMaxPermits = value.coerceAtLeast(1).coerceAtMost(20)
|
||||
{ newMaxPermits ->
|
||||
val permitDifference = maxSourcesInParallel - newMaxPermits
|
||||
maxSourcesInParallel = newMaxPermits
|
||||
|
||||
@@ -160,10 +159,7 @@ class Updater : IUpdater {
|
||||
return
|
||||
}
|
||||
|
||||
val updateInterval =
|
||||
serverConfig.globalUpdateInterval.value.hours
|
||||
.coerceAtLeast(6.hours)
|
||||
.inWholeMilliseconds
|
||||
val updateInterval = serverConfig.globalUpdateInterval.value.hours.inWholeMilliseconds
|
||||
val lastAutomatedUpdate = getLastAutomatedUpdateTimestamp()
|
||||
val isInitialScheduling = lastAutomatedUpdate == 0L
|
||||
|
||||
|
||||
Reference in New Issue
Block a user