Browse Source

Add optional to automatically download new chapers (#538)

* Add optional to automatically download new chapers

* Only trigger download once
Robin Appelman 8 years ago
parent
commit
8b60d5bfcb

+ 25 - 3
app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt

@@ -13,7 +13,10 @@ import eu.kanade.tachiyomi.Constants
 import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.data.database.DatabaseHelper
 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.download.DownloadManager
+import eu.kanade.tachiyomi.data.download.DownloadService
 import eu.kanade.tachiyomi.data.library.LibraryUpdateService.Companion.start
 import eu.kanade.tachiyomi.data.preference.PreferencesHelper
 import eu.kanade.tachiyomi.data.preference.getOrDefault
@@ -53,6 +56,8 @@ class LibraryUpdateService : Service() {
      */
     val preferences: PreferencesHelper by injectLazy()
 
+    val downloadManager: DownloadManager by injectLazy()
+
     /**
      * 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.
                             .onErrorReturn {
                                 failedUpdates.add(manga)
-                                Pair(0, 0)
+                                Pair(emptyList<Chapter>(), emptyList<Chapter>())
                             }
                             // 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.
                             .map { manga }
                 }
@@ -263,18 +273,30 @@ class LibraryUpdateService : Service() {
                     if (newUpdates.isEmpty()) {
                         cancelNotification()
                     } else {
+                        if (preferences.downloadNew()) {
+                            DownloadService.start(this)
+                        }
                         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.
      *
      * @param manga the manga to update.
      * @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()
         return source.fetchChapterList(manga)
                 .map { syncChaptersWithSource(db, it, manga, source) }

+ 2 - 0
app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt

@@ -89,6 +89,8 @@ class PreferenceKeys(context: Context) {
 
     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 sourcePassword(sourceId: Int) = "pref_source_password_$sourceId"

+ 2 - 0
app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt

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

+ 10 - 11
app/src/main/java/eu/kanade/tachiyomi/util/ChapterSourceSync.kt

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

+ 2 - 0
app/src/main/res/values/keys.xml

@@ -65,6 +65,8 @@
     <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_download_new_key">download_new</string>
+
     <!-- String Fonts -->
     <string name="font_roboto_medium">sans-serif</string>
     <string name="font_roboto_regular">sans-serif</string>

+ 1 - 0
app/src/main/res/values/strings.xml

@@ -166,6 +166,7 @@
     <string name="third_to_last">Third 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="pref_download_new">Download new chapters</string>
 
       <!-- Sync section -->
     <string name="services">Services</string>

+ 9 - 0
app/src/main/res/xml/pref_downloads.xml

@@ -44,6 +44,15 @@
             android:summary="%s"
             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>