Cleanup LibraryUpdateService (#8237)
This commit is contained in:
parent
bd285920cd
commit
4ff5c1148e
@ -157,10 +157,6 @@ class LibraryUpdateNotifier(private val context: Context) {
|
|||||||
* @param updates a list of manga with new updates.
|
* @param updates a list of manga with new updates.
|
||||||
*/
|
*/
|
||||||
fun showUpdateNotifications(updates: List<Pair<Manga, Array<Chapter>>>) {
|
fun showUpdateNotifications(updates: List<Pair<Manga, Array<Chapter>>>) {
|
||||||
if (updates.isEmpty()) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
NotificationManagerCompat.from(context).apply {
|
NotificationManagerCompat.from(context).apply {
|
||||||
// Parent group notification
|
// Parent group notification
|
||||||
notify(
|
notify(
|
||||||
|
@ -12,6 +12,7 @@ import eu.kanade.domain.category.model.Category
|
|||||||
import eu.kanade.domain.chapter.interactor.GetChapterByMangaId
|
import eu.kanade.domain.chapter.interactor.GetChapterByMangaId
|
||||||
import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource
|
import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource
|
||||||
import eu.kanade.domain.chapter.interactor.SyncChaptersWithTrackServiceTwoWay
|
import eu.kanade.domain.chapter.interactor.SyncChaptersWithTrackServiceTwoWay
|
||||||
|
import eu.kanade.domain.chapter.model.Chapter
|
||||||
import eu.kanade.domain.chapter.model.toDbChapter
|
import eu.kanade.domain.chapter.model.toDbChapter
|
||||||
import eu.kanade.domain.download.service.DownloadPreferences
|
import eu.kanade.domain.download.service.DownloadPreferences
|
||||||
import eu.kanade.domain.library.model.LibraryManga
|
import eu.kanade.domain.library.model.LibraryManga
|
||||||
@ -27,8 +28,6 @@ import eu.kanade.domain.track.model.toDbTrack
|
|||||||
import eu.kanade.domain.track.model.toDomainTrack
|
import eu.kanade.domain.track.model.toDomainTrack
|
||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.cache.CoverCache
|
import eu.kanade.tachiyomi.data.cache.CoverCache
|
||||||
import eu.kanade.tachiyomi.data.database.models.Chapter
|
|
||||||
import eu.kanade.tachiyomi.data.database.models.toDomainChapter
|
|
||||||
import eu.kanade.tachiyomi.data.download.DownloadManager
|
import eu.kanade.tachiyomi.data.download.DownloadManager
|
||||||
import eu.kanade.tachiyomi.data.download.DownloadService
|
import eu.kanade.tachiyomi.data.download.DownloadService
|
||||||
import eu.kanade.tachiyomi.data.library.LibraryUpdateService.Companion.start
|
import eu.kanade.tachiyomi.data.library.LibraryUpdateService.Companion.start
|
||||||
@ -73,7 +72,6 @@ import java.util.Date
|
|||||||
import java.util.concurrent.CopyOnWriteArrayList
|
import java.util.concurrent.CopyOnWriteArrayList
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
import java.util.concurrent.atomic.AtomicInteger
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
import eu.kanade.domain.chapter.model.Chapter as DomainChapter
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class will take care of updating the chapters of the manga from the library. It can be
|
* This class will take care of updating the chapters of the manga from the library. It can be
|
||||||
@ -191,8 +189,6 @@ class LibraryUpdateService(
|
|||||||
*/
|
*/
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
updateJob?.cancel()
|
updateJob?.cancel()
|
||||||
// Despite what Android Studio
|
|
||||||
// states this can be null
|
|
||||||
ioScope?.cancel()
|
ioScope?.cancel()
|
||||||
if (wakeLock.isHeld) {
|
if (wakeLock.isHeld) {
|
||||||
wakeLock.release()
|
wakeLock.release()
|
||||||
@ -254,6 +250,9 @@ class LibraryUpdateService(
|
|||||||
return START_REDELIVER_INTENT
|
return START_REDELIVER_INTENT
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val isUpdateJobActive: Boolean
|
||||||
|
get() = (updateJob?.isActive == true)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds list of manga to be updated.
|
* Adds list of manga to be updated.
|
||||||
*
|
*
|
||||||
@ -266,24 +265,25 @@ class LibraryUpdateService(
|
|||||||
libraryManga.filter { it.category == categoryId }
|
libraryManga.filter { it.category == categoryId }
|
||||||
} else {
|
} else {
|
||||||
val categoriesToUpdate = libraryPreferences.libraryUpdateCategories().get().map { it.toLong() }
|
val categoriesToUpdate = libraryPreferences.libraryUpdateCategories().get().map { it.toLong() }
|
||||||
val listToInclude = if (categoriesToUpdate.isNotEmpty()) {
|
val includedManga = if (categoriesToUpdate.isNotEmpty()) {
|
||||||
libraryManga.filter { it.category in categoriesToUpdate }
|
libraryManga.filter { it.category in categoriesToUpdate }
|
||||||
} else {
|
} else {
|
||||||
libraryManga
|
libraryManga
|
||||||
}
|
}
|
||||||
|
|
||||||
val categoriesToExclude = libraryPreferences.libraryUpdateCategoriesExclude().get().map { it.toLong() }
|
val categoriesToExclude = libraryPreferences.libraryUpdateCategoriesExclude().get().map { it.toLong() }
|
||||||
val listToExclude = if (categoriesToExclude.isNotEmpty()) {
|
val excludedMangaIds = if (categoriesToExclude.isNotEmpty()) {
|
||||||
libraryManga.filter { it.category in categoriesToExclude }
|
libraryManga.filter { it.category in categoriesToExclude }.map { it.manga.id }
|
||||||
} else {
|
} else {
|
||||||
emptyList()
|
emptyList()
|
||||||
}
|
}
|
||||||
|
|
||||||
listToInclude.minus(listToExclude)
|
includedManga
|
||||||
|
.filterNot { it.manga.id in excludedMangaIds }
|
||||||
|
.distinctBy { it.manga.id }
|
||||||
}
|
}
|
||||||
|
|
||||||
mangaToUpdate = listToUpdate
|
mangaToUpdate = listToUpdate
|
||||||
.distinctBy { it.manga.id }
|
|
||||||
.sortedBy { it.manga.title }
|
.sortedBy { it.manga.title }
|
||||||
|
|
||||||
// Warn when excessively checking a single source
|
// Warn when excessively checking a single source
|
||||||
@ -308,7 +308,7 @@ class LibraryUpdateService(
|
|||||||
val semaphore = Semaphore(5)
|
val semaphore = Semaphore(5)
|
||||||
val progressCount = AtomicInteger(0)
|
val progressCount = AtomicInteger(0)
|
||||||
val currentlyUpdatingManga = CopyOnWriteArrayList<Manga>()
|
val currentlyUpdatingManga = CopyOnWriteArrayList<Manga>()
|
||||||
val newUpdates = CopyOnWriteArrayList<Pair<Manga, Array<DomainChapter>>>()
|
val newUpdates = CopyOnWriteArrayList<Pair<Manga, Array<Chapter>>>()
|
||||||
val skippedUpdates = CopyOnWriteArrayList<Pair<Manga, String?>>()
|
val skippedUpdates = CopyOnWriteArrayList<Pair<Manga, String?>>()
|
||||||
val failedUpdates = CopyOnWriteArrayList<Pair<Manga, String?>>()
|
val failedUpdates = CopyOnWriteArrayList<Pair<Manga, String?>>()
|
||||||
val hasDownloads = AtomicBoolean(false)
|
val hasDownloads = AtomicBoolean(false)
|
||||||
@ -317,26 +317,27 @@ class LibraryUpdateService(
|
|||||||
val restrictions = libraryPreferences.libraryUpdateMangaRestriction().get()
|
val restrictions = libraryPreferences.libraryUpdateMangaRestriction().get()
|
||||||
|
|
||||||
withIOContext {
|
withIOContext {
|
||||||
mangaToUpdate.groupBy { it.manga.source }
|
mangaToUpdate.groupBy { it.manga.source }.values
|
||||||
.values
|
|
||||||
.map { mangaInSource ->
|
.map { mangaInSource ->
|
||||||
async {
|
async {
|
||||||
semaphore.withPermit {
|
semaphore.withPermit {
|
||||||
mangaInSource.forEach { libraryManga ->
|
mangaInSource.forEach { libraryManga ->
|
||||||
val manga = libraryManga.manga
|
val manga = libraryManga.manga
|
||||||
if (updateJob?.isActive != true) {
|
if (!isUpdateJobActive) {
|
||||||
|
notifier.cancelProgressNotification()
|
||||||
return@async
|
return@async
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't continue to update if manga is not in library
|
// Don't continue to update if manga is not in library
|
||||||
manga.id.let { getManga.await(it) } ?: return@forEach
|
if (getManga.await(manga.id)?.favorite != true) {
|
||||||
|
return@forEach
|
||||||
|
}
|
||||||
|
|
||||||
withUpdateNotification(
|
withUpdateNotification(
|
||||||
currentlyUpdatingManga,
|
currentlyUpdatingManga,
|
||||||
progressCount,
|
progressCount,
|
||||||
manga,
|
manga,
|
||||||
) {
|
) {
|
||||||
try {
|
|
||||||
when {
|
when {
|
||||||
MANGA_NON_COMPLETED in restrictions && manga.status.toInt() == SManga.COMPLETED ->
|
MANGA_NON_COMPLETED in restrictions && manga.status.toInt() == SManga.COMPLETED ->
|
||||||
skippedUpdates.add(manga to getString(R.string.skipped_reason_completed))
|
skippedUpdates.add(manga to getString(R.string.skipped_reason_completed))
|
||||||
@ -351,26 +352,19 @@ class LibraryUpdateService(
|
|||||||
skippedUpdates.add(manga to getString(R.string.skipped_reason_not_always_update))
|
skippedUpdates.add(manga to getString(R.string.skipped_reason_not_always_update))
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
|
try {
|
||||||
val newChapters = updateManga(manga)
|
val newChapters = updateManga(manga)
|
||||||
val newDbChapters = newChapters.map { it.toDbChapter() }
|
.sortedByDescending { it.sourceOrder }
|
||||||
|
|
||||||
if (newChapters.isNotEmpty()) {
|
if (newChapters.isNotEmpty()) {
|
||||||
val categoryIds = getCategories.await(manga.id).map { it.id }
|
val categoryIds = getCategories.await(manga.id).map { it.id }
|
||||||
if (manga.shouldDownloadNewChapters(categoryIds, downloadPreferences)) {
|
if (manga.shouldDownloadNewChapters(categoryIds, downloadPreferences)) {
|
||||||
downloadChapters(manga, newDbChapters)
|
downloadChapters(manga, newChapters)
|
||||||
hasDownloads.set(true)
|
hasDownloads.set(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert to the manga that contains new chapters
|
// Convert to the manga that contains new chapters
|
||||||
newUpdates.add(
|
newUpdates.add(manga to newChapters.toTypedArray())
|
||||||
manga to
|
|
||||||
newDbChapters
|
|
||||||
.map { it.toDomainChapter()!! }
|
|
||||||
.sortedByDescending { it.sourceOrder }
|
|
||||||
.toTypedArray(),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
val errorMessage = when (e) {
|
val errorMessage = when (e) {
|
||||||
@ -381,6 +375,8 @@ class LibraryUpdateService(
|
|||||||
}
|
}
|
||||||
failedUpdates.add(manga to errorMessage)
|
failedUpdates.add(manga to errorMessage)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (libraryPreferences.autoUpdateTrackers().get()) {
|
if (libraryPreferences.autoUpdateTrackers().get()) {
|
||||||
updateTrackings(manga, loggedServices)
|
updateTrackings(manga, loggedServices)
|
||||||
@ -419,7 +415,8 @@ class LibraryUpdateService(
|
|||||||
private fun downloadChapters(manga: Manga, chapters: List<Chapter>) {
|
private fun downloadChapters(manga: Manga, chapters: List<Chapter>) {
|
||||||
// We don't want to start downloading while the library is updating, because websites
|
// We don't want to start downloading while the library is updating, because websites
|
||||||
// may don't like it and they could ban the user.
|
// may don't like it and they could ban the user.
|
||||||
downloadManager.downloadChapters(manga, chapters, false)
|
val dbChapters = chapters.map { it.toDbChapter() }
|
||||||
|
downloadManager.downloadChapters(manga, dbChapters, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -428,7 +425,7 @@ class LibraryUpdateService(
|
|||||||
* @param manga the manga to update.
|
* @param manga the manga to update.
|
||||||
* @return a pair of the inserted and removed chapters.
|
* @return a pair of the inserted and removed chapters.
|
||||||
*/
|
*/
|
||||||
private suspend fun updateManga(manga: Manga): List<DomainChapter> {
|
private suspend fun updateManga(manga: Manga): List<Chapter> {
|
||||||
val source = sourceManager.getOrStub(manga.source)
|
val source = sourceManager.getOrStub(manga.source)
|
||||||
|
|
||||||
// Update manga metadata if needed
|
// Update manga metadata if needed
|
||||||
@ -439,12 +436,10 @@ class LibraryUpdateService(
|
|||||||
|
|
||||||
val chapters = source.getChapterList(manga.toSManga())
|
val chapters = source.getChapterList(manga.toSManga())
|
||||||
|
|
||||||
// Get manga from database to account for if it was removed during the update
|
// Get manga from database to account for if it was removed during the update and
|
||||||
val dbManga = getManga.await(manga.id)
|
// to get latest data so it doesn't get overwritten later on
|
||||||
?: return emptyList()
|
val dbManga = getManga.await(manga.id)?.takeIf { it.favorite } ?: return emptyList()
|
||||||
|
|
||||||
// [dbmanga] was used so that manga data doesn't get overwritten
|
|
||||||
// in case manga gets new chapter
|
|
||||||
return syncChaptersWithSource.await(chapters, dbManga, source)
|
return syncChaptersWithSource.await(chapters, dbManga, source)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,7 +456,8 @@ class LibraryUpdateService(
|
|||||||
semaphore.withPermit {
|
semaphore.withPermit {
|
||||||
mangaInSource.forEach { libraryManga ->
|
mangaInSource.forEach { libraryManga ->
|
||||||
val manga = libraryManga.manga
|
val manga = libraryManga.manga
|
||||||
if (updateJob?.isActive != true) {
|
if (!isUpdateJobActive) {
|
||||||
|
notifier.cancelProgressNotification()
|
||||||
return@async
|
return@async
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -505,7 +501,8 @@ class LibraryUpdateService(
|
|||||||
|
|
||||||
mangaToUpdate.forEach { libraryManga ->
|
mangaToUpdate.forEach { libraryManga ->
|
||||||
val manga = libraryManga.manga
|
val manga = libraryManga.manga
|
||||||
if (updateJob?.isActive != true) {
|
if (!isUpdateJobActive) {
|
||||||
|
notifier.cancelProgressNotification()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -550,7 +547,8 @@ class LibraryUpdateService(
|
|||||||
manga: Manga,
|
manga: Manga,
|
||||||
block: suspend () -> Unit,
|
block: suspend () -> Unit,
|
||||||
) {
|
) {
|
||||||
if (updateJob?.isActive != true) {
|
if (!isUpdateJobActive) {
|
||||||
|
notifier.cancelProgressNotification()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -563,7 +561,8 @@ class LibraryUpdateService(
|
|||||||
|
|
||||||
block()
|
block()
|
||||||
|
|
||||||
if (updateJob?.isActive != true) {
|
if (!isUpdateJobActive) {
|
||||||
|
notifier.cancelProgressNotification()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -602,9 +601,7 @@ class LibraryUpdateService(
|
|||||||
}
|
}
|
||||||
return file
|
return file
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (_: Exception) {}
|
||||||
// Empty
|
|
||||||
}
|
|
||||||
return File("")
|
return File("")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user