148 lines
5.9 KiB
Java
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);
|
|
}
|
|
}
|