Compare commits

..

13 Commits

Author SHA1 Message Date
Eric Kok 20845caf8e
Merge pull request #635 from bwitt/bitcomet-start-stop 12 months ago
Eric Kok b78d0c3f34
Merge pull request #655 from bwitt/rtorrent-remove-torrent-delete-data 12 months ago
Eric Kok 0abe266146
Merge pull request #649 from bwitt/switch-to-work-manager 12 months ago
Eric Kok 9b293ecbca
Merge branch 'master' into switch-to-work-manager 12 months ago
Eric Kok b4c7253d39
Merge pull request #651 from bwitt/bitcomet-handle-auth-problem 12 months ago
Eric Kok 87bba074b9
Merge pull request #642 from bwitt/qbittorrent-add-new-label 12 months ago
Eric Kok 302f0660da
Merge pull request #644 from bwitt/update-gradle-deps 12 months ago
Brian Witt 59ea78c331 rTorrent: also send `d.delete_tied` when removing torrent and data 2 years ago
Brian Witt 7732d89704 handle authorization issue in bitComet 2 years ago
Brian Witt 0de53b1d0b Switch to work manager 2 years ago
Brian Witt 7e2ccf9776 Update gradle dependencies 2 years ago
Brian Witt 6c68d4e153 Fix qbittorrent add new label to torrents 2 years ago
Brian Witt 62a8beae05 Remove bitcomet from supportsStoppingStarting so we dont show confusing stop button 2 years ago
  1. 3
      README.md
  2. 29
      app/build.gradle
  3. 12
      app/src/main/AndroidManifest.xml
  4. 22
      app/src/main/java/org/transdroid/core/gui/TransdroidApp.java
  5. 49
      app/src/main/java/org/transdroid/core/service/AppUpdateJob.java
  6. 17
      app/src/main/java/org/transdroid/core/service/AppUpdateJobRunner.java
  7. 45
      app/src/main/java/org/transdroid/core/service/RssCheckerJob.java
  8. 11
      app/src/main/java/org/transdroid/core/service/RssCheckerJobRunner.java
  9. 42
      app/src/main/java/org/transdroid/core/service/ScheduledJobCreator.java
  10. 45
      app/src/main/java/org/transdroid/core/service/ServerCheckerJob.java
  11. 8
      app/src/main/java/org/transdroid/core/service/ServerCheckerJobRunner.java
  12. 2
      app/src/main/java/org/transdroid/daemon/Daemon.java
  13. 6
      app/src/main/java/org/transdroid/daemon/Label.java
  14. 11
      app/src/main/java/org/transdroid/daemon/adapters/bitComet/BitCometAdapter.java
  15. 20
      app/src/main/java/org/transdroid/daemon/adapters/qBittorrent/QBittorrentAdapter.java
  16. 2
      app/src/main/java/org/transdroid/daemon/adapters/rTorrent/RTorrentAdapter.java

3
README.md

@ -108,9 +108,6 @@ Some code/libraries/resources are used in the project:
* [Material Dialogs](https://github.com/afollestad/material-dialogs) * [Material Dialogs](https://github.com/afollestad/material-dialogs)
Aidan Follestad Aidan Follestad
Apache License, Version 2.0 Apache License, Version 2.0
* [Android-Job](https://github.com/evernote/android-job)
Evernote Corporation
Apache License, Version 2.0
* [android-ColorPickerPreference](https://github.com/attenzione/android-ColorPickerPreference) * [android-ColorPickerPreference](https://github.com/attenzione/android-ColorPickerPreference)
Daniel Nilsson and Sergey Margaritov Daniel Nilsson and Sergey Margaritov
Apache License, Version 2.0 Apache License, Version 2.0

29
app/build.gradle

@ -1,11 +1,11 @@
apply plugin: 'com.android.application' apply plugin: 'com.android.application'
android { android {
compileSdkVersion 31 compileSdkVersion 33
defaultConfig { defaultConfig {
minSdkVersion 15 minSdkVersion 21
targetSdkVersion 31 targetSdkVersion 33
versionCode 242 versionCode 242
versionName '2.5.22' versionName '2.5.22'
@ -80,26 +80,27 @@ android {
dependencies { dependencies {
// Android support // Android support
implementation 'androidx.appcompat:appcompat:1.2.0' implementation 'androidx.appcompat:appcompat:1.5.1'
implementation 'androidx.preference:preference:1.1.1' implementation 'androidx.preference:preference:1.2.0'
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0' implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
implementation 'com.google.android.material:material:1.3.0' implementation 'com.google.android.material:material:1.7.0'
// Other // Other
implementation 'org.androidannotations:androidannotations-api:4.7.0' implementation 'org.androidannotations:androidannotations-api:4.8.0'
implementation 'org.androidannotations:ormlite-api:4.7.0' implementation 'org.androidannotations:ormlite-api:4.8.0'
implementation 'com.j256.ormlite:ormlite-core:5.1' implementation 'com.j256.ormlite:ormlite-android:6.1'
implementation 'com.j256.ormlite:ormlite-android:5.1'
implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.5' implementation 'com.nostra13.universalimageloader:universal-image-loader:1.9.5'
implementation 'com.getbase:floatingactionbutton:1.10.1' implementation 'com.getbase:floatingactionbutton:1.10.1'
implementation 'com.nispok:snackbar:2.11.0' implementation 'com.nispok:snackbar:2.11.0'
implementation 'org.apache.openjpa:openjpa-lib:3.1.1' implementation 'org.apache.openjpa:openjpa-lib:3.2.2'
implementation 'net.iharder:base64:2.3.9' implementation 'net.iharder:base64:2.3.9'
implementation('com.github.afollestad.material-dialogs:core:0.9.6.0@aar') { implementation('com.github.afollestad.material-dialogs:core:0.9.6.0@aar') {
transitive = true transitive = true
} }
implementation 'com.evernote:android-job:1.2.6' implementation 'androidx.work:work-runtime:2.7.1'
implementation "androidx.lifecycle:lifecycle-viewmodel:2.5.1"
implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1"
annotationProcessor 'org.androidannotations:androidannotations:4.7.0' annotationProcessor 'org.androidannotations:androidannotations:4.8.0'
annotationProcessor 'org.androidannotations:ormlite:4.7.0' annotationProcessor 'org.androidannotations:ormlite:4.8.0'
} }

12
app/src/main/AndroidManifest.xml

@ -273,6 +273,18 @@
android:authorities="@string/search_history_authority" android:authorities="@string/search_history_authority"
android:exported="false" /> android:exported="false" />
<!-- allow debug logs for WorkManager -->
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<meta-data
android:name="androidx.work.WorkManagerInitializer"
android:value="androidx.startup"
tools:node="remove" />
</provider>
<!-- RSS --> <!-- RSS -->
<activity <activity
android:name="org.transdroid.core.gui.rss.RssFeedsActivity_" android:name="org.transdroid.core.gui.rss.RssFeedsActivity_"

22
app/src/main/java/org/transdroid/core/gui/TransdroidApp.java

@ -18,27 +18,21 @@ package org.transdroid.core.gui;
import android.app.Application; import android.app.Application;
import com.evernote.android.job.JobConfig; import androidx.annotation.NonNull;
import com.evernote.android.job.JobManager; import androidx.work.Configuration;
import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.EApplication; import org.androidannotations.annotations.EApplication;
import org.transdroid.core.gui.log.Log; import org.transdroid.core.gui.log.Log;
import org.transdroid.core.service.ScheduledJobCreator;
@EApplication @EApplication
public class TransdroidApp extends Application { public class TransdroidApp extends Application implements Configuration.Provider {
@Bean
protected Log log;
@NonNull
@Override @Override
public void onCreate() { public Configuration getWorkManagerConfiguration() {
super.onCreate(); return new Configuration.Builder()
.setMinimumLoggingLevel(android.util.Log.DEBUG)
// Configure Android-Job .build();
JobConfig.addLogger((priority, tag, message, t) -> log.d(tag, message));
JobManager.create(this).addJobCreator(new ScheduledJobCreator());
} }
} }

49
app/src/main/java/org/transdroid/core/service/AppUpdateJob.java

@ -16,13 +16,19 @@
*/ */
package org.transdroid.core.service; package org.transdroid.core.service;
import static java.security.AccessController.getContext;
import android.content.Context; import android.content.Context;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.evernote.android.job.Job; import androidx.work.Constraints;
import com.evernote.android.job.JobManager; import androidx.work.Operation;
import com.evernote.android.job.JobRequest; import androidx.work.PeriodicWorkRequest;
import androidx.work.Worker;
import androidx.work.WorkManager;
import androidx.work.NetworkType;
import androidx.work.WorkerParameters;
import org.transdroid.core.app.settings.NotificationSettings; import org.transdroid.core.app.settings.NotificationSettings;
import org.transdroid.core.app.settings.NotificationSettings_; import org.transdroid.core.app.settings.NotificationSettings_;
@ -31,37 +37,48 @@ import org.transdroid.core.app.settings.SystemSettings_;
import org.transdroid.core.gui.log.Log_; import org.transdroid.core.gui.log.Log_;
import org.transdroid.core.gui.navigation.NavigationHelper_; import org.transdroid.core.gui.navigation.NavigationHelper_;
import java.util.UUID;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
public class AppUpdateJob extends Job { public class AppUpdateJob extends Worker {
static final String TAG = "app_update_checker"; static final String TAG = "app_update_checker";
private static Integer scheduledJobId; private static UUID scheduledJobId;
public AppUpdateJob(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
public static void schedule(Context context) { public static <SimpleJob> void schedule(Context context) {
NotificationSettings notificationSettings = NotificationSettings_.getInstance_(context); NotificationSettings notificationSettings = NotificationSettings_.getInstance_(context);
SystemSettings systemSettings = SystemSettings_.getInstance_(context); SystemSettings systemSettings = SystemSettings_.getInstance_(context);
NavigationHelper_ navigationHelper = NavigationHelper_.getInstance_(context); NavigationHelper_ navigationHelper = NavigationHelper_.getInstance_(context);
if (systemSettings.checkForUpdates() && navigationHelper.enableUpdateChecker()) { if (systemSettings.checkForUpdates() && navigationHelper.enableUpdateChecker()) {
Log_.getInstance_(context).d(TAG, "Schedule app update checker job"); Log_.getInstance_(context).d(TAG, "Schedule app update checker job");
NotificationChannels.ensureAppUpdateChannel(context, notificationSettings); NotificationChannels.ensureAppUpdateChannel(context, notificationSettings);
scheduledJobId = new JobRequest.Builder(AppUpdateJob.TAG) Constraints constraints = new Constraints.Builder()
.setPeriodic(TimeUnit.DAYS.toMillis(1)) .setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiredNetworkType(JobRequest.NetworkType.CONNECTED) .build();
.setUpdateCurrent(true) PeriodicWorkRequest appUpdate = new PeriodicWorkRequest.Builder(AppUpdateJob.class, 1, TimeUnit.DAYS)
.build() .addTag(AppUpdateJob.TAG)
.schedule(); .setConstraints(constraints)
.build();
WorkManager.getInstance(context).cancelAllWorkByTag(AppUpdateJob.TAG);
WorkManager.getInstance(context).enqueue(appUpdate);
scheduledJobId = appUpdate.getId();
} else if (scheduledJobId != null) { } else if (scheduledJobId != null) {
Log_.getInstance_(context).d(TAG, "Cancel rss checker job"); Log_.getInstance_(context).d(TAG, "Cancel app update checker job");
JobManager.instance().cancel(scheduledJobId); WorkManager.getInstance(context).cancelWorkById(scheduledJobId);
scheduledJobId = null;
} }
} }
@NonNull @NonNull
@Override @Override
protected Result onRunJob(@NonNull Params params) { public Result doWork() {
return AppUpdateJobRunner_.getInstance_(getContext()).run(); return AppUpdateJobRunner_.getInstance_(getApplicationContext()).run();
} }
} }

17
app/src/main/java/org/transdroid/core/service/AppUpdateJobRunner.java

@ -26,7 +26,8 @@ import android.net.Uri;
import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationCompat;
import com.evernote.android.job.Job; import androidx.work.ListenableWorker;
import androidx.work.Worker;
import org.androidannotations.annotations.Bean; import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.EBean; import org.androidannotations.annotations.EBean;
@ -73,16 +74,16 @@ public class AppUpdateJobRunner {
@SystemService @SystemService
protected NotificationManager notificationManager; protected NotificationManager notificationManager;
Job.Result run() { Worker.Result run() {
// Only run this service if app updates are handled via transdroid.org at all // Only run this service if app updates are handled via transdroid.org at all
if (!navigationHelper.enableUpdateChecker()) if (!navigationHelper.enableUpdateChecker())
return Job.Result.FAILURE; return Worker.Result.failure();
if (!connectivityHelper.shouldPerformBackgroundActions() || !systemSettings.checkForUpdates()) { if (!connectivityHelper.shouldPerformBackgroundActions() || !systemSettings.checkForUpdates()) {
log.d(this, "Skip the app update service, as background data is disabled, the service is explicitly " + log.d(this, "Skip the app update service, as background data is disabled, the service is explicitly " +
"disabled or we are not connected."); "disabled or we are not connected.");
return Job.Result.RESCHEDULE; return Worker.Result.retry();
} }
Date lastChecked = systemSettings.getLastCheckedForAppUpdates(); Date lastChecked = systemSettings.getLastCheckedForAppUpdates();
@ -91,7 +92,7 @@ public class AppUpdateJobRunner {
if (lastChecked != null && lastChecked.after(lastDay.getTime())) { if (lastChecked != null && lastChecked.after(lastDay.getTime())) {
log.d(this, "Skip the update service, as we already checked the last 24 hours (or to be exact at " log.d(this, "Skip the update service, as we already checked the last 24 hours (or to be exact at "
+ lastChecked.toString() + ")."); + lastChecked.toString() + ").");
return Job.Result.RESCHEDULE; return Worker.Result.retry();
} }
DefaultHttpClient httpclient = new DefaultHttpClient(); DefaultHttpClient httpclient = new DefaultHttpClient();
@ -124,7 +125,7 @@ public class AppUpdateJobRunner {
// New version of the search module? // New version of the search module?
try { try {
PackageInfo searchPackage = context.getPackageManager().getPackageInfo("org.transdroid.search", 0); PackageInfo searchPackage = context.getPackageManager().getPackageInfo("org.transdroid.search", 0);
log.d(this, "Local Transdroid Seach is at " + searchPackage.getLongVersionCode() log.d(this, "Local Transdroid Search is at " + searchPackage.getLongVersionCode()
+ " and the reported latest version is " + searchVersion); + " and the reported latest version is " + searchVersion);
if (searchPackage.getLongVersionCode() < searchVersion) { if (searchPackage.getLongVersionCode() < searchVersion) {
// New version available! Notify the user. // New version available! Notify the user.
@ -145,10 +146,10 @@ public class AppUpdateJobRunner {
} catch (Exception e) { } catch (Exception e) {
// Cannot check right now for some reason; log and ignore // Cannot check right now for some reason; log and ignore
log.d(this, "Cannot retrieve latest app or search module version code from the site: " + e.toString()); log.d(this, "Cannot retrieve latest app or search module version code from the site: " + e.toString());
return Job.Result.FAILURE; return Worker.Result.failure();
} }
return Job.Result.SUCCESS; return Worker.Result.success();
} }
/** /**

45
app/src/main/java/org/transdroid/core/service/RssCheckerJob.java

@ -16,45 +16,62 @@
*/ */
package org.transdroid.core.service; package org.transdroid.core.service;
import static java.security.AccessController.getContext;
import android.content.Context; import android.content.Context;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.evernote.android.job.Job; import androidx.work.Constraints;
import com.evernote.android.job.JobManager; import androidx.work.PeriodicWorkRequest;
import com.evernote.android.job.JobRequest; import androidx.work.Worker;
import androidx.work.WorkManager;
import androidx.work.NetworkType;
import androidx.work.WorkerParameters;
import org.transdroid.core.app.settings.NotificationSettings; import org.transdroid.core.app.settings.NotificationSettings;
import org.transdroid.core.app.settings.NotificationSettings_; import org.transdroid.core.app.settings.NotificationSettings_;
import org.transdroid.core.gui.log.Log_; import org.transdroid.core.gui.log.Log_;
public class RssCheckerJob extends Job { import java.util.UUID;
import java.util.concurrent.TimeUnit;
public class RssCheckerJob extends Worker {
static final String TAG = "rss_checker"; static final String TAG = "rss_checker";
private static Integer scheduledJobId; private static UUID scheduledJobId;
public RssCheckerJob(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
public static void schedule(Context context) { public static void schedule(Context context) {
NotificationSettings notificationSettings = NotificationSettings_.getInstance_(context); NotificationSettings notificationSettings = NotificationSettings_.getInstance_(context);
if (notificationSettings.isEnabledForRss()) { if (notificationSettings.isEnabledForRss()) {
Log_.getInstance_(context).d(TAG, "Schedule rss checker job"); Log_.getInstance_(context).d(TAG, "Schedule rss checker job");
NotificationChannels.ensureRssCheckerChannel(context, notificationSettings); NotificationChannels.ensureRssCheckerChannel(context, notificationSettings);
scheduledJobId = new JobRequest.Builder(RssCheckerJob.TAG) Constraints constraints = new Constraints.Builder()
.setPeriodic(notificationSettings.getInvervalInMilliseconds()) .setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiredNetworkType(JobRequest.NetworkType.CONNECTED) .build();
.setUpdateCurrent(true) PeriodicWorkRequest rssChecker = new PeriodicWorkRequest.Builder(RssCheckerJob.class, notificationSettings.getInvervalInMilliseconds(), TimeUnit.MILLISECONDS)
.build() .addTag(RssCheckerJob.TAG)
.schedule(); .setConstraints(constraints)
.build();
WorkManager.getInstance(context).cancelAllWorkByTag(RssCheckerJob.TAG);
WorkManager.getInstance(context).enqueue(rssChecker);
scheduledJobId = rssChecker.getId();
} else if (scheduledJobId != null) { } else if (scheduledJobId != null) {
Log_.getInstance_(context).d(TAG, "Cancel rss checker job"); Log_.getInstance_(context).d(TAG, "Cancel rss checker job");
JobManager.instance().cancel(scheduledJobId); WorkManager.getInstance(context).cancelWorkById(scheduledJobId);
scheduledJobId = null;
} }
} }
@NonNull @NonNull
@Override @Override
protected Result onRunJob(@NonNull Params params) { public Result doWork() {
return RssCheckerJobRunner_.getInstance_(getContext()).run(); return RssCheckerJobRunner_.getInstance_(getApplicationContext()).run();
} }
} }

11
app/src/main/java/org/transdroid/core/service/RssCheckerJobRunner.java

@ -22,8 +22,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationCompat;
import androidx.work.Worker;
import com.evernote.android.job.Job;
import org.androidannotations.annotations.Bean; import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.EBean; import org.androidannotations.annotations.EBean;
@ -59,12 +58,12 @@ public class RssCheckerJobRunner {
@SystemService @SystemService
protected NotificationManager notificationManager; protected NotificationManager notificationManager;
Job.Result run() { Worker.Result run() {
if (!connectivityHelper.shouldPerformBackgroundActions() || !notificationSettings.isEnabledForRss()) { if (!connectivityHelper.shouldPerformBackgroundActions() || !notificationSettings.isEnabledForRss()) {
log.d(this, log.d(this,
"Skip the RSS checker service, as background data is disabled, the service is disabled or we are not connected."); "Skip the RSS checker service, as background data is disabled, the service is disabled or we are not connected.");
return Job.Result.RESCHEDULE; return Worker.Result.retry();
} }
// Check every RSS feed for new items // Check every RSS feed for new items
@ -117,7 +116,7 @@ public class RssCheckerJobRunner {
if (unread == 0) { if (unread == 0) {
// No new items; just exit // No new items; just exit
return Job.Result.SUCCESS; return Worker.Result.success();
} }
// Provide a notification, since there are new RSS items // Provide a notification, since there are new RSS items
@ -140,7 +139,7 @@ public class RssCheckerJobRunner {
} }
notificationManager.notify(80001, builder.build()); notificationManager.notify(80001, builder.build());
return Job.Result.SUCCESS; return Worker.Result.success();
} }
} }

42
app/src/main/java/org/transdroid/core/service/ScheduledJobCreator.java

@ -1,42 +0,0 @@
/*
* Copyright 2010-2018 Eric Kok et al.
*
* Transdroid is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Transdroid is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Transdroid. If not, see <http://www.gnu.org/licenses/>.
*/
package org.transdroid.core.service;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.evernote.android.job.Job;
import com.evernote.android.job.JobCreator;
public class ScheduledJobCreator implements JobCreator {
@Nullable
@Override
public Job create(@NonNull String tag) {
switch (tag) {
case AppUpdateJob.TAG:
return new AppUpdateJob();
case RssCheckerJob.TAG:
return new RssCheckerJob();
case ServerCheckerJob.TAG:
return new ServerCheckerJob();
default:
return null;
}
}
}

45
app/src/main/java/org/transdroid/core/service/ServerCheckerJob.java

@ -20,41 +20,58 @@ import android.content.Context;
import androidx.annotation.NonNull; import androidx.annotation.NonNull;
import com.evernote.android.job.Job; import androidx.annotation.WorkerThread;
import com.evernote.android.job.JobManager; import androidx.work.Constraints;
import com.evernote.android.job.JobRequest; import androidx.work.PeriodicWorkRequest;
import androidx.work.Worker;
import androidx.work.WorkManager;
import androidx.work.NetworkType;
import androidx.work.WorkerParameters;
import org.transdroid.core.app.settings.NotificationSettings; import org.transdroid.core.app.settings.NotificationSettings;
import org.transdroid.core.app.settings.NotificationSettings_; import org.transdroid.core.app.settings.NotificationSettings_;
import org.transdroid.core.gui.log.Log_; import org.transdroid.core.gui.log.Log_;
public class ServerCheckerJob extends Job { import java.time.Period;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
public class ServerCheckerJob extends Worker {
static final String TAG = "server_checker"; static final String TAG = "server_checker";
private static Integer scheduledJobId; private static UUID scheduledJobId;
public ServerCheckerJob(@NonNull Context context, @NonNull WorkerParameters workerParams) {
super(context, workerParams);
}
public static void schedule(Context context) { public static void schedule(Context context) {
NotificationSettings notificationSettings = NotificationSettings_.getInstance_(context); NotificationSettings notificationSettings = NotificationSettings_.getInstance_(context);
if (notificationSettings.isEnabledForTorrents()) { if (notificationSettings.isEnabledForTorrents()) {
Log_.getInstance_(context).d(TAG, "Schedule server checker job"); Log_.getInstance_(context).d(TAG, "Schedule server checker job");
NotificationChannels.ensureServerCheckerChannel(context, notificationSettings); NotificationChannels.ensureServerCheckerChannel(context, notificationSettings);
scheduledJobId = new JobRequest.Builder(ServerCheckerJob.TAG) Constraints constraints = new Constraints.Builder()
.setPeriodic(notificationSettings.getInvervalInMilliseconds()) .setRequiredNetworkType(NetworkType.CONNECTED)
.setRequiredNetworkType(JobRequest.NetworkType.CONNECTED) .build();
.setUpdateCurrent(true) PeriodicWorkRequest serverChecker = new PeriodicWorkRequest.Builder(ServerCheckerJob.class, notificationSettings.getInvervalInMilliseconds(), TimeUnit.MILLISECONDS)
.build() .addTag(ServerCheckerJob.TAG)
.schedule(); .setConstraints(constraints)
.build();
WorkManager.getInstance(context).cancelAllWorkByTag(ServerCheckerJob.TAG);
WorkManager.getInstance(context).enqueue(serverChecker);
scheduledJobId = serverChecker.getId();
} else if (scheduledJobId != null) { } else if (scheduledJobId != null) {
Log_.getInstance_(context).d(TAG, "Cancel server checker job"); Log_.getInstance_(context).d(TAG, "Cancel server checker job");
JobManager.instance().cancel(scheduledJobId); WorkManager.getInstance(context).cancelWorkById(scheduledJobId);
scheduledJobId = null;
} }
} }
@NonNull @NonNull
@Override @Override
protected Result onRunJob(@NonNull Params params) { public Result doWork() {
return ServerCheckerJobRunner_.getInstance_(getContext()).run(); return ServerCheckerJobRunner_.getInstance_(getApplicationContext()).run();
} }
} }

8
app/src/main/java/org/transdroid/core/service/ServerCheckerJobRunner.java

@ -22,7 +22,7 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.text.TextUtils; import android.text.TextUtils;
import androidx.core.app.NotificationCompat; import androidx.core.app.NotificationCompat;
import com.evernote.android.job.Job; import androidx.work.Worker;
import org.androidannotations.annotations.Bean; import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.EBean; import org.androidannotations.annotations.EBean;
import org.androidannotations.annotations.RootContext; import org.androidannotations.annotations.RootContext;
@ -61,12 +61,12 @@ public class ServerCheckerJobRunner {
@SystemService @SystemService
protected NotificationManager notificationManager; protected NotificationManager notificationManager;
Job.Result run() { Worker.Result run() {
if (!connectivityHelper.shouldPerformBackgroundActions() || !notificationSettings.isEnabledForTorrents()) { if (!connectivityHelper.shouldPerformBackgroundActions() || !notificationSettings.isEnabledForTorrents()) {
log.d(this, log.d(this,
"Skip the server checker service, as background data is disabled, the service is disabled or we are not connected."); "Skip the server checker service, as background data is disabled, the service is disabled or we are not connected.");
return Job.Result.RESCHEDULE; return Worker.Result.retry();
} }
int notifyBase = 10000; int notifyBase = 10000;
@ -207,7 +207,7 @@ public class ServerCheckerJobRunner {
} }
return Job.Result.SUCCESS; return Worker.Result.success();
} }
private Boolean findLastDoneStat(JSONArray lastStats, Torrent torrent) { private Boolean findLastDoneStat(JSONArray lastStats, Torrent torrent) {

2
app/src/main/java/org/transdroid/daemon/Daemon.java

@ -337,7 +337,7 @@ public enum Daemon {
} }
public static boolean supportsStoppingStarting(Daemon type) { public static boolean supportsStoppingStarting(Daemon type) {
return type == uTorrent || type == rTorrent || type == BitTorrent || type == BitComet || type == Dummy; return type == uTorrent || type == rTorrent || type == BitTorrent || type == Dummy;
} }
public static boolean supportsForcedStarting(Daemon type) { public static boolean supportsForcedStarting(Daemon type) {

6
app/src/main/java/org/transdroid/daemon/Label.java

@ -69,6 +69,12 @@ public final class Label implements Parcelable, Comparable<Label> {
return name.compareTo(another.getName()); return name.compareTo(another.getName());
} }
@Override
public boolean equals(Object another) {
// compare names
return name.equals(((Label) another).getName());
}
@Override @Override
public int describeContents() { public int describeContents() {
return 0; return 0;

11
app/src/main/java/org/transdroid/daemon/adapters/bitComet/BitCometAdapter.java

@ -136,6 +136,8 @@ public class BitCometAdapter implements IDaemonAdapter {
return new RetrieveTaskSuccessResult((RetrieveTask) task, parseXmlTorrents(xmlResult), return new RetrieveTaskSuccessResult((RetrieveTask) task, parseXmlTorrents(xmlResult),
null); null);
} }
} catch (DaemonException e) {
throw e;
} catch (Exception e) { } catch (Exception e) {
// it's probably an old client, parse HTML instead // it's probably an old client, parse HTML instead
String htmlResult = makeRequest(log, "/panel/task_list"); String htmlResult = makeRequest(log, "/panel/task_list");
@ -243,7 +245,7 @@ public class BitCometAdapter implements IDaemonAdapter {
task.getMethod() + " is not supported by " + getType())); task.getMethod() + " is not supported by " + getType()));
} }
} catch (DaemonException e) { } catch (DaemonException e) {
return new DaemonTaskFailureResult(task, new DaemonException(ExceptionType.ParsingFailed, e.toString())); return new DaemonTaskFailureResult(task, e);
} }
} }
@ -290,6 +292,10 @@ public class BitCometAdapter implements IDaemonAdapter {
// Make the request // Make the request
HttpResponse response = httpclient.execute(new HttpGet(buildWebUIUrl(url))); HttpResponse response = httpclient.execute(new HttpGet(buildWebUIUrl(url)));
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == 401 || statusCode == 403) {
throw new DaemonException(ExceptionType.AuthenticationFailure, "Response code " + statusCode);
}
HttpEntity entity = response.getEntity(); HttpEntity entity = response.getEntity();
if (entity != null) { if (entity != null) {
@ -309,6 +315,9 @@ public class BitCometAdapter implements IDaemonAdapter {
throw new DaemonException(ExceptionType.ConnectionError, e.toString()); throw new DaemonException(ExceptionType.ConnectionError, e.toString());
} catch (Exception e) { } catch (Exception e) {
log.d(LOG_NAME, "Error: " + e.toString()); log.d(LOG_NAME, "Error: " + e.toString());
if (e instanceof DaemonException) {
throw (DaemonException) e;
}
throw new DaemonException(ExceptionType.ConnectionError, e.toString()); throw new DaemonException(ExceptionType.ConnectionError, e.toString());
} }

20
app/src/main/java/org/transdroid/daemon/adapters/qBittorrent/QBittorrentAdapter.java

@ -94,6 +94,8 @@ public class QBittorrentAdapter implements IDaemonAdapter {
private int qbLowPriority = 1; private int qbLowPriority = 1;
private int qbNormalPriority = 2; private int qbNormalPriority = 2;
private int qbHighPriority = 7; private int qbHighPriority = 7;
// a cache of all labels on the server
private List<Label> labelList;
public QBittorrentAdapter(DaemonSettings settings) { public QBittorrentAdapter(DaemonSettings settings) {
this.settings = settings; this.settings = settings;
@ -245,7 +247,7 @@ public class QBittorrentAdapter implements IDaemonAdapter {
if (allLabelsResult == null) { if (allLabelsResult == null) {
allLabelsResult = new JSONArray(); allLabelsResult = new JSONArray();
} }
final List<Label> labelList = parseJsonLabels(allLabelsResult, allTorrentsResult); labelList = parseJsonLabels(allLabelsResult, allTorrentsResult);
return new RetrieveTaskSuccessResult((RetrieveTask) task, torrentsList, labelList); return new RetrieveTaskSuccessResult((RetrieveTask) task, torrentsList, labelList);
case GetTorrentDetails: case GetTorrentDetails:
@ -446,6 +448,20 @@ public class QBittorrentAdapter implements IDaemonAdapter {
case SetLabel: case SetLabel:
SetLabelTask labelTask = (SetLabelTask) task; SetLabelTask labelTask = (SetLabelTask) task;
String newLabel = labelTask.getNewLabel();
if (version >= 30200) {
if (!labelList.contains(new Label(newLabel, 0))) {
// create new label on server side
if (version >= 40100) {
path = "/api/v2/torrents/createCategory";
} else {
path = "/command/addCategory";
}
makeRequest(log, path,
new BasicNameValuePair("category", newLabel));
}
}
if (version >= 40100) { if (version >= 40100) {
path = "/api/v2/torrents/setCategory"; path = "/api/v2/torrents/setCategory";
} else { } else {
@ -453,7 +469,7 @@ public class QBittorrentAdapter implements IDaemonAdapter {
} }
makeRequest(log, path, makeRequest(log, path,
new BasicNameValuePair("hashes", task.getTargetTorrent().getUniqueID()), new BasicNameValuePair("hashes", task.getTargetTorrent().getUniqueID()),
new BasicNameValuePair("category", labelTask.getNewLabel())); new BasicNameValuePair("category", newLabel));
return new DaemonTaskSuccessResult(task); return new DaemonTaskSuccessResult(task);
case SetDownloadLocation: case SetDownloadLocation:

2
app/src/main/java/org/transdroid/daemon/adapters/rTorrent/RTorrentAdapter.java

@ -219,6 +219,8 @@ public class RTorrentAdapter implements IDaemonAdapter {
if (removeTask.includingData()) { if (removeTask.includingData()) {
makeRtorrentCall(log, "d.custom5.set", makeRtorrentCall(log, "d.custom5.set",
new String[]{task.getTargetTorrent().getUniqueID(), "1"}); new String[]{task.getTargetTorrent().getUniqueID(), "1"});
makeRtorrentCall(log, "d.delete_tied",
new String[]{task.getTargetTorrent().getUniqueID()});
} }
makeRtorrentCall(log, "d.erase", new String[]{task.getTargetTorrent().getUniqueID()}); makeRtorrentCall(log, "d.erase", new String[]{task.getTargetTorrent().getUniqueID()});
return new DaemonTaskSuccessResult(task); return new DaemonTaskSuccessResult(task);

Loading…
Cancel
Save