Browse Source

Update ranking (#1772)

* Add LibraryUpdateRanker

This class provides various functions to generate Comparators that can 
be used to order the manga to update.

One such ordering is by relevance:
It prioritises manga that were updated more recently.

Another Ordering is by lexicographic order:
This is the default behaviour.

* Use relevanceRanking scheme

Instead of default(noRanking/lex ranking) now mangaList is sorted with 
relevanceRanking.

* Add UI and associated variables & strings for Update Ranking.

* Use user preferences to determine update ranking scheme.

* Refactor relevanceRanking to latestFirstranking.

This name seems to better reflect the ranking scheme and frees up the 
name relevanceRanking for future use.

* Set latestFirst scheme as default.

(Changing over from lexicographic scheme)

* Fix 1

[Convert LibraryUpdateRanker to a object.](./files/82f263749f0ae775385b23dd919f1865360db969#r287513539)

[Nitpick: Add lines](./files/82f263749f0ae775385b23dd919f1865360db969#r287540256)

[Replace Java comparator](./files/82f263749f0ae775385b23dd919f1865360db969#r287539976)

[Nitpick: Add local variable](./files/82f263749f0ae775385b23dd919f1865360db969#r287514805)

* Fix 2

[Weird import](./files/82f263749f0ae775385b23dd919f1865360db969#r287513709)

[Default value](./files/82f263749f0ae775385b23dd919f1865360db969#r287540064)

[Use existing Strings](./files/82f263749f0ae775385b23dd919f1865360db969#r287514476)

[Use Library update order](./files/82f263749f0ae775385b23dd919f1865360db969#r287540204)
Harsh Parekh 5 years ago
parent
commit
5d8dc241d8

+ 43 - 0
app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateRanker.kt

@@ -0,0 +1,43 @@
+package eu.kanade.tachiyomi.data.library
+
+import eu.kanade.tachiyomi.data.database.models.Manga
+
+/**
+ * This class will provide various functions to Rank mangas to efficiently schedule mangas to update.
+ */
+object LibraryUpdateRanker {
+
+    val rankingScheme = listOf(
+            (this::lexicographicRanking)(),
+            (this::latestFirstRanking)())
+
+    /**
+     * Provides a total ordering over all the Mangas.
+     *
+     * Assumption: An active [Manga] mActive is expected to have been last updated after an
+     * inactive [Manga] mInactive.
+     *
+     * Using this insight, function returns a Comparator for which mActive appears before mInactive.
+     * @return a Comparator that ranks manga based on relevance.
+     */
+    fun latestFirstRanking(): Comparator<Manga> {
+        return Comparator { mangaFirst: Manga,
+                            mangaSecond: Manga ->
+            compareValues(mangaSecond.last_update, mangaFirst.last_update)
+        }
+    }
+
+    /**
+     * Provides a total ordering over all the Mangas.
+     *
+     * Order the manga lexicographically.
+     * @return a Comparator that ranks manga lexicographically based on the title.
+     */
+    fun lexicographicRanking(): Comparator<Manga> {
+        return Comparator { mangaFirst: Manga,
+                                   mangaSecond: Manga ->
+            compareValues(mangaFirst.title, mangaSecond.title)
+        }
+    }
+
+}

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

@@ -18,6 +18,7 @@ import eu.kanade.tachiyomi.data.database.models.LibraryManga
 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.LibraryUpdateRanker.rankingScheme
 import eu.kanade.tachiyomi.data.library.LibraryUpdateService.Companion.start
 import eu.kanade.tachiyomi.data.notification.NotificationReceiver
 import eu.kanade.tachiyomi.data.notification.Notifications
@@ -204,7 +205,9 @@ class LibraryUpdateService(
         // Update favorite manga. Destroy service when completed or in case of an error.
         subscription = Observable
                 .defer {
+                    val selectedScheme = preferences.libraryUpdatePrioritization().getOrDefault()
                     val mangaList = getMangaToUpdate(intent, target)
+                            .sortedWith(rankingScheme[selectedScheme])
 
                     // Update either chapter list or manga details.
                     when (target) {

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

@@ -87,6 +87,8 @@ object PreferenceKeys {
 
     const val libraryUpdateCategories = "library_update_categories"
 
+    const val libraryUpdatePrioritization = "library_update_prioritization"
+
     const val filterDownloaded = "pref_filter_downloaded_key"
 
     const val filterUnread = "pref_filter_unread_key"

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

@@ -143,6 +143,8 @@ class PreferencesHelper(val context: Context) {
 
     fun libraryUpdateCategories() = rxPrefs.getStringSet(Keys.libraryUpdateCategories, emptySet())
 
+    fun libraryUpdatePrioritization() = rxPrefs.getInteger(Keys.libraryUpdatePrioritization, 1)
+
     fun libraryAsList() = rxPrefs.getBoolean(Keys.libraryAsList, false)
 
     fun downloadBadge() = rxPrefs.getBoolean(Keys.downloadBadge, false)

+ 16 - 0
app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsGeneralController.kt

@@ -159,6 +159,22 @@ class SettingsGeneralController : SettingsController() {
                             selectedCategories.joinToString { it.name }
                     }
         }
+        intListPreference{
+            key = Keys.libraryUpdatePrioritization
+            titleRes = R.string.pref_library_update_prioritization
+            // The following arrays are to be lined up with the list rankingScheme in:
+            // ../../data/library/LibraryUpdateRanker.kt
+            entriesRes = arrayOf(
+                    R.string.action_sort_alpha,
+                    R.string.action_sort_last_updated
+            )
+            entryValues = arrayOf(
+                    "0",
+                    "1"
+            )
+            defaultValue = "1"
+            summaryRes = R.string.pref_library_update_prioritization_summary
+        }
         intListPreference {
             key = Keys.defaultCategory
             titleRes = R.string.default_category

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

@@ -132,6 +132,8 @@
     <string name="update_monthly">Monthly</string>
     <string name="pref_library_update_categories">Categories to include in global update</string>
     <string name="all">All</string>
+    <string name="pref_library_update_prioritization">Library update order</string>
+    <string name="pref_library_update_prioritization_summary">Select the order in which Tachiyomi checks for update</string>
     <string name="pref_library_update_restriction">Library update restrictions</string>
     <string name="pref_library_update_restriction_summary">Update only when the conditions are met</string>
     <string name="wifi">Wi-Fi</string>