Show notification with error log on update failures
This commit is contained in:
parent
ccc198e081
commit
fc4e290c49
@ -6,6 +6,7 @@ import android.content.Context
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.BitmapFactory
|
import android.graphics.BitmapFactory
|
||||||
|
import android.net.Uri
|
||||||
import androidx.core.app.NotificationCompat
|
import androidx.core.app.NotificationCompat
|
||||||
import androidx.core.app.NotificationManagerCompat
|
import androidx.core.app.NotificationManagerCompat
|
||||||
import com.bumptech.glide.Glide
|
import com.bumptech.glide.Glide
|
||||||
@ -80,6 +81,39 @@ class LibraryUpdateNotifier(private val context: Context) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows notification containing update entries that failed with action to open full log.
|
||||||
|
*
|
||||||
|
* @param errors List of entry titles that failed to update.
|
||||||
|
* @param uri Uri for error log file containing all titles that failed.
|
||||||
|
*/
|
||||||
|
fun showUpdateErrorNotification(errors: List<String>, uri: Uri) {
|
||||||
|
if (errors.isEmpty()) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
context.notificationManager.notify(
|
||||||
|
Notifications.ID_LIBRARY_ERROR,
|
||||||
|
context.notificationBuilder(Notifications.CHANNEL_LIBRARY) {
|
||||||
|
setContentTitle(context.resources.getQuantityString(R.plurals.notification_update_error, errors.size, errors.size))
|
||||||
|
setStyle(
|
||||||
|
NotificationCompat.BigTextStyle().bigText(
|
||||||
|
errors.joinToString("\n") {
|
||||||
|
it.chop(NOTIF_TITLE_MAX_LEN)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
)
|
||||||
|
setSmallIcon(R.drawable.ic_tachi)
|
||||||
|
addAction(
|
||||||
|
R.drawable.nnf_ic_file_folder,
|
||||||
|
context.getString(R.string.action_open_log),
|
||||||
|
NotificationReceiver.openErrorLogPendingActivity(context, uri)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
.build()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Shows the notification containing the result of the update done by the service.
|
* Shows the notification containing the result of the update done by the service.
|
||||||
*
|
*
|
||||||
|
@ -23,8 +23,10 @@ import eu.kanade.tachiyomi.source.SourceManager
|
|||||||
import eu.kanade.tachiyomi.source.model.SManga
|
import eu.kanade.tachiyomi.source.model.SManga
|
||||||
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
import eu.kanade.tachiyomi.util.chapter.syncChaptersWithSource
|
||||||
import eu.kanade.tachiyomi.util.prepUpdateCover
|
import eu.kanade.tachiyomi.util.prepUpdateCover
|
||||||
|
import eu.kanade.tachiyomi.util.storage.getUriCompat
|
||||||
import eu.kanade.tachiyomi.util.system.acquireWakeLock
|
import eu.kanade.tachiyomi.util.system.acquireWakeLock
|
||||||
import eu.kanade.tachiyomi.util.system.isServiceRunning
|
import eu.kanade.tachiyomi.util.system.isServiceRunning
|
||||||
|
import java.io.File
|
||||||
import java.util.ArrayList
|
import java.util.ArrayList
|
||||||
import java.util.concurrent.atomic.AtomicInteger
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
@ -253,7 +255,7 @@ class LibraryUpdateService(
|
|||||||
// List containing new updates
|
// List containing new updates
|
||||||
val newUpdates = ArrayList<Pair<LibraryManga, Array<Chapter>>>()
|
val newUpdates = ArrayList<Pair<LibraryManga, Array<Chapter>>>()
|
||||||
// List containing failed updates
|
// List containing failed updates
|
||||||
val failedUpdates = ArrayList<Manga>()
|
val failedUpdates = ArrayList<Pair<Manga, String?>>()
|
||||||
// List containing categories that get included in downloads.
|
// List containing categories that get included in downloads.
|
||||||
val categoriesToDownload = preferences.downloadNewCategories().get().map(String::toInt)
|
val categoriesToDownload = preferences.downloadNewCategories().get().map(String::toInt)
|
||||||
// Boolean to determine if user wants to automatically download new chapters.
|
// Boolean to determine if user wants to automatically download new chapters.
|
||||||
@ -270,7 +272,7 @@ class LibraryUpdateService(
|
|||||||
updateManga(manga)
|
updateManga(manga)
|
||||||
// If there's any error, return empty update and continue.
|
// If there's any error, return empty update and continue.
|
||||||
.onErrorReturn {
|
.onErrorReturn {
|
||||||
failedUpdates.add(manga)
|
failedUpdates.add(Pair(manga, it.message))
|
||||||
Pair(emptyList(), emptyList())
|
Pair(emptyList(), emptyList())
|
||||||
}
|
}
|
||||||
// Filter out mangas without new chapters (or failed).
|
// Filter out mangas without new chapters (or failed).
|
||||||
@ -303,6 +305,8 @@ class LibraryUpdateService(
|
|||||||
}
|
}
|
||||||
// Notify result of the overall update.
|
// Notify result of the overall update.
|
||||||
.doOnCompleted {
|
.doOnCompleted {
|
||||||
|
notifier.cancelProgressNotification()
|
||||||
|
|
||||||
if (newUpdates.isNotEmpty()) {
|
if (newUpdates.isNotEmpty()) {
|
||||||
notifier.showUpdateNotifications(newUpdates)
|
notifier.showUpdateNotifications(newUpdates)
|
||||||
if (downloadNew && hasDownloads) {
|
if (downloadNew && hasDownloads) {
|
||||||
@ -311,10 +315,12 @@ class LibraryUpdateService(
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (failedUpdates.isNotEmpty()) {
|
if (failedUpdates.isNotEmpty()) {
|
||||||
Timber.e("Failed updating: ${failedUpdates.map { it.title }}")
|
val errorFile = writeErrorFile(failedUpdates)
|
||||||
|
notifier.showUpdateErrorNotification(
|
||||||
|
failedUpdates.map { it.first.title },
|
||||||
|
errorFile.getUriCompat(this)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
notifier.cancelProgressNotification()
|
|
||||||
}
|
}
|
||||||
.map { manga -> manga.first }
|
.map { manga -> manga.first }
|
||||||
}
|
}
|
||||||
@ -417,4 +423,25 @@ class LibraryUpdateService(
|
|||||||
notifier.cancelProgressNotification()
|
notifier.cancelProgressNotification()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Writes basic file of update errors to cache dir.
|
||||||
|
*/
|
||||||
|
private fun writeErrorFile(errors: List<Pair<Manga, String?>>): File {
|
||||||
|
try {
|
||||||
|
if (errors.isNotEmpty()) {
|
||||||
|
val destFile = File(externalCacheDir, "tachiyomi_update_errors.txt")
|
||||||
|
|
||||||
|
destFile.bufferedWriter().use { out ->
|
||||||
|
errors.forEach { (manga, error) ->
|
||||||
|
out.write("${manga.title}: $error\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return destFile
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
// Empty
|
||||||
|
}
|
||||||
|
return File("")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,7 @@ object Notifications {
|
|||||||
*/
|
*/
|
||||||
const val CHANNEL_LIBRARY = "library_channel"
|
const val CHANNEL_LIBRARY = "library_channel"
|
||||||
const val ID_LIBRARY_PROGRESS = -101
|
const val ID_LIBRARY_PROGRESS = -101
|
||||||
|
const val ID_LIBRARY_ERROR = -102
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notification channel and ids used by the downloader.
|
* Notification channel and ids used by the downloader.
|
||||||
|
@ -579,6 +579,10 @@
|
|||||||
<item quantity="one">Chapters %1$s and 1 more</item>
|
<item quantity="one">Chapters %1$s and 1 more</item>
|
||||||
<item quantity="other">Chapters %1$s and %2$d more</item>
|
<item quantity="other">Chapters %1$s and %2$d more</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
|
<plurals name="notification_update_error">
|
||||||
|
<item quantity="one">1 update failed</item>
|
||||||
|
<item quantity="other">%1$d updates failed</item>
|
||||||
|
</plurals>
|
||||||
<string name="notification_cover_update_failed">Failed to update cover</string>
|
<string name="notification_cover_update_failed">Failed to update cover</string>
|
||||||
<string name="notification_first_add_to_library">Please add the manga to your library before doing this</string>
|
<string name="notification_first_add_to_library">Please add the manga to your library before doing this</string>
|
||||||
<string name="notification_not_connected_to_ac_title">Sync canceled</string>
|
<string name="notification_not_connected_to_ac_title">Sync canceled</string>
|
||||||
|
Loading…
Reference in New Issue
Block a user