From c2bfeb443d6e3dbcd1c45f3b9aa26c6c822e8bcf Mon Sep 17 00:00:00 2001 From: Cuong-Tran Date: Tue, 18 Feb 2025 14:58:46 +0700 Subject: [PATCH] remove MetadataUpdateJob (migrated into LibraryUpdateJob.updateCovers) --- .../data/library/MetadataUpdateJob.kt | 204 ------------------ 1 file changed, 204 deletions(-) delete mode 100644 app/src/main/java/eu/kanade/tachiyomi/data/library/MetadataUpdateJob.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/library/MetadataUpdateJob.kt b/app/src/main/java/eu/kanade/tachiyomi/data/library/MetadataUpdateJob.kt deleted file mode 100644 index c6401ef72..000000000 --- a/app/src/main/java/eu/kanade/tachiyomi/data/library/MetadataUpdateJob.kt +++ /dev/null @@ -1,204 +0,0 @@ -package eu.kanade.tachiyomi.data.library - -import android.content.Context -import android.content.pm.ServiceInfo -import android.os.Build -import androidx.work.CoroutineWorker -import androidx.work.ExistingWorkPolicy -import androidx.work.ForegroundInfo -import androidx.work.OneTimeWorkRequestBuilder -import androidx.work.WorkInfo -import androidx.work.WorkQuery -import androidx.work.WorkerParameters -import eu.kanade.domain.manga.interactor.UpdateManga -import eu.kanade.domain.manga.model.copyFrom -import eu.kanade.domain.manga.model.toSManga -import eu.kanade.tachiyomi.data.cache.CoverCache -import eu.kanade.tachiyomi.data.notification.Notifications -import eu.kanade.tachiyomi.util.prepUpdateCover -import eu.kanade.tachiyomi.util.system.isRunning -import eu.kanade.tachiyomi.util.system.setForegroundSafely -import eu.kanade.tachiyomi.util.system.workManager -import kotlinx.coroutines.CancellationException -import kotlinx.coroutines.async -import kotlinx.coroutines.awaitAll -import kotlinx.coroutines.coroutineScope -import kotlinx.coroutines.ensureActive -import kotlinx.coroutines.sync.Semaphore -import kotlinx.coroutines.sync.withPermit -import logcat.LogPriority -import tachiyomi.core.common.util.lang.withIOContext -import tachiyomi.core.common.util.system.logcat -import tachiyomi.domain.library.model.LibraryManga -import tachiyomi.domain.manga.interactor.GetLibraryManga -import tachiyomi.domain.manga.model.Manga -import tachiyomi.domain.manga.model.toMangaUpdate -import tachiyomi.domain.source.service.SourceManager -import uy.kohesive.injekt.Injekt -import uy.kohesive.injekt.api.get -import java.util.concurrent.CopyOnWriteArrayList -import java.util.concurrent.atomic.AtomicInteger - -class MetadataUpdateJob(private val context: Context, workerParams: WorkerParameters) : - CoroutineWorker(context, workerParams) { - - private val sourceManager: SourceManager = Injekt.get() - private val coverCache: CoverCache = Injekt.get() - private val getLibraryManga: GetLibraryManga = Injekt.get() - private val updateManga: UpdateManga = Injekt.get() - - private val notifier = LibraryUpdateNotifier(context) - - private var mangaToUpdate: List = mutableListOf() - - override suspend fun doWork(): Result { - setForegroundSafely() - - addMangaToQueue() - - return withIOContext { - try { - updateMetadata() - Result.success() - } catch (e: Exception) { - if (e is CancellationException) { - // Assume success although cancelled - Result.success() - } else { - logcat(LogPriority.ERROR, e) - Result.failure() - } - } finally { - notifier.cancelProgressNotification() - } - } - } - - override suspend fun getForegroundInfo(): ForegroundInfo { - val notifier = LibraryUpdateNotifier(context) - return ForegroundInfo( - Notifications.ID_LIBRARY_PROGRESS, - notifier.progressNotificationBuilder.build(), - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { - ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC - } else { - 0 - }, - ) - } - - /** - * Adds list of manga to be updated. - */ - private suspend fun addMangaToQueue() { - mangaToUpdate = getLibraryManga.await() - notifier.showQueueSizeWarningNotificationIfNeeded(mangaToUpdate) - } - - private suspend fun updateMetadata() { - val semaphore = Semaphore(5) - val progressCount = AtomicInteger(0) - val currentlyUpdatingManga = CopyOnWriteArrayList() - - coroutineScope { - mangaToUpdate.groupBy { it.manga.source } - .values - .map { mangaInSource -> - async { - semaphore.withPermit { - mangaInSource.forEach { libraryManga -> - val manga = libraryManga.manga - ensureActive() - - withUpdateNotification( - currentlyUpdatingManga, - progressCount, - manga, - ) { - val source = sourceManager.get(manga.source) ?: return@withUpdateNotification - try { - val networkManga = source.getMangaDetails(manga.toSManga()) - val updatedManga = manga.prepUpdateCover(coverCache, networkManga, true) - .copyFrom(networkManga) - try { - updateManga.await(updatedManga.toMangaUpdate()) - } catch (e: Exception) { - logcat(LogPriority.ERROR) { "Manga doesn't exist anymore" } - } - } catch (e: Throwable) { - // Ignore errors and continue - logcat(LogPriority.ERROR, e) - } - } - } - } - } - } - .awaitAll() - } - - notifier.cancelProgressNotification() - } - - private suspend fun withUpdateNotification( - updatingManga: CopyOnWriteArrayList, - completed: AtomicInteger, - manga: Manga, - block: suspend () -> Unit, - ) = coroutineScope { - ensureActive() - - updatingManga.add(manga) - notifier.showProgressNotification( - updatingManga, - completed.get(), - mangaToUpdate.size, - ) - - block() - - ensureActive() - - updatingManga.remove(manga) - completed.getAndIncrement() - notifier.showProgressNotification( - updatingManga, - completed.get(), - mangaToUpdate.size, - ) - } - - companion object { - private const val TAG = "MetadataUpdate" - private const val WORK_NAME_MANUAL = "MetadataUpdate" - - private const val MANGA_PER_SOURCE_QUEUE_WARNING_THRESHOLD = 60 - - fun startNow(context: Context): Boolean { - val wm = context.workManager - if (wm.isRunning(TAG)) { - // Already running either as a scheduled or manual job - return false - } - val request = OneTimeWorkRequestBuilder() - .addTag(TAG) - .addTag(WORK_NAME_MANUAL) - .build() - wm.enqueueUniqueWork(WORK_NAME_MANUAL, ExistingWorkPolicy.KEEP, request) - - return true - } - - fun stop(context: Context) { - val wm = context.workManager - val workQuery = WorkQuery.Builder.fromTags(listOf(TAG)) - .addStates(listOf(WorkInfo.State.RUNNING)) - .build() - wm.getWorkInfos(workQuery).get() - // Should only return one work but just in case - .forEach { - wm.cancelWorkById(it.id) - } - } - } -}