lbry-android/app/src/main/java/io/lbry/browser/tasks/MergeSubscriptionsTask.java
2020-06-25 21:16:41 +01:00

148 lines
5.9 KiB
Java

package io.lbry.browser.tasks;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.os.AsyncTask;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import io.lbry.browser.MainActivity;
import io.lbry.browser.data.DatabaseHelper;
import io.lbry.browser.exceptions.LbryUriException;
import io.lbry.browser.exceptions.LbryioRequestException;
import io.lbry.browser.exceptions.LbryioResponseException;
import io.lbry.browser.model.lbryinc.Subscription;
import io.lbry.browser.utils.Helper;
import io.lbry.browser.utils.LbryUri;
import io.lbry.browser.utils.Lbryio;
import okhttp3.Response;
// background task to create a diff of local and remote subscriptions and try to merge
public class MergeSubscriptionsTask extends AsyncTask<Void, Void, List<Subscription>> {
private static final String TAG = "MergeSubscriptionsTask";
private Context context;
private List<Subscription> base;
private List<Subscription> diff;
private MergeSubscriptionsHandler handler;
private Exception error;
private boolean replaceLocal;
public MergeSubscriptionsTask(List<Subscription> base, boolean replaceLocal, Context context, MergeSubscriptionsHandler handler) {
this.base = base;
this.replaceLocal = replaceLocal;
this.context = context;
this.handler = handler;
}
protected List<Subscription> doInBackground(Void... params) {
List<Subscription> combined = new ArrayList<>(base);
List<Subscription> localSubs = new ArrayList<>();
List<Subscription> remoteSubs = new ArrayList<>();
diff = new ArrayList<>();
SQLiteDatabase db = null;
try {
// fetch local subscriptions
if (context instanceof MainActivity) {
db = ((MainActivity) context).getDbHelper().getWritableDatabase();
}
if (db != null) {
if (replaceLocal) {
DatabaseHelper.clearSubscriptions(db);
for (Subscription sub : base) {
DatabaseHelper.createOrUpdateSubscription(sub, db);
}
} else {
localSubs = DatabaseHelper.getSubscriptions(db);
for (Subscription sub : localSubs) {
if (!combined.contains(sub)) {
combined.add(sub);
}
}
}
}
// fetch remote subscriptions
JSONArray array = (JSONArray) Lbryio.parseResponse(Lbryio.call("subscription", "list", context));
if (array != null) {
for (int i = 0; i < array.length(); i++) {
JSONObject item = array.getJSONObject(i);
String claimId = item.getString("claim_id");
String channelName = item.getString("channel_name");
LbryUri url = new LbryUri();
url.setChannelName(channelName);
url.setClaimId(claimId);
Subscription subscription = new Subscription(channelName, url.toString());
remoteSubs.add(subscription);
}
}
for (int i = 0; i < combined.size(); i++) {
Subscription local = combined.get(i);
if (!remoteSubs.contains(local)) {
// add to remote subscriptions
try {
LbryUri uri = LbryUri.parse(local.getUrl());
Map<String, String> options = new HashMap<>();
String channelClaimId = uri.getChannelClaimId();
String channelName = Helper.normalizeChannelName(local.getChannelName());
if (!Helper.isNullOrEmpty(channelClaimId) && !Helper.isNullOrEmpty(channelName)) {
options.put("claim_id", channelClaimId);
options.put("channel_name", channelName);
Lbryio.parseResponse(Lbryio.call("subscription", "new", options, context));
}
} catch (LbryUriException | LbryioRequestException | LbryioResponseException ex) {
// pass
Log.e(TAG, String.format("subscription/new failed: %s", ex.getMessage()), ex);
}
}
}
if (!replaceLocal) {
for (int i = 0; i < localSubs.size(); i++) {
Subscription local = localSubs.get(i);
if (!base.contains(local) && !diff.contains(local)) {
diff.add(local);
}
}
}
for (int i = 0; i < remoteSubs.size(); i++) {
Subscription remote = remoteSubs.get(i);
if (!combined.contains(remote)) {
combined.add(remote);
if (!diff.contains(remote)) {
diff.add(remote);
}
}
}
} catch (ClassCastException | LbryioRequestException | LbryioResponseException | JSONException | IllegalStateException | SQLiteException ex) {
error = ex;
return null;
}
return combined;
}
protected void onPostExecute(List<Subscription> subscriptions) {
if (handler != null) {
if (subscriptions != null) {
handler.onSuccess(subscriptions, diff);
} else {
handler.onError(error);
}
}
}
public interface MergeSubscriptionsHandler {
void onSuccess(List<Subscription> subscriptions, List<Subscription> diff);
void onError(Exception error);
}
}