From 5d8dc241d8dd9b5f7e37cb07c77ff719a995af37 Mon Sep 17 00:00:00 2001 From: Harsh Parekh Date: Sun, 9 Jun 2019 08:32:12 -0400 Subject: [PATCH] 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) --- .../data/library/LibraryUpdateRanker.kt | 43 +++++++++++++++++++ .../data/library/LibraryUpdateService.kt | 3 ++ .../data/preference/PreferenceKeys.kt | 2 + .../data/preference/PreferencesHelper.kt | 2 + .../ui/setting/SettingsGeneralController.kt | 16 +++++++ app/src/main/res/values/strings.xml | 2 + 6 files changed, 68 insertions(+) create mode 100644 app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateRanker.kt diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateRanker.kt b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateRanker.kt new file mode 100644 index 000000000..735afa833 --- /dev/null +++ b/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 { + 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 { + return Comparator { mangaFirst: Manga, + mangaSecond: Manga -> + compareValues(mangaFirst.title, mangaSecond.title) + } + } + +} \ No newline at end of file diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt index faf44eee4..415a45868 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateService.kt +++ b/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) { diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt index eb5f9d4a1..58388547c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferenceKeys.kt +++ b/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" diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt b/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt index 6545b4a39..b8ab34909 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/preference/PreferencesHelper.kt +++ b/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) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsGeneralController.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsGeneralController.kt index bc1eb6468..b4619de08 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsGeneralController.kt +++ b/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 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 78b2350f8..4b0f0e6f3 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -132,6 +132,8 @@ Monthly Categories to include in global update All + Library update order + Select the order in which Tachiyomi checks for update Library update restrictions Update only when the conditions are met Wi-Fi