Linting fixes
This commit is contained in:
@@ -14,7 +14,7 @@ import uy.kohesive.injekt.Injekt
|
||||
import uy.kohesive.injekt.api.get
|
||||
|
||||
class LibraryUpdateJob(private val context: Context, workerParams: WorkerParameters) :
|
||||
Worker(context, workerParams) {
|
||||
Worker(context, workerParams) {
|
||||
|
||||
override fun doWork(): Result {
|
||||
LibraryUpdateService.start(context)
|
||||
@@ -30,22 +30,24 @@ class LibraryUpdateJob(private val context: Context, workerParams: WorkerParamet
|
||||
if (interval > 0) {
|
||||
val restrictions = preferences.libraryUpdateRestriction()!!
|
||||
val acRestriction = "ac" in restrictions
|
||||
val wifiRestriction = if ("wifi" in restrictions)
|
||||
val wifiRestriction = if ("wifi" in restrictions) {
|
||||
NetworkType.UNMETERED
|
||||
else
|
||||
} else {
|
||||
NetworkType.CONNECTED
|
||||
}
|
||||
|
||||
val constraints = Constraints.Builder()
|
||||
.setRequiredNetworkType(wifiRestriction)
|
||||
.setRequiresCharging(acRestriction)
|
||||
.build()
|
||||
.setRequiredNetworkType(wifiRestriction)
|
||||
.setRequiresCharging(acRestriction)
|
||||
.build()
|
||||
|
||||
val request = PeriodicWorkRequestBuilder<LibraryUpdateJob>(
|
||||
interval.toLong(), TimeUnit.HOURS,
|
||||
10, TimeUnit.MINUTES)
|
||||
.addTag(TAG)
|
||||
.setConstraints(constraints)
|
||||
.build()
|
||||
interval.toLong(), TimeUnit.HOURS,
|
||||
10, TimeUnit.MINUTES
|
||||
)
|
||||
.addTag(TAG)
|
||||
.setConstraints(constraints)
|
||||
.build()
|
||||
|
||||
WorkManager.getInstance(context).enqueueUniquePeriodicWork(TAG, ExistingPeriodicWorkPolicy.REPLACE, request)
|
||||
} else {
|
||||
|
||||
@@ -8,8 +8,9 @@ import eu.kanade.tachiyomi.data.database.models.Manga
|
||||
object LibraryUpdateRanker {
|
||||
|
||||
val rankingScheme = listOf(
|
||||
(this::lexicographicRanking)(),
|
||||
(this::latestFirstRanking)())
|
||||
(this::lexicographicRanking)(),
|
||||
(this::latestFirstRanking)()
|
||||
)
|
||||
|
||||
/**
|
||||
* Provides a total ordering over all the Mangas.
|
||||
@@ -22,7 +23,7 @@ object LibraryUpdateRanker {
|
||||
*/
|
||||
fun latestFirstRanking(): Comparator<Manga> {
|
||||
return Comparator { mangaFirst: Manga,
|
||||
mangaSecond: Manga ->
|
||||
mangaSecond: Manga ->
|
||||
compareValues(mangaSecond.last_update, mangaFirst.last_update)
|
||||
}
|
||||
}
|
||||
@@ -35,7 +36,7 @@ object LibraryUpdateRanker {
|
||||
*/
|
||||
fun lexicographicRanking(): Comparator<Manga> {
|
||||
return Comparator { mangaFirst: Manga,
|
||||
mangaSecond: Manga ->
|
||||
mangaSecond: Manga ->
|
||||
compareValues(mangaFirst.title, mangaSecond.title)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -184,7 +184,8 @@ class LibraryUpdateService(
|
||||
super.onCreate()
|
||||
startForeground(Notifications.ID_LIBRARY_PROGRESS, progressNotificationBuilder.build())
|
||||
wakeLock = (getSystemService(Context.POWER_SERVICE) as PowerManager).newWakeLock(
|
||||
PowerManager.PARTIAL_WAKE_LOCK, "LibraryUpdateService:WakeLock")
|
||||
PowerManager.PARTIAL_WAKE_LOCK, "LibraryUpdateService:WakeLock"
|
||||
)
|
||||
wakeLock.acquire()
|
||||
}
|
||||
|
||||
@@ -218,33 +219,37 @@ class LibraryUpdateService(
|
||||
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
|
||||
if (intent == null) return START_NOT_STICKY
|
||||
val target = intent.getSerializableExtra(KEY_TARGET) as? Target
|
||||
?: return START_NOT_STICKY
|
||||
?: return START_NOT_STICKY
|
||||
|
||||
// Unsubscribe from any previous subscription if needed.
|
||||
subscription?.unsubscribe()
|
||||
|
||||
// Update favorite manga. Destroy service when completed or in case of an error.
|
||||
subscription = Observable
|
||||
.defer {
|
||||
val selectedScheme = preferences.libraryUpdatePrioritization().get()
|
||||
val mangaList = getMangaToUpdate(intent, target)
|
||||
.sortedWith(rankingScheme[selectedScheme])
|
||||
.defer {
|
||||
val selectedScheme = preferences.libraryUpdatePrioritization().get()
|
||||
val mangaList = getMangaToUpdate(intent, target)
|
||||
.sortedWith(rankingScheme[selectedScheme])
|
||||
|
||||
// Update either chapter list or manga details.
|
||||
when (target) {
|
||||
Target.CHAPTERS -> updateChapterList(mangaList)
|
||||
Target.DETAILS -> updateDetails(mangaList)
|
||||
Target.TRACKING -> updateTrackings(mangaList)
|
||||
}
|
||||
// Update either chapter list or manga details.
|
||||
when (target) {
|
||||
Target.CHAPTERS -> updateChapterList(mangaList)
|
||||
Target.DETAILS -> updateDetails(mangaList)
|
||||
Target.TRACKING -> updateTrackings(mangaList)
|
||||
}
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe({
|
||||
}, {
|
||||
}
|
||||
.subscribeOn(Schedulers.io())
|
||||
.subscribe(
|
||||
{
|
||||
},
|
||||
{
|
||||
Timber.e(it)
|
||||
stopSelf(startId)
|
||||
}, {
|
||||
},
|
||||
{
|
||||
stopSelf(startId)
|
||||
})
|
||||
}
|
||||
)
|
||||
|
||||
return START_REDELIVER_INTENT
|
||||
}
|
||||
@@ -259,16 +264,17 @@ class LibraryUpdateService(
|
||||
fun getMangaToUpdate(intent: Intent, target: Target): List<LibraryManga> {
|
||||
val categoryId = intent.getIntExtra(KEY_CATEGORY, -1)
|
||||
|
||||
var listToUpdate = if (categoryId != -1)
|
||||
var listToUpdate = if (categoryId != -1) {
|
||||
db.getLibraryMangas().executeAsBlocking().filter { it.category == categoryId }
|
||||
else {
|
||||
} else {
|
||||
val categoriesToUpdate = preferences.libraryUpdateCategories().get().map(String::toInt)
|
||||
if (categoriesToUpdate.isNotEmpty())
|
||||
if (categoriesToUpdate.isNotEmpty()) {
|
||||
db.getLibraryMangas().executeAsBlocking()
|
||||
.filter { it.category in categoriesToUpdate }
|
||||
.distinctBy { it.id }
|
||||
else
|
||||
.filter { it.category in categoriesToUpdate }
|
||||
.distinctBy { it.id }
|
||||
} else {
|
||||
db.getLibraryMangas().executeAsBlocking().distinctBy { it.id }
|
||||
}
|
||||
}
|
||||
if (target == Target.CHAPTERS && preferences.updateOnlyNonCompleted()) {
|
||||
listToUpdate = listToUpdate.filter { it.status != SManga.COMPLETED }
|
||||
@@ -302,55 +308,57 @@ class LibraryUpdateService(
|
||||
|
||||
// Emit each manga and update it sequentially.
|
||||
return Observable.from(mangaToUpdate)
|
||||
// Notify manga that will update.
|
||||
.doOnNext { showProgressNotification(it, count.andIncrement, mangaToUpdate.size) }
|
||||
// Update the chapters of the manga.
|
||||
.concatMap { manga ->
|
||||
updateManga(manga)
|
||||
// If there's any error, return empty update and continue.
|
||||
.onErrorReturn {
|
||||
failedUpdates.add(manga)
|
||||
Pair(emptyList(), emptyList())
|
||||
}
|
||||
// Filter out mangas without new chapters (or failed).
|
||||
.filter { pair -> pair.first.isNotEmpty() }
|
||||
.doOnNext {
|
||||
if (downloadNew && (categoriesToDownload.isEmpty() ||
|
||||
manga.category in categoriesToDownload)) {
|
||||
|
||||
downloadChapters(manga, it.first)
|
||||
hasDownloads = true
|
||||
}
|
||||
}
|
||||
// Convert to the manga that contains new chapters.
|
||||
.map {
|
||||
Pair(
|
||||
manga,
|
||||
(it.first.sortedByDescending { ch -> ch.source_order }.toTypedArray())
|
||||
)
|
||||
}
|
||||
}
|
||||
// Add manga with new chapters to the list.
|
||||
.doOnNext { manga ->
|
||||
// Add to the list
|
||||
newUpdates.add(manga)
|
||||
}
|
||||
// Notify result of the overall update.
|
||||
.doOnCompleted {
|
||||
if (newUpdates.isNotEmpty()) {
|
||||
showUpdateNotifications(newUpdates)
|
||||
if (downloadNew && hasDownloads) {
|
||||
DownloadService.start(this)
|
||||
// Notify manga that will update.
|
||||
.doOnNext { showProgressNotification(it, count.andIncrement, mangaToUpdate.size) }
|
||||
// Update the chapters of the manga.
|
||||
.concatMap { manga ->
|
||||
updateManga(manga)
|
||||
// If there's any error, return empty update and continue.
|
||||
.onErrorReturn {
|
||||
failedUpdates.add(manga)
|
||||
Pair(emptyList(), emptyList())
|
||||
}
|
||||
// Filter out mangas without new chapters (or failed).
|
||||
.filter { pair -> pair.first.isNotEmpty() }
|
||||
.doOnNext {
|
||||
if (downloadNew && (
|
||||
categoriesToDownload.isEmpty() ||
|
||||
manga.category in categoriesToDownload
|
||||
)
|
||||
) {
|
||||
downloadChapters(manga, it.first)
|
||||
hasDownloads = true
|
||||
}
|
||||
}
|
||||
|
||||
if (failedUpdates.isNotEmpty()) {
|
||||
Timber.e("Failed updating: ${failedUpdates.map { it.title }}")
|
||||
// Convert to the manga that contains new chapters.
|
||||
.map {
|
||||
Pair(
|
||||
manga,
|
||||
(it.first.sortedByDescending { ch -> ch.source_order }.toTypedArray())
|
||||
)
|
||||
}
|
||||
}
|
||||
// Add manga with new chapters to the list.
|
||||
.doOnNext { manga ->
|
||||
// Add to the list
|
||||
newUpdates.add(manga)
|
||||
}
|
||||
// Notify result of the overall update.
|
||||
.doOnCompleted {
|
||||
if (newUpdates.isNotEmpty()) {
|
||||
showUpdateNotifications(newUpdates)
|
||||
if (downloadNew && hasDownloads) {
|
||||
DownloadService.start(this)
|
||||
}
|
||||
|
||||
cancelProgressNotification()
|
||||
}
|
||||
.map { manga -> manga.first }
|
||||
|
||||
if (failedUpdates.isNotEmpty()) {
|
||||
Timber.e("Failed updating: ${failedUpdates.map { it.title }}")
|
||||
}
|
||||
|
||||
cancelProgressNotification()
|
||||
}
|
||||
.map { manga -> manga.first }
|
||||
}
|
||||
|
||||
fun downloadChapters(manga: Manga, chapters: List<Chapter>) {
|
||||
@@ -373,7 +381,7 @@ class LibraryUpdateService(
|
||||
fun updateManga(manga: Manga): Observable<Pair<List<Chapter>, List<Chapter>>> {
|
||||
val source = sourceManager.get(manga.source) as? HttpSource ?: return Observable.empty()
|
||||
return source.fetchChapterList(manga)
|
||||
.map { syncChaptersWithSource(db, it, manga, source) }
|
||||
.map { syncChaptersWithSource(db, it, manga, source) }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -389,24 +397,24 @@ class LibraryUpdateService(
|
||||
|
||||
// Emit each manga and update it sequentially.
|
||||
return Observable.from(mangaToUpdate)
|
||||
// Notify manga that will update.
|
||||
.doOnNext { showProgressNotification(it, count.andIncrement, mangaToUpdate.size) }
|
||||
// Update the details of the manga.
|
||||
.concatMap { manga ->
|
||||
val source = sourceManager.get(manga.source) as? HttpSource
|
||||
?: return@concatMap Observable.empty<LibraryManga>()
|
||||
// Notify manga that will update.
|
||||
.doOnNext { showProgressNotification(it, count.andIncrement, mangaToUpdate.size) }
|
||||
// Update the details of the manga.
|
||||
.concatMap { manga ->
|
||||
val source = sourceManager.get(manga.source) as? HttpSource
|
||||
?: return@concatMap Observable.empty<LibraryManga>()
|
||||
|
||||
source.fetchMangaDetails(manga)
|
||||
.map { networkManga ->
|
||||
manga.copyFrom(networkManga)
|
||||
db.insertManga(manga).executeAsBlocking()
|
||||
manga
|
||||
}
|
||||
.onErrorReturn { manga }
|
||||
}
|
||||
.doOnCompleted {
|
||||
cancelProgressNotification()
|
||||
}
|
||||
source.fetchMangaDetails(manga)
|
||||
.map { networkManga ->
|
||||
manga.copyFrom(networkManga)
|
||||
db.insertManga(manga).executeAsBlocking()
|
||||
manga
|
||||
}
|
||||
.onErrorReturn { manga }
|
||||
}
|
||||
.doOnCompleted {
|
||||
cancelProgressNotification()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -421,28 +429,28 @@ class LibraryUpdateService(
|
||||
|
||||
// Emit each manga and update it sequentially.
|
||||
return Observable.from(mangaToUpdate)
|
||||
// Notify manga that will update.
|
||||
.doOnNext { showProgressNotification(it, count++, mangaToUpdate.size) }
|
||||
// Update the tracking details.
|
||||
.concatMap { manga ->
|
||||
val tracks = db.getTracks(manga).executeAsBlocking()
|
||||
// Notify manga that will update.
|
||||
.doOnNext { showProgressNotification(it, count++, mangaToUpdate.size) }
|
||||
// Update the tracking details.
|
||||
.concatMap { manga ->
|
||||
val tracks = db.getTracks(manga).executeAsBlocking()
|
||||
|
||||
Observable.from(tracks)
|
||||
.concatMap { track ->
|
||||
val service = trackManager.getService(track.sync_id)
|
||||
if (service != null && service in loggedServices) {
|
||||
service.refresh(track)
|
||||
.doOnNext { db.insertTrack(it).executeAsBlocking() }
|
||||
.onErrorReturn { track }
|
||||
} else {
|
||||
Observable.empty()
|
||||
}
|
||||
}
|
||||
.map { manga }
|
||||
}
|
||||
.doOnCompleted {
|
||||
cancelProgressNotification()
|
||||
}
|
||||
Observable.from(tracks)
|
||||
.concatMap { track ->
|
||||
val service = trackManager.getService(track.sync_id)
|
||||
if (service != null && service in loggedServices) {
|
||||
service.refresh(track)
|
||||
.doOnNext { db.insertTrack(it).executeAsBlocking() }
|
||||
.onErrorReturn { track }
|
||||
} else {
|
||||
Observable.empty()
|
||||
}
|
||||
}
|
||||
.map { manga }
|
||||
}
|
||||
.doOnCompleted {
|
||||
cancelProgressNotification()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -453,15 +461,19 @@ class LibraryUpdateService(
|
||||
* @param total the total progress.
|
||||
*/
|
||||
private fun showProgressNotification(manga: Manga, current: Int, total: Int) {
|
||||
val title = if (preferences.hideNotificationContent())
|
||||
val title = if (preferences.hideNotificationContent()) {
|
||||
getString(R.string.notification_check_updates)
|
||||
else
|
||||
} else {
|
||||
manga.title
|
||||
}
|
||||
|
||||
notificationManager.notify(Notifications.ID_LIBRARY_PROGRESS, progressNotificationBuilder
|
||||
notificationManager.notify(
|
||||
Notifications.ID_LIBRARY_PROGRESS,
|
||||
progressNotificationBuilder
|
||||
.setContentTitle(title)
|
||||
.setProgress(total, current, false)
|
||||
.build())
|
||||
.build()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -476,31 +488,38 @@ class LibraryUpdateService(
|
||||
|
||||
NotificationManagerCompat.from(this).apply {
|
||||
// Parent group notification
|
||||
notify(Notifications.ID_NEW_CHAPTERS, notification(Notifications.CHANNEL_NEW_CHAPTERS) {
|
||||
setContentTitle(getString(R.string.notification_new_chapters))
|
||||
if (updates.size == 1 && !preferences.hideNotificationContent()) {
|
||||
setContentText(updates.first().first.title.chop(NOTIF_TITLE_MAX_LEN))
|
||||
} else {
|
||||
setContentText(resources.getQuantityString(R.plurals.notification_new_chapters_summary, updates.size, updates.size))
|
||||
notify(
|
||||
Notifications.ID_NEW_CHAPTERS,
|
||||
notification(Notifications.CHANNEL_NEW_CHAPTERS) {
|
||||
setContentTitle(getString(R.string.notification_new_chapters))
|
||||
if (updates.size == 1 && !preferences.hideNotificationContent()) {
|
||||
setContentText(updates.first().first.title.chop(NOTIF_TITLE_MAX_LEN))
|
||||
} else {
|
||||
setContentText(resources.getQuantityString(R.plurals.notification_new_chapters_summary, updates.size, updates.size))
|
||||
|
||||
if (!preferences.hideNotificationContent()) {
|
||||
setStyle(NotificationCompat.BigTextStyle().bigText(updates.joinToString("\n") {
|
||||
it.first.title.chop(NOTIF_TITLE_MAX_LEN)
|
||||
}))
|
||||
if (!preferences.hideNotificationContent()) {
|
||||
setStyle(
|
||||
NotificationCompat.BigTextStyle().bigText(
|
||||
updates.joinToString("\n") {
|
||||
it.first.title.chop(NOTIF_TITLE_MAX_LEN)
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
setSmallIcon(R.drawable.ic_tachi)
|
||||
setLargeIcon(notificationBitmap)
|
||||
|
||||
setGroup(Notifications.GROUP_NEW_CHAPTERS)
|
||||
setGroupAlertBehavior(GROUP_ALERT_SUMMARY)
|
||||
setGroupSummary(true)
|
||||
priority = NotificationCompat.PRIORITY_HIGH
|
||||
|
||||
setContentIntent(getNotificationIntent())
|
||||
setAutoCancel(true)
|
||||
}
|
||||
|
||||
setSmallIcon(R.drawable.ic_tachi)
|
||||
setLargeIcon(notificationBitmap)
|
||||
|
||||
setGroup(Notifications.GROUP_NEW_CHAPTERS)
|
||||
setGroupAlertBehavior(GROUP_ALERT_SUMMARY)
|
||||
setGroupSummary(true)
|
||||
priority = NotificationCompat.PRIORITY_HIGH
|
||||
|
||||
setContentIntent(getNotificationIntent())
|
||||
setAutoCancel(true)
|
||||
})
|
||||
)
|
||||
|
||||
// Per-manga notification
|
||||
if (!preferences.hideNotificationContent()) {
|
||||
@@ -536,13 +555,21 @@ class LibraryUpdateService(
|
||||
setAutoCancel(true)
|
||||
|
||||
// Mark chapters as read action
|
||||
addAction(R.drawable.ic_glasses_black_24dp, getString(R.string.action_mark_as_read),
|
||||
NotificationReceiver.markAsReadPendingBroadcast(this@LibraryUpdateService,
|
||||
manga, chapters, Notifications.ID_NEW_CHAPTERS))
|
||||
addAction(
|
||||
R.drawable.ic_glasses_black_24dp, getString(R.string.action_mark_as_read),
|
||||
NotificationReceiver.markAsReadPendingBroadcast(
|
||||
this@LibraryUpdateService,
|
||||
manga, chapters, Notifications.ID_NEW_CHAPTERS
|
||||
)
|
||||
)
|
||||
// View chapters action
|
||||
addAction(R.drawable.ic_book_24dp, getString(R.string.action_view_chapters),
|
||||
NotificationReceiver.openChapterPendingActivity(this@LibraryUpdateService,
|
||||
manga, Notifications.ID_NEW_CHAPTERS))
|
||||
addAction(
|
||||
R.drawable.ic_book_24dp, getString(R.string.action_view_chapters),
|
||||
NotificationReceiver.openChapterPendingActivity(
|
||||
this@LibraryUpdateService,
|
||||
manga, Notifications.ID_NEW_CHAPTERS
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -556,28 +583,31 @@ class LibraryUpdateService(
|
||||
private fun getMangaIcon(manga: Manga): Bitmap? {
|
||||
return try {
|
||||
Glide.with(this)
|
||||
.asBitmap()
|
||||
.load(manga.toMangaThumbnail())
|
||||
.dontTransform()
|
||||
.centerCrop()
|
||||
.circleCrop()
|
||||
.override(NOTIF_ICON_SIZE, NOTIF_ICON_SIZE)
|
||||
.submit()
|
||||
.get()
|
||||
.asBitmap()
|
||||
.load(manga.toMangaThumbnail())
|
||||
.dontTransform()
|
||||
.centerCrop()
|
||||
.circleCrop()
|
||||
.override(NOTIF_ICON_SIZE, NOTIF_ICON_SIZE)
|
||||
.submit()
|
||||
.get()
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
private fun getNewChaptersDescription(chapters: Array<Chapter>): String {
|
||||
val formatter = DecimalFormat("#.###", DecimalFormatSymbols()
|
||||
.apply { decimalSeparator = '.' })
|
||||
val formatter = DecimalFormat(
|
||||
"#.###",
|
||||
DecimalFormatSymbols()
|
||||
.apply { decimalSeparator = '.' }
|
||||
)
|
||||
|
||||
val displayableChapterNumbers = chapters
|
||||
.filter { it.isRecognizedNumber }
|
||||
.sortedBy { it.chapter_number }
|
||||
.map { formatter.format(it.chapter_number) }
|
||||
.toSet()
|
||||
.filter { it.isRecognizedNumber }
|
||||
.sortedBy { it.chapter_number }
|
||||
.map { formatter.format(it.chapter_number) }
|
||||
.toSet()
|
||||
|
||||
return when (displayableChapterNumbers.size) {
|
||||
// No sensible chapter numbers to show (i.e. no chapters have parsed chapter number)
|
||||
|
||||
Reference in New Issue
Block a user