Fix multiple issues with the E-Hentai updater
This commit is contained in:
parent
d88f570f65
commit
f0b621dfe5
@ -31,7 +31,7 @@ android {
|
|||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId = "eu.kanade.tachiyomi.sy"
|
applicationId = "eu.kanade.tachiyomi.sy"
|
||||||
|
|
||||||
versionCode = 70
|
versionCode = 71
|
||||||
versionName = "1.11.0"
|
versionName = "1.11.0"
|
||||||
|
|
||||||
buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"")
|
buildConfigField("String", "COMMIT_COUNT", "\"${getCommitCount()}\"")
|
||||||
|
@ -30,6 +30,9 @@ object Notifications {
|
|||||||
const val ID_LIBRARY_SIZE_WARNING = -103
|
const val ID_LIBRARY_SIZE_WARNING = -103
|
||||||
const val CHANNEL_LIBRARY_ERROR = "library_errors_channel"
|
const val CHANNEL_LIBRARY_ERROR = "library_errors_channel"
|
||||||
const val ID_LIBRARY_ERROR = -102
|
const val ID_LIBRARY_ERROR = -102
|
||||||
|
const val CHANNEL_LIBRARY_EHENTAI = "library_ehentai_channel"
|
||||||
|
const val ID_EHENTAI_PROGRESS = -199
|
||||||
|
const val ID_EHENTAI_ERROR = -198
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Notification channel and ids used by the downloader.
|
* Notification channel and ids used by the downloader.
|
||||||
@ -166,6 +169,13 @@ object Notifications {
|
|||||||
setGroup(GROUP_APK_UPDATES)
|
setGroup(GROUP_APK_UPDATES)
|
||||||
setName(context.stringResource(MR.strings.channel_ext_updates))
|
setName(context.stringResource(MR.strings.channel_ext_updates))
|
||||||
},
|
},
|
||||||
|
// SY -->
|
||||||
|
buildNotificationChannel(CHANNEL_LIBRARY_EHENTAI, IMPORTANCE_LOW) {
|
||||||
|
setName("EHentai")
|
||||||
|
setGroup(GROUP_LIBRARY)
|
||||||
|
setShowBadge(false)
|
||||||
|
},
|
||||||
|
//SY <--
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
109
app/src/main/java/exh/eh/EHentaiUpdateNotifier.kt
Normal file
109
app/src/main/java/exh/eh/EHentaiUpdateNotifier.kt
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
package exh.eh
|
||||||
|
|
||||||
|
import android.content.Context
|
||||||
|
import android.graphics.BitmapFactory
|
||||||
|
import android.net.Uri
|
||||||
|
import androidx.core.app.NotificationCompat
|
||||||
|
import eu.kanade.tachiyomi.R
|
||||||
|
import eu.kanade.tachiyomi.core.security.SecurityPreferences
|
||||||
|
import eu.kanade.tachiyomi.data.notification.NotificationReceiver
|
||||||
|
import eu.kanade.tachiyomi.data.notification.Notifications
|
||||||
|
import eu.kanade.tachiyomi.util.lang.chop
|
||||||
|
import eu.kanade.tachiyomi.util.system.cancelNotification
|
||||||
|
import eu.kanade.tachiyomi.util.system.notificationBuilder
|
||||||
|
import eu.kanade.tachiyomi.util.system.notify
|
||||||
|
import tachiyomi.core.common.i18n.stringResource
|
||||||
|
import tachiyomi.domain.manga.model.Manga
|
||||||
|
import tachiyomi.i18n.MR
|
||||||
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
import java.math.RoundingMode
|
||||||
|
import java.text.NumberFormat
|
||||||
|
|
||||||
|
class EHentaiUpdateNotifier(private val context: Context) {
|
||||||
|
|
||||||
|
private val securityPreferences: SecurityPreferences by injectLazy()
|
||||||
|
|
||||||
|
private val percentFormatter = NumberFormat.getPercentInstance().apply {
|
||||||
|
roundingMode = RoundingMode.DOWN
|
||||||
|
maximumFractionDigits = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bitmap of the app for notifications.
|
||||||
|
*/
|
||||||
|
private val notificationBitmap by lazy {
|
||||||
|
BitmapFactory.decodeResource(context.resources, R.mipmap.ic_launcher)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cached progress notification to avoid creating a lot.
|
||||||
|
*/
|
||||||
|
val progressNotificationBuilder by lazy {
|
||||||
|
context.notificationBuilder(Notifications.CHANNEL_LIBRARY_EHENTAI) {
|
||||||
|
setContentTitle(context.stringResource(MR.strings.app_name))
|
||||||
|
setSmallIcon(R.drawable.ic_refresh_24dp)
|
||||||
|
setLargeIcon(notificationBitmap)
|
||||||
|
setOngoing(true)
|
||||||
|
setOnlyAlertOnce(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows the notification containing the currently updating manga and the progress.
|
||||||
|
*
|
||||||
|
* @param manga the manga that are being updated.
|
||||||
|
* @param current the current progress.
|
||||||
|
* @param total the total progress.
|
||||||
|
*/
|
||||||
|
fun showProgressNotification(manga: Manga, current: Int, total: Int) {
|
||||||
|
progressNotificationBuilder
|
||||||
|
.setContentTitle(
|
||||||
|
context.stringResource(
|
||||||
|
MR.strings.notification_updating_progress,
|
||||||
|
percentFormatter.format(current.toFloat() / total),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
if (!securityPreferences.hideNotificationContent().get()) {
|
||||||
|
val updatingText = manga.title.chop(40)
|
||||||
|
progressNotificationBuilder.setStyle(NotificationCompat.BigTextStyle().bigText(updatingText))
|
||||||
|
}
|
||||||
|
|
||||||
|
context.notify(
|
||||||
|
Notifications.ID_EHENTAI_PROGRESS,
|
||||||
|
progressNotificationBuilder
|
||||||
|
.setProgress(total, current, false)
|
||||||
|
.build(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows notification containing update entries that failed with action to open full log.
|
||||||
|
*
|
||||||
|
* @param failed Number of entries that failed to update.
|
||||||
|
* @param uri Uri for error log file containing all titles that failed.
|
||||||
|
*/
|
||||||
|
fun showUpdateErrorNotification(failed: Int, uri: Uri) {
|
||||||
|
if (failed == 0) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
context.notify(
|
||||||
|
Notifications.ID_EHENTAI_ERROR,
|
||||||
|
Notifications.CHANNEL_LIBRARY_EHENTAI,
|
||||||
|
) {
|
||||||
|
setContentTitle(context.stringResource(MR.strings.notification_update_error, failed))
|
||||||
|
setContentText(context.stringResource(MR.strings.action_show_errors))
|
||||||
|
setSmallIcon(R.drawable.ic_tachi)
|
||||||
|
|
||||||
|
setContentIntent(NotificationReceiver.openErrorLogPendingActivity(context, uri))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cancels the progress notification.
|
||||||
|
*/
|
||||||
|
fun cancelProgressNotification() {
|
||||||
|
context.cancelNotification(Notifications.ID_EHENTAI_PROGRESS)
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,15 @@
|
|||||||
package exh.eh
|
package exh.eh
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import android.content.pm.ServiceInfo
|
||||||
|
import android.os.Build
|
||||||
import androidx.work.Constraints
|
import androidx.work.Constraints
|
||||||
import androidx.work.CoroutineWorker
|
import androidx.work.CoroutineWorker
|
||||||
import androidx.work.ExistingPeriodicWorkPolicy
|
import androidx.work.ExistingPeriodicWorkPolicy
|
||||||
|
import androidx.work.ForegroundInfo
|
||||||
import androidx.work.NetworkType
|
import androidx.work.NetworkType
|
||||||
import androidx.work.OneTimeWorkRequestBuilder
|
import androidx.work.OneTimeWorkRequestBuilder
|
||||||
|
import androidx.work.OutOfQuotaPolicy
|
||||||
import androidx.work.PeriodicWorkRequestBuilder
|
import androidx.work.PeriodicWorkRequestBuilder
|
||||||
import androidx.work.WorkerParameters
|
import androidx.work.WorkerParameters
|
||||||
import com.elvishew.xlog.Logger
|
import com.elvishew.xlog.Logger
|
||||||
@ -14,8 +18,10 @@ import eu.kanade.domain.chapter.interactor.SyncChaptersWithSource
|
|||||||
import eu.kanade.domain.manga.interactor.UpdateManga
|
import eu.kanade.domain.manga.interactor.UpdateManga
|
||||||
import eu.kanade.domain.manga.model.toSManga
|
import eu.kanade.domain.manga.model.toSManga
|
||||||
import eu.kanade.tachiyomi.data.library.LibraryUpdateNotifier
|
import eu.kanade.tachiyomi.data.library.LibraryUpdateNotifier
|
||||||
|
import eu.kanade.tachiyomi.data.notification.Notifications
|
||||||
import eu.kanade.tachiyomi.source.online.all.EHentai
|
import eu.kanade.tachiyomi.source.online.all.EHentai
|
||||||
import eu.kanade.tachiyomi.util.system.isConnectedToWifi
|
import eu.kanade.tachiyomi.util.system.isConnectedToWifi
|
||||||
|
import eu.kanade.tachiyomi.util.system.setForegroundSafely
|
||||||
import eu.kanade.tachiyomi.util.system.workManager
|
import eu.kanade.tachiyomi.util.system.workManager
|
||||||
import exh.debug.DebugToggles
|
import exh.debug.DebugToggles
|
||||||
import exh.eh.EHentaiUpdateWorkerConstants.UPDATES_PER_ITERATION
|
import exh.eh.EHentaiUpdateWorkerConstants.UPDATES_PER_ITERATION
|
||||||
@ -48,7 +54,7 @@ class EHentaiUpdateWorker(private val context: Context, workerParams: WorkerPara
|
|||||||
private val preferences: UnsortedPreferences by injectLazy()
|
private val preferences: UnsortedPreferences by injectLazy()
|
||||||
private val sourceManager: SourceManager by injectLazy()
|
private val sourceManager: SourceManager by injectLazy()
|
||||||
private val updateHelper: EHentaiUpdateHelper by injectLazy()
|
private val updateHelper: EHentaiUpdateHelper by injectLazy()
|
||||||
private val logger: Logger = xLog()
|
private val logger: Logger by lazy { xLog() }
|
||||||
private val updateManga: UpdateManga by injectLazy()
|
private val updateManga: UpdateManga by injectLazy()
|
||||||
private val syncChaptersWithSource: SyncChaptersWithSource by injectLazy()
|
private val syncChaptersWithSource: SyncChaptersWithSource by injectLazy()
|
||||||
private val getChaptersByMangaId: GetChaptersByMangaId by injectLazy()
|
private val getChaptersByMangaId: GetChaptersByMangaId by injectLazy()
|
||||||
@ -56,22 +62,38 @@ class EHentaiUpdateWorker(private val context: Context, workerParams: WorkerPara
|
|||||||
private val insertFlatMetadata: InsertFlatMetadata by injectLazy()
|
private val insertFlatMetadata: InsertFlatMetadata by injectLazy()
|
||||||
private val getExhFavoriteMangaWithMetadata: GetExhFavoriteMangaWithMetadata by injectLazy()
|
private val getExhFavoriteMangaWithMetadata: GetExhFavoriteMangaWithMetadata by injectLazy()
|
||||||
|
|
||||||
private val updateNotifier by lazy { LibraryUpdateNotifier(context) }
|
private val updateNotifier by lazy { EHentaiUpdateNotifier(context) }
|
||||||
|
private val libraryUpdateNotifier by lazy { LibraryUpdateNotifier(context) }
|
||||||
|
|
||||||
override suspend fun doWork(): Result {
|
override suspend fun doWork(): Result {
|
||||||
return try {
|
return try {
|
||||||
if (requiresWifiConnection(preferences) && !context.isConnectedToWifi()) {
|
if (requiresWifiConnection(preferences) && !context.isConnectedToWifi()) {
|
||||||
Result.success() // retry again later
|
Result.success() // retry again later
|
||||||
} else {
|
} else {
|
||||||
|
setForegroundSafely()
|
||||||
startUpdating()
|
startUpdating()
|
||||||
logger.d("Update job completed!")
|
logger.d("Update job completed!")
|
||||||
Result.success()
|
Result.success()
|
||||||
}
|
}
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
Result.success() // retry again later
|
Result.success() // retry again later
|
||||||
|
} finally {
|
||||||
|
updateNotifier.cancelProgressNotification()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override suspend fun getForegroundInfo(): ForegroundInfo {
|
||||||
|
return ForegroundInfo(
|
||||||
|
Notifications.ID_EHENTAI_PROGRESS,
|
||||||
|
updateNotifier.progressNotificationBuilder.build(),
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
},
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private suspend fun startUpdating() {
|
private suspend fun startUpdating() {
|
||||||
logger.d("Update job started!")
|
logger.d("Update job started!")
|
||||||
val startTime = System.currentTimeMillis()
|
val startTime = System.currentTimeMillis()
|
||||||
@ -138,6 +160,11 @@ class EHentaiUpdateWorker(private val context: Context, workerParams: WorkerPara
|
|||||||
}
|
}
|
||||||
|
|
||||||
val (new, chapters) = try {
|
val (new, chapters) = try {
|
||||||
|
updateNotifier.showProgressNotification(
|
||||||
|
manga,
|
||||||
|
updatedThisIteration + failuresThisIteration,
|
||||||
|
mangaMetaToUpdateThisIter.size,
|
||||||
|
)
|
||||||
updateEntryAndGetChapters(manga)
|
updateEntryAndGetChapters(manga)
|
||||||
} catch (e: GalleryNotUpdatedException) {
|
} catch (e: GalleryNotUpdatedException) {
|
||||||
if (e.network) {
|
if (e.network) {
|
||||||
@ -193,8 +220,9 @@ class EHentaiUpdateWorker(private val context: Context, workerParams: WorkerPara
|
|||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
updateNotifier.cancelProgressNotification()
|
||||||
if (updatedManga.isNotEmpty()) {
|
if (updatedManga.isNotEmpty()) {
|
||||||
updateNotifier.showUpdateNotifications(updatedManga)
|
libraryUpdateNotifier.showUpdateNotifications(updatedManga)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -237,7 +265,11 @@ class EHentaiUpdateWorker(private val context: Context, workerParams: WorkerPara
|
|||||||
private val logger by lazy { XLog.tag("EHUpdaterScheduler") }
|
private val logger by lazy { XLog.tag("EHUpdaterScheduler") }
|
||||||
|
|
||||||
fun launchBackgroundTest(context: Context) {
|
fun launchBackgroundTest(context: Context) {
|
||||||
context.workManager.enqueue(OneTimeWorkRequestBuilder<EHentaiUpdateWorker>().build())
|
context.workManager.enqueue(
|
||||||
|
OneTimeWorkRequestBuilder<EHentaiUpdateWorker>()
|
||||||
|
.setExpedited(OutOfQuotaPolicy.RUN_AS_NON_EXPEDITED_WORK_REQUEST)
|
||||||
|
.build(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun scheduleBackground(context: Context, prefInterval: Int? = null, prefRestrictions: Set<String>? = null) {
|
fun scheduleBackground(context: Context, prefInterval: Int? = null, prefRestrictions: Set<String>? = null) {
|
||||||
|
@ -445,7 +445,7 @@ class FavoritesSyncHelper(val context: Context) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sealed class FavoritesSyncStatus() {
|
sealed class FavoritesSyncStatus {
|
||||||
abstract val message: String
|
abstract val message: String
|
||||||
|
|
||||||
data class Error(override val message: String) : FavoritesSyncStatus()
|
data class Error(override val message: String) : FavoritesSyncStatus()
|
||||||
|
@ -24,6 +24,6 @@ enum class MangaDexRelation(val res: StringResource, val mdString: String?) {
|
|||||||
;
|
;
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun fromDex(mdString: String) = values().find { it.mdString == mdString }
|
fun fromDex(mdString: String) = entries.find { it.mdString == mdString }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user