Refactor LibraryUpdateService a bit for future changes
This commit is contained in:
parent
94f5117941
commit
b5c2934270
@ -71,6 +71,7 @@ class LibraryUpdateService(
|
|||||||
private lateinit var notifier: LibraryUpdateNotifier
|
private lateinit var notifier: LibraryUpdateNotifier
|
||||||
private lateinit var ioScope: CoroutineScope
|
private lateinit var ioScope: CoroutineScope
|
||||||
|
|
||||||
|
private var mangaToUpdate: List<LibraryManga> = mutableListOf()
|
||||||
private var updateJob: Job? = null
|
private var updateJob: Job? = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -86,6 +87,8 @@ class LibraryUpdateService(
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
|
private var instance: LibraryUpdateService? = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Key for category to update.
|
* Key for category to update.
|
||||||
*/
|
*/
|
||||||
@ -116,17 +119,18 @@ class LibraryUpdateService(
|
|||||||
* @return true if service newly started, false otherwise
|
* @return true if service newly started, false otherwise
|
||||||
*/
|
*/
|
||||||
fun start(context: Context, category: Category? = null, target: Target = Target.CHAPTERS): Boolean {
|
fun start(context: Context, category: Category? = null, target: Target = Target.CHAPTERS): Boolean {
|
||||||
if (!isRunning(context)) {
|
return if (!isRunning(context)) {
|
||||||
val intent = Intent(context, LibraryUpdateService::class.java).apply {
|
val intent = Intent(context, LibraryUpdateService::class.java).apply {
|
||||||
putExtra(KEY_TARGET, target)
|
putExtra(KEY_TARGET, target)
|
||||||
category?.let { putExtra(KEY_CATEGORY, it.id) }
|
category?.let { putExtra(KEY_CATEGORY, it.id) }
|
||||||
}
|
}
|
||||||
ContextCompat.startForegroundService(context, intent)
|
ContextCompat.startForegroundService(context, intent)
|
||||||
|
|
||||||
return true
|
true
|
||||||
|
} else {
|
||||||
|
instance?.addMangaToQueue(category?.id ?: -1, target)
|
||||||
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -163,6 +167,9 @@ class LibraryUpdateService(
|
|||||||
if (wakeLock.isHeld) {
|
if (wakeLock.isHeld) {
|
||||||
wakeLock.release()
|
wakeLock.release()
|
||||||
}
|
}
|
||||||
|
if (instance == this) {
|
||||||
|
instance = null
|
||||||
|
}
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,23 +193,25 @@ class LibraryUpdateService(
|
|||||||
val target = intent.getSerializableExtra(KEY_TARGET) as? Target
|
val target = intent.getSerializableExtra(KEY_TARGET) as? Target
|
||||||
?: return START_NOT_STICKY
|
?: return START_NOT_STICKY
|
||||||
|
|
||||||
// Unsubscribe from any previous subscription if needed.
|
instance = this
|
||||||
|
|
||||||
|
// Unsubscribe from any previous subscription if needed
|
||||||
updateJob?.cancel()
|
updateJob?.cancel()
|
||||||
|
|
||||||
// Update favorite manga. Destroy service when completed or in case of an error.
|
// Update favorite manga
|
||||||
val selectedScheme = preferences.libraryUpdatePrioritization().get()
|
val categoryId = intent.getIntExtra(KEY_CATEGORY, -1)
|
||||||
val mangaList = getMangaToUpdate(intent, target)
|
addMangaToQueue(categoryId, target)
|
||||||
.sortedWith(rankingScheme[selectedScheme])
|
|
||||||
|
|
||||||
|
// Destroy service when completed or in case of an error.
|
||||||
val handler = CoroutineExceptionHandler { _, exception ->
|
val handler = CoroutineExceptionHandler { _, exception ->
|
||||||
Timber.e(exception)
|
Timber.e(exception)
|
||||||
stopSelf(startId)
|
stopSelf(startId)
|
||||||
}
|
}
|
||||||
updateJob = ioScope.launch(handler) {
|
updateJob = ioScope.launch(handler) {
|
||||||
when (target) {
|
when (target) {
|
||||||
Target.CHAPTERS -> updateChapterList(mangaList)
|
Target.CHAPTERS -> updateChapterList()
|
||||||
Target.COVERS -> updateCovers(mangaList)
|
Target.COVERS -> updateCovers()
|
||||||
Target.TRACKING -> updateTrackings(mangaList)
|
Target.TRACKING -> updateTrackings()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
updateJob?.invokeOnCompletion { stopSelf(startId) }
|
updateJob?.invokeOnCompletion { stopSelf(startId) }
|
||||||
@ -211,32 +220,32 @@ class LibraryUpdateService(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the list of manga to be updated.
|
* Adds list of manga to be updated.
|
||||||
*
|
*
|
||||||
* @param intent the update intent.
|
* @param category the ID of the category to update, or -1 if no category specified.
|
||||||
* @param target the target to update.
|
* @param target the target to update.
|
||||||
* @return a list of manga to update
|
|
||||||
*/
|
*/
|
||||||
fun getMangaToUpdate(intent: Intent, target: Target): List<LibraryManga> {
|
fun addMangaToQueue(categoryId: Int, target: Target) {
|
||||||
val categoryId = intent.getIntExtra(KEY_CATEGORY, -1)
|
val libraryManga = db.getLibraryMangas().executeAsBlocking()
|
||||||
|
|
||||||
var listToUpdate = if (categoryId != -1) {
|
var listToUpdate = if (categoryId != -1) {
|
||||||
db.getLibraryMangas().executeAsBlocking().filter { it.category == categoryId }
|
libraryManga.filter { it.category == categoryId }
|
||||||
} else {
|
} else {
|
||||||
val categoriesToUpdate = preferences.libraryUpdateCategories().get().map(String::toInt)
|
val categoriesToUpdate = preferences.libraryUpdateCategories().get().map(String::toInt)
|
||||||
if (categoriesToUpdate.isNotEmpty()) {
|
if (categoriesToUpdate.isNotEmpty()) {
|
||||||
db.getLibraryMangas().executeAsBlocking()
|
libraryManga.filter { it.category in categoriesToUpdate }
|
||||||
.filter { it.category in categoriesToUpdate }
|
|
||||||
.distinctBy { it.id }
|
|
||||||
} else {
|
} else {
|
||||||
db.getLibraryMangas().executeAsBlocking().distinctBy { it.id }
|
libraryManga
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (target == Target.CHAPTERS && preferences.updateOnlyNonCompleted()) {
|
if (target == Target.CHAPTERS && preferences.updateOnlyNonCompleted()) {
|
||||||
listToUpdate = listToUpdate.filter { it.status != SManga.COMPLETED }
|
listToUpdate = listToUpdate.filterNot { it.status == SManga.COMPLETED }
|
||||||
}
|
}
|
||||||
|
|
||||||
return listToUpdate
|
val selectedScheme = preferences.libraryUpdatePrioritization().get()
|
||||||
|
mangaToUpdate = listToUpdate
|
||||||
|
.distinctBy { it.id }
|
||||||
|
.sortedWith(rankingScheme[selectedScheme])
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -248,7 +257,7 @@ class LibraryUpdateService(
|
|||||||
* @param mangaToUpdate the list to update
|
* @param mangaToUpdate the list to update
|
||||||
* @return an observable delivering the progress of each update.
|
* @return an observable delivering the progress of each update.
|
||||||
*/
|
*/
|
||||||
suspend fun updateChapterList(mangaToUpdate: List<LibraryManga>) {
|
suspend fun updateChapterList() {
|
||||||
val progressCount = AtomicInteger(0)
|
val progressCount = AtomicInteger(0)
|
||||||
val newUpdates = mutableListOf<Pair<LibraryManga, Array<Chapter>>>()
|
val newUpdates = mutableListOf<Pair<LibraryManga, Array<Chapter>>>()
|
||||||
val failedUpdates = mutableListOf<Pair<Manga, String?>>()
|
val failedUpdates = mutableListOf<Pair<Manga, String?>>()
|
||||||
@ -342,7 +351,7 @@ class LibraryUpdateService(
|
|||||||
return syncChaptersWithSource(db, chapters, manga, source)
|
return syncChaptersWithSource(db, chapters, manga, source)
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun updateCovers(mangaToUpdate: List<LibraryManga>) {
|
private suspend fun updateCovers() {
|
||||||
var progressCount = 0
|
var progressCount = 0
|
||||||
|
|
||||||
mangaToUpdate.forEach { manga ->
|
mangaToUpdate.forEach { manga ->
|
||||||
@ -375,7 +384,7 @@ class LibraryUpdateService(
|
|||||||
* Method that updates the metadata of the connected tracking services. It's called in a
|
* Method that updates the metadata of the connected tracking services. It's called in a
|
||||||
* background thread, so it's safe to do heavy operations or network calls here.
|
* background thread, so it's safe to do heavy operations or network calls here.
|
||||||
*/
|
*/
|
||||||
private suspend fun updateTrackings(mangaToUpdate: List<LibraryManga>) {
|
private suspend fun updateTrackings() {
|
||||||
var progressCount = 0
|
var progressCount = 0
|
||||||
val loggedServices = trackManager.services.filter { it.isLogged }
|
val loggedServices = trackManager.services.filter { it.isLogged }
|
||||||
|
|
||||||
|
@ -100,7 +100,8 @@ class LibraryUpdateServiceTest {
|
|||||||
val intent = Intent()
|
val intent = Intent()
|
||||||
val target = LibraryUpdateService.Target.CHAPTERS
|
val target = LibraryUpdateService.Target.CHAPTERS
|
||||||
runBlocking {
|
runBlocking {
|
||||||
service.updateChapterList(service.getMangaToUpdate(intent, target))
|
service.addMangaToQueue(intent, target)
|
||||||
|
service.updateChapterList()
|
||||||
|
|
||||||
// There are 3 network attempts and 2 insertions (1 request failed)
|
// There are 3 network attempts and 2 insertions (1 request failed)
|
||||||
assertThat(service.db.getChapters(favManga[0]).executeAsBlocking()).hasSize(2)
|
assertThat(service.db.getChapters(favManga[0]).executeAsBlocking()).hasSize(2)
|
||||||
|
Loading…
Reference in New Issue
Block a user