remove MetadataUpdateJob (migrated into LibraryUpdateJob.updateCovers)
This commit is contained in:
parent
f95d19782b
commit
c2bfeb443d
1 changed files with 0 additions and 204 deletions
|
|
@ -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<LibraryManga> = 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<Manga>()
|
|
||||||
|
|
||||||
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<Manga>,
|
|
||||||
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<MetadataUpdateJob>()
|
|
||||||
.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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
Reference in a new issue