diff --git a/AndroidCompat/Config/src/main/java/xyz/nulldev/ts/config/ConfigModule.kt b/AndroidCompat/Config/src/main/java/xyz/nulldev/ts/config/ConfigModule.kt index 3594059359..9005e51468 100644 --- a/AndroidCompat/Config/src/main/java/xyz/nulldev/ts/config/ConfigModule.kt +++ b/AndroidCompat/Config/src/main/java/xyz/nulldev/ts/config/ConfigModule.kt @@ -41,6 +41,7 @@ class SystemPropertyOverrideDelegate(val getConfig: () -> Config, val moduleName return when (T::class.simpleName) { "Int" -> combined.toInt() "Boolean" -> combined.toBoolean() + "Double" -> combined.toDouble() // add more types as needed else -> combined // covers String } as T diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/update/Updater.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/update/Updater.kt index b45ab47058..06c6fbecc4 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/update/Updater.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/update/Updater.kt @@ -21,7 +21,7 @@ import mu.KotlinLogging import org.kodein.di.DI import org.kodein.di.conf.global import org.kodein.di.instance -import suwayomi.tachidesk.manga.controller.UpdateController +import suwayomi.tachidesk.manga.impl.Category import suwayomi.tachidesk.manga.impl.CategoryManga import suwayomi.tachidesk.manga.impl.Chapter import suwayomi.tachidesk.manga.model.dataclass.CategoryDataClass @@ -29,7 +29,11 @@ import suwayomi.tachidesk.manga.model.dataclass.IncludeInUpdate import suwayomi.tachidesk.manga.model.dataclass.MangaDataClass import suwayomi.tachidesk.manga.model.table.MangaStatus import suwayomi.tachidesk.server.serverConfig +import java.util.Date +import java.util.Timer +import java.util.TimerTask import java.util.concurrent.ConcurrentHashMap +import java.util.prefs.Preferences class Updater : IUpdater { private val logger = KotlinLogging.logger {} @@ -43,6 +47,46 @@ class Updater : IUpdater { private val semaphore = Semaphore(serverConfig.maxParallelUpdateRequests) + private val lastAutomatedUpdateKey = "lastAutomatedUpdateKey" + private val preferences = Preferences.userNodeForPackage(Updater::class.java) + + private val updateTimer = Timer() + private var currentUpdateTask: TimerTask? = null + + init { + scheduleUpdateTask() + } + + private fun scheduleUpdateTask() { + if (!serverConfig.automaticallyTriggerGlobalUpdate) { + return + } + + val minInterval = 1000 * 60 * 60 * 6L // 6 hours + val intervalInMS = (serverConfig.globalUpdateInterval * 60 * 60 * 1000).toLong() // hours to ms + val updateInterval = intervalInMS.coerceAtLeast(minInterval) + + val lastAutomatedUpdate = preferences.getLong(lastAutomatedUpdateKey, 0) + val initialDelay = updateInterval - (System.currentTimeMillis() - lastAutomatedUpdate) % updateInterval + + currentUpdateTask?.cancel() + currentUpdateTask = object : TimerTask() { + override fun run() { + preferences.putLong(lastAutomatedUpdateKey, System.currentTimeMillis()) + + if (status.value.running) { + logger.debug { "Global update is already in progress, do not trigger global update" } + return + } + + logger.info { "Trigger global update (interval= ${serverConfig.globalUpdateInterval}h, lastAutomatedUpdate= ${Date(lastAutomatedUpdate)})" } + addCategoriesToUpdateQueue(Category.getCategoryList(), true) + } + } + + updateTimer.scheduleAtFixedRate(currentUpdateTask, initialDelay, updateInterval) + } + private fun getOrCreateUpdateChannelFor(source: String): Channel { return updateChannels.getOrPut(source) { logger.debug { "getOrCreateUpdateChannelFor: created channel for $source - channels: ${updateChannels.size + 1}" } diff --git a/server/src/main/kotlin/suwayomi/tachidesk/server/ServerConfig.kt b/server/src/main/kotlin/suwayomi/tachidesk/server/ServerConfig.kt index 3a51645a8a..41e06fbdff 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/server/ServerConfig.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/server/ServerConfig.kt @@ -38,6 +38,8 @@ class ServerConfig(getConfig: () -> Config, moduleName: String = MODULE_NAME) : var excludeUnreadChapters: Boolean by overridableConfig var excludeNotStarted: Boolean by overridableConfig var excludeCompleted: Boolean by overridableConfig + var automaticallyTriggerGlobalUpdate: Boolean by overridableConfig + var globalUpdateInterval: Double by overridableConfig // Authentication var basicAuthEnabled: Boolean by overridableConfig diff --git a/server/src/main/kotlin/suwayomi/tachidesk/server/ServerSetup.kt b/server/src/main/kotlin/suwayomi/tachidesk/server/ServerSetup.kt index 5206528378..ffe96084a0 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/server/ServerSetup.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/server/ServerSetup.kt @@ -66,10 +66,12 @@ fun applicationSetup() { // Application dirs val applicationDirs = ApplicationDirs() + val updater = Updater() + DI.global.addImport( DI.Module("Server") { bind() with singleton { applicationDirs } - bind() with singleton { Updater() } + bind() with singleton { updater } bind() with singleton { JavalinJackson() } bind() with singleton { Json { ignoreUnknownKeys = true } } } diff --git a/server/src/main/resources/server-reference.conf b/server/src/main/resources/server-reference.conf index 4847a0ec04..f1cbb82ffa 100644 --- a/server/src/main/resources/server-reference.conf +++ b/server/src/main/resources/server-reference.conf @@ -23,6 +23,8 @@ server.maxParallelUpdateRequests = 10 # sets how many sources can be updated in server.excludeUnreadChapters = true server.excludeNotStarted = true server.excludeCompleted = true +server.automaticallyTriggerGlobalUpdate = false +server.globalUpdateInterval = 12 # time in hours (doesn't have to be full hours e.g. 12.5) - range: 6 <= n < ∞ - default: 12 hours - interval in which the global update will be automatically triggered # Authentication server.basicAuthEnabled = false diff --git a/server/src/test/resources/server-reference.conf b/server/src/test/resources/server-reference.conf index 324cde08d1..aedf9f2749 100644 --- a/server/src/test/resources/server-reference.conf +++ b/server/src/test/resources/server-reference.conf @@ -15,6 +15,8 @@ server.maxParallelUpdateRequests = 10 server.excludeUnreadChapters = true server.excludeNotStarted = true server.excludeCompleted = true +server.automaticallyTriggerGlobalUpdate = false +server.globalUpdateInterval = 12 # misc server.debugLogsEnabled = true