Add optional to automatically download new chapers (#538)

* Add optional to automatically download new chapers

* Only trigger download once
This commit is contained in:
Robin Appelman 2016-12-06 17:22:03 +01:00 committed by inorichi
parent 30b4c6e755
commit 8b60d5bfcb
7 changed files with 51 additions and 14 deletions

View file

@ -13,7 +13,10 @@ import eu.kanade.tachiyomi.Constants
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.DatabaseHelper import eu.kanade.tachiyomi.data.database.DatabaseHelper
import eu.kanade.tachiyomi.data.database.models.Category import eu.kanade.tachiyomi.data.database.models.Category
import eu.kanade.tachiyomi.data.database.models.Chapter
import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.database.models.Manga
import eu.kanade.tachiyomi.data.download.DownloadManager
import eu.kanade.tachiyomi.data.download.DownloadService
import eu.kanade.tachiyomi.data.library.LibraryUpdateService.Companion.start import eu.kanade.tachiyomi.data.library.LibraryUpdateService.Companion.start
import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.data.preference.getOrDefault import eu.kanade.tachiyomi.data.preference.getOrDefault
@ -53,6 +56,8 @@ class LibraryUpdateService : Service() {
*/ */
val preferences: PreferencesHelper by injectLazy() val preferences: PreferencesHelper by injectLazy()
val downloadManager: DownloadManager by injectLazy()
/** /**
* Wake lock that will be held until the service is destroyed. * Wake lock that will be held until the service is destroyed.
*/ */
@ -243,10 +248,15 @@ class LibraryUpdateService : Service() {
// 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(manga)
Pair(0, 0) Pair(emptyList<Chapter>(), emptyList<Chapter>())
} }
// Filter out mangas without new chapters (or failed). // Filter out mangas without new chapters (or failed).
.filter { pair -> pair.first > 0 } .filter { pair -> pair.first.size > 0 }
.doOnNext {
if (preferences.downloadNew()) {
downloadChapters(manga, it.first)
}
}
// Convert to the manga that contains new chapters. // Convert to the manga that contains new chapters.
.map { manga } .map { manga }
} }
@ -263,18 +273,30 @@ class LibraryUpdateService : Service() {
if (newUpdates.isEmpty()) { if (newUpdates.isEmpty()) {
cancelNotification() cancelNotification()
} else { } else {
if (preferences.downloadNew()) {
DownloadService.start(this)
}
showResultNotification(newUpdates, failedUpdates) showResultNotification(newUpdates, failedUpdates)
} }
} }
} }
fun downloadChapters(manga: Manga, chapters: List<Chapter>) {
// we need to get the chapters from the db so we have chapter ids
val mangaChapters = db.getChapters(manga).executeAsBlocking()
val dbChapters = chapters.map {
mangaChapters.find { mangaChapter -> mangaChapter.url == it.url }!!
}
downloadManager.downloadChapters(manga, dbChapters)
}
/** /**
* Updates the chapters for the given manga and adds them to the database. * Updates the chapters for the given manga and adds them to the database.
* *
* @param manga the manga to update. * @param manga the manga to update.
* @return a pair of the inserted and removed chapters. * @return a pair of the inserted and removed chapters.
*/ */
fun updateManga(manga: Manga): Observable<Pair<Int, Int>> { fun updateManga(manga: Manga): Observable<Pair<List<Chapter>, List<Chapter>>> {
val source = sourceManager.get(manga.source) as? OnlineSource ?: return Observable.empty() val source = sourceManager.get(manga.source) as? OnlineSource ?: return Observable.empty()
return source.fetchChapterList(manga) return source.fetchChapterList(manga)
.map { syncChaptersWithSource(db, it, manga, source) } .map { syncChaptersWithSource(db, it, manga, source) }

View file

@ -89,6 +89,8 @@ class PreferenceKeys(context: Context) {
val startScreen = context.getString(R.string.pref_start_screen_key) val startScreen = context.getString(R.string.pref_start_screen_key)
val downloadNew = context.getString(R.string.pref_download_new_key)
fun sourceUsername(sourceId: Int) = "pref_source_username_$sourceId" fun sourceUsername(sourceId: Int) = "pref_source_username_$sourceId"
fun sourcePassword(sourceId: Int) = "pref_source_password_$sourceId" fun sourcePassword(sourceId: Int) = "pref_source_password_$sourceId"

View file

@ -134,4 +134,6 @@ class PreferencesHelper(context: Context) {
fun hiddenCatalogues() = rxPrefs.getStringSet("hidden_catalogues", emptySet()) fun hiddenCatalogues() = rxPrefs.getStringSet("hidden_catalogues", emptySet())
fun downloadNew() = prefs.getBoolean(keys.downloadNew, false)
} }

View file

@ -19,7 +19,7 @@ import java.util.*
fun syncChaptersWithSource(db: DatabaseHelper, fun syncChaptersWithSource(db: DatabaseHelper,
sourceChapters: List<Chapter>, sourceChapters: List<Chapter>,
manga: Manga, manga: Manga,
source: Source) : Pair<Int, Int> { source: Source) : Pair<List<Chapter>, List<Chapter>> {
// Chapters from db. // Chapters from db.
val dbChapters = db.getChapters(manga).executeAsBlocking() val dbChapters = db.getChapters(manga).executeAsBlocking()
@ -44,22 +44,19 @@ fun syncChaptersWithSource(db: DatabaseHelper,
// Chapters from the db not in the source. // Chapters from the db not in the source.
val toDelete = dbChapters.filterNot { it in sourceChapters } val toDelete = dbChapters.filterNot { it in sourceChapters }
// Amount of chapters added and deleted. val readded = mutableListOf<Chapter>()
var added = 0
var deleted = 0
// Amount of chapters readded (different url but the same chapter number).
var readded = 0
db.inTransaction { db.inTransaction {
val deletedChapterNumbers = TreeSet<Float>()
val deletedReadChapterNumbers = TreeSet<Float>() val deletedReadChapterNumbers = TreeSet<Float>()
if (!toDelete.isEmpty()) { if (!toDelete.isEmpty()) {
for (c in toDelete) { for (c in toDelete) {
if (c.read) { if (c.read) {
deletedReadChapterNumbers.add(c.chapter_number) deletedReadChapterNumbers.add(c.chapter_number)
} }
deletedChapterNumbers.add(c.chapter_number)
} }
deleted = db.deleteChapters(toDelete).executeAsBlocking().results().size db.deleteChapters(toDelete).executeAsBlocking()
} }
if (!toAdd.isEmpty()) { if (!toAdd.isEmpty()) {
@ -73,14 +70,16 @@ fun syncChaptersWithSource(db: DatabaseHelper,
// Try to mark already read chapters as read when the source deletes them // Try to mark already read chapters as read when the source deletes them
if (c.isRecognizedNumber && c.chapter_number in deletedReadChapterNumbers) { if (c.isRecognizedNumber && c.chapter_number in deletedReadChapterNumbers) {
c.read = true c.read = true
readded++ }
if (c.isRecognizedNumber && c.chapter_number in deletedChapterNumbers) {
readded.add(c)
} }
} }
added = db.insertChapters(toAdd).executeAsBlocking().numberOfInserts() db.insertChapters(toAdd).executeAsBlocking()
} }
// Fix order in source. // Fix order in source.
db.fixChaptersSourceOrder(sourceChapters).executeAsBlocking() db.fixChaptersSourceOrder(sourceChapters).executeAsBlocking()
} }
return Pair(added - readded, deleted - readded) return Pair(toAdd.subtract(readded).toList(), toDelete.subtract(readded).toList())
} }

View file

@ -65,6 +65,8 @@
<string name="pref_display_catalogue_as_list">pref_display_catalogue_as_list</string> <string name="pref_display_catalogue_as_list">pref_display_catalogue_as_list</string>
<string name="pref_last_catalogue_source_key">pref_last_catalogue_source_key</string> <string name="pref_last_catalogue_source_key">pref_last_catalogue_source_key</string>
<string name="pref_download_new_key">download_new</string>
<!-- String Fonts --> <!-- String Fonts -->
<string name="font_roboto_medium">sans-serif</string> <string name="font_roboto_medium">sans-serif</string>
<string name="font_roboto_regular">sans-serif</string> <string name="font_roboto_regular">sans-serif</string>

View file

@ -166,6 +166,7 @@
<string name="third_to_last">Third to last chapter</string> <string name="third_to_last">Third to last chapter</string>
<string name="fourth_to_last">Fourth to last chapter</string> <string name="fourth_to_last">Fourth to last chapter</string>
<string name="fifth_to_last">Fifth to last chapter</string> <string name="fifth_to_last">Fifth to last chapter</string>
<string name="pref_download_new">Download new chapters</string>
<!-- Sync section --> <!-- Sync section -->
<string name="services">Services</string> <string name="services">Services</string>

View file

@ -44,6 +44,15 @@
android:summary="%s" android:summary="%s"
android:title="@string/pref_remove_after_read" /> android:title="@string/pref_remove_after_read" />
<PreferenceCategory
android:persistent="false"
android:title="@string/pref_download_new" />
<SwitchPreference
android:defaultValue="false"
android:key="@string/pref_download_new_key"
android:title="@string/pref_download_new"/>
</PreferenceScreen> </PreferenceScreen>
</PreferenceScreen> </PreferenceScreen>