Fix removing manga from library reverts during global update (#7063)

* Fix removing manga from library reverts during global update

* Review Changes

* Review changes 2
This commit is contained in:
FourTOne5 2022-05-07 08:15:44 +06:00 committed by GitHub
parent 49d3ddb830
commit c4088bad12
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 46 additions and 30 deletions

View File

@ -174,6 +174,8 @@ 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()
@ -233,8 +235,7 @@ class LibraryUpdateService(
/** /**
* Adds list of manga to be updated. * Adds list of manga to be updated.
* *
* @param category the ID of the category to update, or -1 if no category specified. * @param categoryId the ID of the category to update, or -1 if no category specified.
* @param target the target to update.
*/ */
fun addMangaToQueue(categoryId: Int) { fun addMangaToQueue(categoryId: Int) {
val libraryManga = db.getLibraryMangas().executeAsBlocking() val libraryManga = db.getLibraryMangas().executeAsBlocking()
@ -274,12 +275,11 @@ class LibraryUpdateService(
} }
/** /**
* Method that updates the given list of manga. It's called in a background thread, so it's safe * Method that updates manga in [mangaToUpdate]. It's called in a background thread, so it's safe
* to do heavy operations or network calls here. * to do heavy operations or network calls here.
* For each manga it calls [updateManga] and updates the notification showing the current * For each manga it calls [updateManga] and updates the notification showing the current
* progress. * progress.
* *
* @param mangaToUpdate the list to update
* @return an observable delivering the progress of each update. * @return an observable delivering the progress of each update.
*/ */
private suspend fun updateChapterList() { private suspend fun updateChapterList() {
@ -305,35 +305,38 @@ class LibraryUpdateService(
return@async return@async
} }
// Don't continue to update if manga not in library
db.getManga(manga.id!!).executeAsBlocking() ?: return@forEach
withUpdateNotification( withUpdateNotification(
currentlyUpdatingManga, currentlyUpdatingManga,
progressCount, progressCount,
manga, manga,
) { manga -> ) { mangaWithNotif ->
try { try {
when { when {
MANGA_NON_COMPLETED in restrictions && manga.status == SManga.COMPLETED -> { MANGA_NON_COMPLETED in restrictions && mangaWithNotif.status == SManga.COMPLETED ->
skippedUpdates.add(manga to getString(R.string.skipped_reason_completed)) skippedUpdates.add(mangaWithNotif to getString(R.string.skipped_reason_completed))
}
MANGA_HAS_UNREAD in restrictions && manga.unreadCount != 0 -> { MANGA_HAS_UNREAD in restrictions && mangaWithNotif.unreadCount != 0 ->
skippedUpdates.add(manga to getString(R.string.skipped_reason_not_caught_up)) skippedUpdates.add(mangaWithNotif to getString(R.string.skipped_reason_not_caught_up))
}
MANGA_NON_READ in restrictions && manga.totalChapters > 0 && !manga.hasStarted -> { MANGA_NON_READ in restrictions && mangaWithNotif.totalChapters > 0 && !mangaWithNotif.hasStarted ->
skippedUpdates.add(manga to getString(R.string.skipped_reason_not_started)) skippedUpdates.add(mangaWithNotif to getString(R.string.skipped_reason_not_started))
}
else -> { else -> {
// Convert to the manga that contains new chapters // Convert to the manga that contains new chapters
val (newChapters, _) = updateManga(manga) val (newChapters, _) = updateManga(mangaWithNotif)
if (newChapters.isNotEmpty()) { if (newChapters.isNotEmpty()) {
if (manga.shouldDownloadNewChapters(db, preferences)) { if (mangaWithNotif.shouldDownloadNewChapters(db, preferences)) {
downloadChapters(manga, newChapters) downloadChapters(mangaWithNotif, 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.sortedByDescending { ch -> ch.source_order } mangaWithNotif to newChapters.sortedByDescending { ch -> ch.source_order }
.toTypedArray(), .toTypedArray(),
) )
} }
@ -352,11 +355,11 @@ class LibraryUpdateService(
e.message e.message
} }
} }
failedUpdates.add(manga to errorMessage) failedUpdates.add(mangaWithNotif to errorMessage)
} }
if (preferences.autoUpdateTrackers()) { if (preferences.autoUpdateTrackers()) {
updateTrackings(manga, loggedServices) updateTrackings(mangaWithNotif, loggedServices)
} }
} }
} }
@ -404,6 +407,7 @@ class LibraryUpdateService(
private suspend fun updateManga(manga: Manga): Pair<List<Chapter>, List<Chapter>> { private suspend fun updateManga(manga: Manga): Pair<List<Chapter>, List<Chapter>> {
val source = sourceManager.getOrStub(manga.source) val source = sourceManager.getOrStub(manga.source)
var networkSManga: SManga? = null
// Update manga details metadata // Update manga details metadata
if (preferences.autoUpdateMetadata()) { if (preferences.autoUpdateMetadata()) {
val updatedManga = source.getMangaDetails(manga.toMangaInfo()) val updatedManga = source.getMangaDetails(manga.toMangaInfo())
@ -415,14 +419,26 @@ class LibraryUpdateService(
sManga.thumbnail_url = manga.thumbnail_url sManga.thumbnail_url = manga.thumbnail_url
} }
manga.copyFrom(sManga) networkSManga = sManga
db.insertManga(manga).executeAsBlocking()
} }
val chapters = source.getChapterList(manga.toMangaInfo()) val chapters = source.getChapterList(manga.toMangaInfo())
.map { it.toSChapter() } .map { it.toSChapter() }
return syncChaptersWithSource(db, chapters, manga, source) // Get manga from database to account for if it was removed
// from library or database
val dbManga = db.getManga(manga.id!!).executeAsBlocking()
?: return Pair(emptyList(), emptyList())
// Copy into [dbManga] to retain favourite value
networkSManga?.let {
dbManga.copyFrom(it)
db.insertManga(dbManga).executeAsBlocking()
}
// [dbmanga] was used so that manga data doesn't get overwritten
// incase manga gets new chapter
return syncChaptersWithSource(db, chapters, dbManga, source)
} }
private suspend fun updateCovers() { private suspend fun updateCovers() {
@ -445,16 +461,16 @@ class LibraryUpdateService(
currentlyUpdatingManga, currentlyUpdatingManga,
progressCount, progressCount,
manga, manga,
) { manga -> ) { mangaWithNotif ->
sourceManager.get(manga.source)?.let { source -> sourceManager.get(mangaWithNotif.source)?.let { source ->
try { try {
val networkManga = val networkManga =
source.getMangaDetails(manga.toMangaInfo()) source.getMangaDetails(mangaWithNotif.toMangaInfo())
val sManga = networkManga.toSManga() val sManga = networkManga.toSManga()
manga.prepUpdateCover(coverCache, sManga, true) mangaWithNotif.prepUpdateCover(coverCache, sManga, true)
sManga.thumbnail_url?.let { sManga.thumbnail_url?.let {
manga.thumbnail_url = it mangaWithNotif.thumbnail_url = it
db.insertManga(manga).executeAsBlocking() db.insertManga(mangaWithNotif).executeAsBlocking()
} }
} catch (e: Throwable) { } catch (e: Throwable) {
// Ignore errors and continue // Ignore errors and continue

View File

@ -25,7 +25,7 @@ fun syncChaptersWithSource(
db: DatabaseHelper, db: DatabaseHelper,
rawSourceChapters: List<SChapter>, rawSourceChapters: List<SChapter>,
manga: Manga, manga: Manga,
source: Source, source: Source
): Pair<List<Chapter>, List<Chapter>> { ): Pair<List<Chapter>, List<Chapter>> {
if (rawSourceChapters.isEmpty()) { if (rawSourceChapters.isEmpty()) {
throw NoChaptersException() throw NoChaptersException()