From 91829b0e7d35b6e665d31230ccedfa35760988a0 Mon Sep 17 00:00:00 2001 From: len Date: Thu, 15 Sep 2016 18:00:54 +0200 Subject: [PATCH] Select categories for global update --- app/src/main/AndroidManifest.xml | 33 ++--- .../data/library/LibraryUpdateService.kt | 124 +++++------------- .../data/library/LibraryUpdateTrigger.kt | 52 ++++++++ .../data/preference/PreferenceKeys.kt | 2 + .../data/preference/PreferencesHelper.kt | 2 + .../ui/setting/SettingsGeneralFragment.kt | 32 ++++- app/src/main/res/values/keys.xml | 1 + app/src/main/res/values/strings.xml | 1 + app/src/main/res/xml/pref_general.xml | 4 + .../data/library/LibraryUpdateAlarmTest.kt | 124 ------------------ .../data/library/LibraryUpdateServiceTest.kt | 4 +- 11 files changed, 135 insertions(+), 244 deletions(-) create mode 100644 app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateTrigger.kt delete mode 100644 app/src/test/java/eu/kanade/tachiyomi/data/library/LibraryUpdateAlarmTest.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3c8f5400da..d91c3b2d6d 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -59,6 +59,15 @@ + + + + + + - - - - - - - - - - - - - - - - - - - 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 b36acef0ed..612682170f 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 @@ -8,8 +8,6 @@ import android.content.Intent import android.os.IBinder import android.os.PowerManager import android.support.v4.app.NotificationCompat -import com.github.pwittchen.reactivenetwork.library.ConnectivityStatus -import com.github.pwittchen.reactivenetwork.library.ReactiveNetwork import eu.kanade.tachiyomi.Constants import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.data.database.DatabaseHelper @@ -17,10 +15,14 @@ import eu.kanade.tachiyomi.data.database.models.Category import eu.kanade.tachiyomi.data.database.models.Manga import eu.kanade.tachiyomi.data.library.LibraryUpdateService.Companion.start import eu.kanade.tachiyomi.data.preference.PreferencesHelper +import eu.kanade.tachiyomi.data.preference.getOrDefault import eu.kanade.tachiyomi.data.source.SourceManager import eu.kanade.tachiyomi.data.source.online.OnlineSource import eu.kanade.tachiyomi.ui.main.MainActivity -import eu.kanade.tachiyomi.util.* +import eu.kanade.tachiyomi.util.AndroidComponentUtil +import eu.kanade.tachiyomi.util.notification +import eu.kanade.tachiyomi.util.notificationManager +import eu.kanade.tachiyomi.util.syncChaptersWithSource import rx.Observable import rx.Subscription import rx.schedulers.Schedulers @@ -97,7 +99,7 @@ class LibraryUpdateService : Service() { * * @param context the application context. * @param isManual whether the update has been manually triggered. - * @param category a specific category to update, or null for all in the library. + * @param category a specific category to update, or null for global update. */ fun start(context: Context, isManual: Boolean = false, category: Category? = null) { if (!isRunning(context)) { @@ -156,45 +158,7 @@ class LibraryUpdateService : Service() { * @return the start value of the command. */ override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { - - // Get connectivity status - val connection = ReactiveNetwork().getConnectivityStatus(this, true) - - // Get library update restrictions - val restrictions = preferences.libraryUpdateRestriction() - - // Check if users updates library manual - val isManualUpdate = intent?.getBooleanExtra(UPDATE_IS_MANUAL, false) ?: false - - // Whether to cancel the update. - var cancelUpdate = false - - // Check if device has internet connection - // Check if device has wifi connection if only wifi is enabled - if (connection == ConnectivityStatus.OFFLINE || (!isManualUpdate && "wifi" in restrictions - && connection != ConnectivityStatus.WIFI_CONNECTED_HAS_INTERNET)) { - - if (isManualUpdate) { - toast(R.string.notification_no_connection_title) - } - - // Enable library update when connection available - AndroidComponentUtil.toggleComponent(this, SyncOnConnectionAvailable::class.java, true) - cancelUpdate = true - } - if (!isManualUpdate && "ac" in restrictions && !DeviceUtil.isPowerConnected(this)) { - AndroidComponentUtil.toggleComponent(this, SyncOnPowerConnected::class.java, true) - cancelUpdate = true - } - - if (cancelUpdate) { - stopSelf(startId) - return Service.START_NOT_STICKY - } - - // Stop enabled components. - AndroidComponentUtil.toggleComponent(this, SyncOnConnectionAvailable::class.java, false) - AndroidComponentUtil.toggleComponent(this, SyncOnPowerConnected::class.java, false) + if (intent == null) return Service.START_NOT_STICKY // Unsubscribe from any previous subscription if needed. subscription?.unsubscribe() @@ -202,15 +166,17 @@ class LibraryUpdateService : Service() { // Update favorite manga. Destroy service when completed or in case of an error. subscription = Observable.defer { updateMangaList(getMangaToUpdate(intent)) } .subscribeOn(Schedulers.io()) - .subscribe({}, - { - showNotification(getString(R.string.notification_update_error), "") - stopSelf(startId) - }, { + .subscribe({ + }, { + showNotification(getString(R.string.notification_update_error), "") + LibraryUpdateTrigger.setupTask(this) + stopSelf(startId) + }, { + LibraryUpdateTrigger.setupTask(this) stopSelf(startId) }) - return Service.START_STICKY + return Service.START_REDELIVER_INTENT } /** @@ -219,19 +185,26 @@ class LibraryUpdateService : Service() { * @param intent the update intent. * @return a list of manga to update */ - fun getMangaToUpdate(intent: Intent?): List { - val categoryId = intent?.getIntExtra(UPDATE_CATEGORY, -1) ?: -1 + fun getMangaToUpdate(intent: Intent): List { + val categoryId = intent.getIntExtra(UPDATE_CATEGORY, -1) - var toUpdate = if (categoryId != -1) + var listToUpdate = if (categoryId != -1) db.getLibraryMangas().executeAsBlocking().filter { it.category == categoryId } - else - db.getFavoriteMangas().executeAsBlocking() - - if (preferences.updateOnlyNonCompleted()) { - toUpdate = toUpdate.filter { it.status != Manga.COMPLETED } + else { + val categoriesToUpdate = preferences.libraryUpdateCategories().getOrDefault().map { it.toInt() } + if (categoriesToUpdate.isNotEmpty()) + db.getLibraryMangas().executeAsBlocking() + .filter { it.category in categoriesToUpdate } + .distinctBy { it.id } + else + db.getFavoriteMangas().executeAsBlocking().distinctBy { it.id } } - return toUpdate + if (preferences.updateOnlyNonCompleted()) { + listToUpdate = listToUpdate.filter { it.status != Manga.COMPLETED } + } + + return listToUpdate } /** @@ -410,41 +383,6 @@ class LibraryUpdateService : Service() { return PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT) } - /** - * Class that triggers the library to update when a connection is available. It receives - * network changes. - */ - class SyncOnConnectionAvailable : BroadcastReceiver() { - /** - * Method called when a network change occurs. - * - * @param context the application context. - * @param intent the intent received. - */ - override fun onReceive(context: Context, intent: Intent) { - if (DeviceUtil.isNetworkConnected(context)) { - AndroidComponentUtil.toggleComponent(context, this.javaClass, false) - start(context) - } - } - } - - /** - * Class that triggers the library to update when connected to power. - */ - class SyncOnPowerConnected: BroadcastReceiver() { - /** - * Method called when AC is connected. - * - * @param context the application context. - * @param intent the intent received. - */ - override fun onReceive(context: Context, intent: Intent) { - AndroidComponentUtil.toggleComponent(context, this.javaClass, false) - start(context) - } - } - /** * Class that stops updating the library. */ diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateTrigger.kt b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateTrigger.kt new file mode 100644 index 0000000000..e58beba034 --- /dev/null +++ b/app/src/main/java/eu/kanade/tachiyomi/data/library/LibraryUpdateTrigger.kt @@ -0,0 +1,52 @@ +package eu.kanade.tachiyomi.data.library + +import android.content.Context +import com.google.android.gms.gcm.* +import eu.kanade.tachiyomi.data.preference.PreferencesHelper +import eu.kanade.tachiyomi.data.preference.getOrDefault +import uy.kohesive.injekt.Injekt +import uy.kohesive.injekt.api.get + +class LibraryUpdateTrigger : GcmTaskService() { + + override fun onInitializeTasks() { + setupTask(this) + } + + override fun onRunTask(params: TaskParams): Int { + LibraryUpdateService.start(this) + return GcmNetworkManager.RESULT_SUCCESS + } + + companion object { + fun setupTask(context: Context) { + val preferences = Injekt.get() + val interval = preferences.libraryUpdateInterval().getOrDefault() + if (interval > 0) { + val restrictions = preferences.libraryUpdateRestriction() + val acRestriction = "ac" in restrictions + val wifiRestriction = if ("wifi" in restrictions) + Task.NETWORK_STATE_UNMETERED + else + Task.NETWORK_STATE_ANY + + val task = PeriodicTask.Builder() + .setService(LibraryUpdateTrigger::class.java) + .setTag("Library periodic update") + .setPeriod(interval * 60 * 60L) + .setFlex(5 * 60) + .setRequiredNetwork(wifiRestriction) + .setRequiresCharging(acRestriction) + .setUpdateCurrent(true) + .setPersisted(true) + .build() + + GcmNetworkManager.getInstance(context).schedule(task) + } + } + + fun cancelTask(context: Context) { + GcmNetworkManager.getInstance(context).cancelAllTasks(LibraryUpdateTrigger::class.java) + } + } +} \ No newline at end of file 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 c575c96e90..99432b13ef 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 @@ -74,6 +74,8 @@ class PreferenceKeys(context: Context) { val libraryUpdateRestriction = context.getString(R.string.pref_library_update_restriction_key) + val libraryUpdateCategories = context.getString(R.string.pref_library_update_categories_key) + val filterDownloaded = context.getString(R.string.pref_filter_downloaded_key) val filterUnread = context.getString(R.string.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 d88f17e0c2..d14a5c6f5e 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 @@ -124,6 +124,8 @@ class PreferencesHelper(context: Context) { fun libraryUpdateRestriction() = prefs.getStringSet(keys.libraryUpdateRestriction, emptySet()) + fun libraryUpdateCategories() = rxPrefs.getStringSet(keys.libraryUpdateCategories, emptySet()) + fun libraryAsList() = rxPrefs.getBoolean(keys.libraryAsList, false) fun filterDownloaded() = rxPrefs.getBoolean(keys.filterDownloaded, false) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsGeneralFragment.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsGeneralFragment.kt index 49d0ed2e58..deedb43630 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsGeneralFragment.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/setting/SettingsGeneralFragment.kt @@ -6,7 +6,8 @@ import android.support.v7.preference.PreferenceFragmentCompat import android.support.v7.preference.XpPreferenceFragment import android.view.View import eu.kanade.tachiyomi.R -import eu.kanade.tachiyomi.data.library.LibraryUpdateAlarm +import eu.kanade.tachiyomi.data.database.DatabaseHelper +import eu.kanade.tachiyomi.data.library.LibraryUpdateTrigger import eu.kanade.tachiyomi.data.preference.PreferencesHelper import eu.kanade.tachiyomi.util.plusAssign import eu.kanade.tachiyomi.widget.preference.IntListPreference @@ -14,6 +15,7 @@ import eu.kanade.tachiyomi.widget.preference.LibraryColumnsDialog import eu.kanade.tachiyomi.widget.preference.SimpleDialogPreference import net.xpece.android.support.preference.MultiSelectListPreference import rx.Observable +import timber.log.Timber import uy.kohesive.injekt.injectLazy class SettingsGeneralFragment : SettingsFragment(), @@ -30,6 +32,8 @@ class SettingsGeneralFragment : SettingsFragment(), private val preferences: PreferencesHelper by injectLazy() + private val db: DatabaseHelper by injectLazy() + val columnsPreference by lazy { findPreference(getString(R.string.pref_library_columns_dialog_key)) as SimpleDialogPreference @@ -47,6 +51,10 @@ class SettingsGeneralFragment : SettingsFragment(), findPreference(getString(R.string.pref_theme_key)) as IntListPreference } + val categoryUpdate by lazy { + findPreference(getString(R.string.pref_library_update_categories_key)) as MultiSelectListPreference + } + override fun onViewCreated(view: View, savedState: Bundle?) { super.onViewCreated(view, savedState) @@ -60,10 +68,30 @@ class SettingsGeneralFragment : SettingsFragment(), .subscribe { updateColumnsSummary(it.first, it.second) } updateInterval.setOnPreferenceChangeListener { preference, newValue -> - LibraryUpdateAlarm.startAlarm(activity, (newValue as String).toInt()) + val enabled = (newValue as String).toInt() > 0 + if (enabled) + LibraryUpdateTrigger.setupTask(context) + else + LibraryUpdateTrigger.cancelTask(context) + true } + val dbCategories = db.getCategories().executeAsBlocking() + categoryUpdate.apply { + entries = dbCategories.map { it.name }.toTypedArray() + entryValues = dbCategories.map { it.id.toString() }.toTypedArray() + } + + subscriptions += preferences.libraryUpdateCategories().asObservable() + .subscribe { + Timber.e(it.joinToString()) + categoryUpdate.summary = it + .mapNotNull { id -> dbCategories.find { it.id == id.toInt() } } + .sortedBy { it.order } + .joinToString { it.name } + } + themePreference.setOnPreferenceChangeListener { preference, newValue -> (activity as SettingsActivity).parentFlags = SettingsActivity.FLAG_THEME_CHANGED activity.recreate() diff --git a/app/src/main/res/values/keys.xml b/app/src/main/res/values/keys.xml index 1149d78f44..b6e36a54ad 100644 --- a/app/src/main/res/values/keys.xml +++ b/app/src/main/res/values/keys.xml @@ -14,6 +14,7 @@ pref_library_columns_portrait_key pref_library_columns_landscape_key pref_library_update_interval_key + library_update_categories pref_update_only_non_completed_key pref_auto_update_manga_sync_key pref_ask_update_manga_sync_key diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 4f4e632950..e82cf670dc 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -85,6 +85,7 @@ Every 12 hours Daily Every 2 days + Categories to include in global update Library update restrictions Update only when the conditions are met Wi-Fi diff --git a/app/src/main/res/xml/pref_general.xml b/app/src/main/res/xml/pref_general.xml index 350b551a8f..e1add0d0f3 100644 --- a/app/src/main/res/xml/pref_general.xml +++ b/app/src/main/res/xml/pref_general.xml @@ -36,6 +36,10 @@ android:summary="%s" android:title="@string/pref_library_update_interval"/> + + >(Exception())) `when`(source.fetchChapterList(favManga[2])).thenReturn(Observable.just(chapters3)) - service.updateMangaList(service.getMangaToUpdate(null)).subscribe() + val intent = Intent() + service.updateMangaList(service.getMangaToUpdate(intent)).subscribe() // There are 3 network attempts and 2 insertions (1 request failed) assertThat(service.db.getChapters(favManga[0]).executeAsBlocking()).hasSize(2)