summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorTom Hennen <TomHennen@users.noreply.github.com>2015-05-13 21:06:50 -0400
committerTom Hennen <TomHennen@users.noreply.github.com>2015-05-13 21:06:50 -0400
commit73c4dfc04db814e6f2b4b2234150a404c2ec6cfa (patch)
tree2147c8945080a20699aebcc34631cfabb4e4fd74 /core
parentcf16cac089169e56736df13b2a9d75e40fbd7289 (diff)
parent108daed5a95a3aaded136538d1e1364791b602f0 (diff)
downloadAntennaPod-73c4dfc04db814e6f2b4b2234150a404c2ec6cfa.zip
Merge pull request #809 from mfietz/fix/gpodder-sync
Gpodder synchronization fixes
Diffstat (limited to 'core')
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/gpoddernet/model/GpodnetEpisodeAction.java2
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/preferences/GpodnetPreferences.java5
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/service/GpodnetSyncService.java146
-rw-r--r--core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java8
4 files changed, 108 insertions, 53 deletions
diff --git a/core/src/main/java/de/danoeh/antennapod/core/gpoddernet/model/GpodnetEpisodeAction.java b/core/src/main/java/de/danoeh/antennapod/core/gpoddernet/model/GpodnetEpisodeAction.java
index 0c431d60b..bd6210d13 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/gpoddernet/model/GpodnetEpisodeAction.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/gpoddernet/model/GpodnetEpisodeAction.java
@@ -258,7 +258,7 @@ public class GpodnetEpisodeAction {
private int total = -1;
public Builder(FeedItem item, Action action) {
- this(item.getFeed().getDownload_url(), item.getItemIdentifier(), action);
+ this(item.getFeed().getDownload_url(), item.getMedia().getDownload_url(), action);
}
public Builder(String podcast, String episode, Action action) {
diff --git a/core/src/main/java/de/danoeh/antennapod/core/preferences/GpodnetPreferences.java b/core/src/main/java/de/danoeh/antennapod/core/preferences/GpodnetPreferences.java
index cfdd0c5d6..c3c6ce8c5 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/preferences/GpodnetPreferences.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/preferences/GpodnetPreferences.java
@@ -173,7 +173,7 @@ public class GpodnetPreferences {
writePreference(PREF_SYNC_REMOVED, removedFeeds);
}
feedListLock.unlock();
- GpodnetSyncService.sendSyncIntent(ClientConfig.applicationCallbacks.getApplicationInstance());
+ GpodnetSyncService.sendSyncSubscriptionsIntent(ClientConfig.applicationCallbacks.getApplicationInstance());
}
public static void addRemovedFeed(String feed) {
@@ -186,7 +186,7 @@ public class GpodnetPreferences {
writePreference(PREF_SYNC_ADDED, addedFeeds);
}
feedListLock.unlock();
- GpodnetSyncService.sendSyncIntent(ClientConfig.applicationCallbacks.getApplicationInstance());
+ GpodnetSyncService.sendSyncSubscriptionsIntent(ClientConfig.applicationCallbacks.getApplicationInstance());
}
public static Set<String> getAddedFeedsCopy() {
@@ -225,6 +225,7 @@ public class GpodnetPreferences {
ensurePreferencesLoaded();
queuedEpisodeActions.add(action);
writePreference(PREF_SYNC_EPISODE_ACTIONS, writeEpisodeActionsToString(queuedEpisodeActions));
+ GpodnetSyncService.sendSyncActionsIntent(ClientConfig.applicationCallbacks.getApplicationInstance());
}
public static List<GpodnetEpisodeAction> getQueuedEpisodeActions() {
diff --git a/core/src/main/java/de/danoeh/antennapod/core/service/GpodnetSyncService.java b/core/src/main/java/de/danoeh/antennapod/core/service/GpodnetSyncService.java
index 6e318dd36..3f2222f42 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/service/GpodnetSyncService.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/service/GpodnetSyncService.java
@@ -12,7 +12,6 @@ import android.util.Log;
import android.util.Pair;
import java.util.Collection;
-import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
@@ -22,6 +21,7 @@ import de.danoeh.antennapod.core.ClientConfig;
import de.danoeh.antennapod.core.R;
import de.danoeh.antennapod.core.feed.Feed;
import de.danoeh.antennapod.core.feed.FeedItem;
+import de.danoeh.antennapod.core.feed.FeedMedia;
import de.danoeh.antennapod.core.gpoddernet.GpodnetService;
import de.danoeh.antennapod.core.gpoddernet.GpodnetServiceAuthenticationException;
import de.danoeh.antennapod.core.gpoddernet.GpodnetServiceException;
@@ -50,17 +50,38 @@ public class GpodnetSyncService extends Service {
public static final String ARG_ACTION = "action";
public static final String ACTION_SYNC = "de.danoeh.antennapod.intent.action.sync";
+ public static final String ACTION_SYNC_SUBSCRIPTIONS = "de.danoeh.antennapod.intent.action.sync_subscriptions";
+ public static final String ACTION_SYNC_ACTIONS = "de.danoeh.antennapod.intent.action.sync_ACTIONS";
private GpodnetService service;
+ private boolean syncSubscriptions = false;
+ private boolean syncActions = false;
+
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
final String action = (intent != null) ? intent.getStringExtra(ARG_ACTION) : null;
- if (action != null && action.equals(ACTION_SYNC)) {
- Log.d(TAG, String.format("Waiting %d milliseconds before uploading changes", WAIT_INTERVAL));
- syncWaiterThread.restart();
+ if (action != null) {
+ switch(action) {
+ case ACTION_SYNC:
+ syncSubscriptions = true;
+ syncActions = true;
+ break;
+ case ACTION_SYNC_SUBSCRIPTIONS:
+ syncSubscriptions = true;
+ break;
+ case ACTION_SYNC_ACTIONS:
+ syncActions = true;
+ break;
+ default:
+ Log.e(TAG, "Received invalid intent: action argument is invalid");
+ }
+ if(syncSubscriptions || syncActions) {
+ Log.d(TAG, String.format("Waiting %d milliseconds before uploading changes", WAIT_INTERVAL));
+ syncWaiterThread.restart();
+ }
} else {
- Log.e(TAG, "Received invalid intent: action argument is null or invalid");
+ Log.e(TAG, "Received invalid intent: action argument is null");
}
return START_FLAG_REDELIVERY;
}
@@ -91,8 +112,14 @@ public class GpodnetSyncService extends Service {
stopSelf();
return;
}
- syncSubscriptionChanges();
- syncEpisodeActions();
+ if(syncSubscriptions) {
+ syncSubscriptionChanges();
+ syncSubscriptions = false;
+ }
+ if(syncActions) {
+ syncEpisodeActions();
+ syncActions = false;
+ }
stopSelf();
}
@@ -100,37 +127,36 @@ public class GpodnetSyncService extends Service {
final long timestamp = GpodnetPreferences.getLastSubscriptionSyncTimestamp();
try {
final List<String> localSubscriptions = DBReader.getFeedListDownloadUrls(this);
+ Collection<String> localAdded = GpodnetPreferences.getAddedFeedsCopy();
+ Collection<String> localRemoved = GpodnetPreferences.getRemovedFeedsCopy();
GpodnetService service = tryLogin();
// first sync: download all subscriptions...
GpodnetSubscriptionChange subscriptionChanges = service.getSubscriptionChanges(GpodnetPreferences.getUsername(),
GpodnetPreferences.getDeviceID(), timestamp);
- long lastUpdate = subscriptionChanges.getTimestamp();
+ long newTimeStamp = subscriptionChanges.getTimestamp();
Log.d(TAG, "Downloaded subscription changes: " + subscriptionChanges);
- processSubscriptionChanges(localSubscriptions, subscriptionChanges);
-
- Collection<String> added;
- Collection<String> removed;
- if (timestamp == 0) {
- added = localSubscriptions;
- GpodnetPreferences.removeRemovedFeeds(GpodnetPreferences.getRemovedFeedsCopy());
- removed = Collections.emptyList();
- } else {
- added = GpodnetPreferences.getAddedFeedsCopy();
- removed = GpodnetPreferences.getRemovedFeedsCopy();
+ processSubscriptionChanges(localSubscriptions, localAdded, localRemoved, subscriptionChanges);
+
+ if(timestamp == 0) {
+ // this is this apps first sync with gpodder:
+ // only submit changes gpodder has not just sent us
+ localAdded = localSubscriptions;
+ localAdded.removeAll(subscriptionChanges.getAdded());
+ localRemoved.removeAll(subscriptionChanges.getRemoved());
}
- if(added.size() > 0 || removed.size() > 0) {
+ if(localAdded.size() > 0 || localRemoved.size() > 0) {
Log.d(TAG, String.format("Uploading subscriptions, Added: %s\nRemoved: %s",
- added, removed));
+ localAdded, localRemoved));
GpodnetUploadChangesResponse uploadResponse = service.uploadChanges(GpodnetPreferences.getUsername(),
- GpodnetPreferences.getDeviceID(), added, removed);
- lastUpdate = uploadResponse.timestamp;
+ GpodnetPreferences.getDeviceID(), localAdded, localRemoved);
+ newTimeStamp = uploadResponse.timestamp;
Log.d(TAG, "Upload changes response: " + uploadResponse);
- GpodnetPreferences.removeAddedFeeds(added);
- GpodnetPreferences.removeRemovedFeeds(removed);
+ GpodnetPreferences.removeAddedFeeds(localAdded);
+ GpodnetPreferences.removeRemovedFeeds(localRemoved);
}
- GpodnetPreferences.setLastSubscriptionSyncTimestamp(lastUpdate);
+ GpodnetPreferences.setLastSubscriptionSyncTimestamp(newTimeStamp);
clearErrorNotifications();
} catch (GpodnetServiceException e) {
e.printStackTrace();
@@ -140,6 +166,27 @@ public class GpodnetSyncService extends Service {
}
}
+ private synchronized void processSubscriptionChanges(List<String> localSubscriptions,
+ Collection<String> localAdded,
+ Collection<String> localRemoved,
+ GpodnetSubscriptionChange changes) throws DownloadRequestException {
+ // local changes are always superior to remote changes!
+ // add subscription if (1) not already subscribed and (2) not just unsubscribed
+ for (String downloadUrl : changes.getAdded()) {
+ if (false == localSubscriptions.contains(downloadUrl) &&
+ false == localRemoved.contains(downloadUrl)) {
+ Feed feed = new Feed(downloadUrl, new Date(0));
+ DownloadRequester.getInstance().downloadFeed(this, feed);
+ }
+ }
+ // remove subscription if not just subscribed (again)
+ for (String downloadUrl : changes.getRemoved()) {
+ if(false == localAdded.contains(downloadUrl)) {
+ DBTasks.removeFeedWithDownloadUrl(GpodnetSyncService.this, downloadUrl);
+ }
+ }
+ }
+
private synchronized void syncEpisodeActions() {
final long timestamp = GpodnetPreferences.getLastEpisodeActionsSyncTimestamp();
Log.d(TAG, "last episode actions sync timestamp: " + timestamp);
@@ -173,25 +220,13 @@ public class GpodnetSyncService extends Service {
}
}
- private synchronized void processSubscriptionChanges(List<String> localSubscriptions, GpodnetSubscriptionChange changes) throws DownloadRequestException {
- for (String downloadUrl : changes.getAdded()) {
- if (!localSubscriptions.contains(downloadUrl)) {
- Feed feed = new Feed(downloadUrl, new Date(0));
- DownloadRequester.getInstance().downloadFeed(this, feed);
- }
- }
- for (String downloadUrl : changes.getRemoved()) {
- DBTasks.removeFeedWithDownloadUrl(GpodnetSyncService.this, downloadUrl);
- }
- }
- private synchronized void processEpisodeActions(List<GpodnetEpisodeAction> localActions, List<GpodnetEpisodeAction> remoteActions) throws DownloadRequestException {
+ private synchronized void processEpisodeActions(List<GpodnetEpisodeAction> localActions,
+ List<GpodnetEpisodeAction> remoteActions) throws DownloadRequestException {
if(remoteActions.size() == 0) {
return;
}
Map<Pair<String, String>, GpodnetEpisodeAction> localMostRecentPlayAction = new HashMap<Pair<String, String>, GpodnetEpisodeAction>();
- Map<Pair<String, String>, GpodnetEpisodeAction> remoteMostRecentPlayAction = new HashMap<Pair<String, String>, GpodnetEpisodeAction>();
- // make sure more recent local actions are not overwritten by older remote actions
for(GpodnetEpisodeAction action : localActions) {
Pair key = new Pair(action.getPodcast(), action.getEpisode());
GpodnetEpisodeAction mostRecent = localMostRecentPlayAction.get(key);
@@ -201,6 +236,9 @@ public class GpodnetSyncService extends Service {
localMostRecentPlayAction.put(key, action);
}
}
+
+ // make sure more recent local actions are not overwritten by older remote actions
+ Map<Pair<String, String>, GpodnetEpisodeAction> mostRecentPlayAction = new HashMap<Pair<String, String>, GpodnetEpisodeAction>();
for (GpodnetEpisodeAction action : remoteActions) {
switch (action.getAction()) {
case NEW:
@@ -218,11 +256,11 @@ public class GpodnetSyncService extends Service {
GpodnetEpisodeAction localMostRecent = localMostRecentPlayAction.get(key);
if(localMostRecent == null ||
localMostRecent.getTimestamp().before(action.getTimestamp())) {
- GpodnetEpisodeAction mostRecent = remoteMostRecentPlayAction.get(key);
+ GpodnetEpisodeAction mostRecent = mostRecentPlayAction.get(key);
if (mostRecent == null) {
- remoteMostRecentPlayAction.put(key, action);
+ mostRecentPlayAction.put(key, action);
} else if (mostRecent.getTimestamp().before(action.getTimestamp())) {
- remoteMostRecentPlayAction.put(key, action);
+ mostRecentPlayAction.put(key, action);
}
}
break;
@@ -231,10 +269,12 @@ public class GpodnetSyncService extends Service {
break;
}
}
- for (GpodnetEpisodeAction action : remoteMostRecentPlayAction.values()) {
+ for (GpodnetEpisodeAction action : mostRecentPlayAction.values()) {
FeedItem playItem = DBReader.getFeedItem(this, action.getPodcast(), action.getEpisode());
if (playItem != null) {
- playItem.getMedia().setPosition(action.getPosition() * 1000);
+ FeedMedia media = playItem.getMedia();
+ media.setPosition(action.getPosition() * 1000);
+ DBWriter.setFeedMedia(this, media);
if(playItem.getMedia().hasAlmostEnded()) {
DBWriter.markItemRead(this, playItem, true, true);
DBWriter.addItemToPlaybackHistory(this, playItem.getMedia());
@@ -342,4 +382,20 @@ public class GpodnetSyncService extends Service {
context.startService(intent);
}
}
+
+ public static void sendSyncSubscriptionsIntent(Context context) {
+ if (GpodnetPreferences.loggedIn()) {
+ Intent intent = new Intent(context, GpodnetSyncService.class);
+ intent.putExtra(ARG_ACTION, ACTION_SYNC_SUBSCRIPTIONS);
+ context.startService(intent);
+ }
+ }
+
+ public static void sendSyncActionsIntent(Context context) {
+ if (GpodnetPreferences.loggedIn()) {
+ Intent intent = new Intent(context, GpodnetSyncService.class);
+ intent.putExtra(ARG_ACTION, ACTION_SYNC_ACTIONS);
+ context.startService(intent);
+ }
+ }
}
diff --git a/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java b/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java
index 1ec5a0949..ecbfce5e0 100644
--- a/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java
+++ b/core/src/main/java/de/danoeh/antennapod/core/storage/DBTasks.java
@@ -171,10 +171,10 @@ public final class DBTasks {
isRefreshing.set(false);
if (FlattrUtils.hasToken()) {
- if (BuildConfig.DEBUG) Log.d(TAG, "Flattring all pending things.");
+ Log.d(TAG, "Flattring all pending things.");
new FlattrClickWorker(context).executeAsync(); // flattr pending things
- if (BuildConfig.DEBUG) Log.d(TAG, "Fetching flattr status.");
+ Log.d(TAG, "Fetching flattr status.");
new FlattrStatusFetcher(context).start();
}
@@ -185,9 +185,7 @@ public final class DBTasks {
}
}.start();
} else {
- if (BuildConfig.DEBUG)
- Log.d(TAG,
- "Ignoring request to refresh all feeds: Refresh lock is locked");
+ Log.d(TAG, "Ignoring request to refresh all feeds: Refresh lock is locked");
}
}