use of de.danoeh.antennapod.net.sync.model.EpisodeAction in project AntennaPod by AntennaPod.
the class SyncService method processEpisodeActions.
private synchronized void processEpisodeActions(List<EpisodeAction> remoteActions) {
Log.d(TAG, "Processing " + remoteActions.size() + " actions");
if (remoteActions.size() == 0) {
return;
}
Map<Pair<String, String>, EpisodeAction> playActionsToUpdate = EpisodeActionFilter.getRemoteActionsOverridingLocalActions(remoteActions, synchronizationQueueStorage.getQueuedEpisodeActions());
LongList queueToBeRemoved = new LongList();
List<FeedItem> updatedItems = new ArrayList<>();
for (EpisodeAction action : playActionsToUpdate.values()) {
String guid = GuidValidator.isValidGuid(action.getGuid()) ? action.getGuid() : null;
FeedItem feedItem = DBReader.getFeedItemByGuidOrEpisodeUrl(guid, action.getEpisode());
if (feedItem == null) {
Log.i(TAG, "Unknown feed item: " + action);
continue;
}
if (feedItem.getMedia() == null) {
Log.i(TAG, "Feed item has no media: " + action);
continue;
}
if (action.getAction() == EpisodeAction.NEW) {
DBWriter.markItemPlayed(feedItem, FeedItem.UNPLAYED, true);
continue;
}
feedItem.getMedia().setPosition(action.getPosition() * 1000);
if (FeedItemUtil.hasAlmostEnded(feedItem.getMedia())) {
Log.d(TAG, "Marking as played: " + action);
feedItem.setPlayed(true);
feedItem.getMedia().setPosition(0);
queueToBeRemoved.add(feedItem.getId());
} else {
Log.d(TAG, "Setting position: " + action);
}
updatedItems.add(feedItem);
}
DBWriter.removeQueueItem(getApplicationContext(), false, queueToBeRemoved.toArray());
DBReader.loadAdditionalFeedItemListData(updatedItems);
DBWriter.setItemList(updatedItems);
}
use of de.danoeh.antennapod.net.sync.model.EpisodeAction in project AntennaPod by AntennaPod.
the class GpodnetService method uploadEpisodeActionsPartial.
private UploadChangesResponse uploadEpisodeActionsPartial(List<EpisodeAction> episodeActions, int from, int to) throws SyncServiceException {
try {
Log.d(TAG, "Uploading partial actions " + from + " to " + to + " of " + episodeActions.size());
URL url = new URI(baseScheme, null, baseHost, basePort, String.format("/api/2/episodes/%s.json", username), null, null).toURL();
final JSONArray list = new JSONArray();
for (int i = from; i < to; i++) {
EpisodeAction episodeAction = episodeActions.get(i);
JSONObject obj = episodeAction.writeToJsonObject();
if (obj != null) {
obj.put("device", deviceId);
list.put(obj);
}
}
RequestBody body = RequestBody.create(JSON, list.toString());
Request.Builder request = new Request.Builder().post(body).url(url);
final String response = executeRequest(request);
return GpodnetEpisodeActionPostResponse.fromJSONObject(response);
} catch (JSONException | MalformedURLException | URISyntaxException e) {
e.printStackTrace();
throw new SyncServiceException(e);
}
}
use of de.danoeh.antennapod.net.sync.model.EpisodeAction in project AntennaPod by AntennaPod.
the class DBWriter method deleteFeedMediaSynchronous.
private static boolean deleteFeedMediaSynchronous(@NonNull Context context, @NonNull FeedMedia media) {
Log.i(TAG, String.format(Locale.US, "Requested to delete FeedMedia [id=%d, title=%s, downloaded=%s", media.getId(), media.getEpisodeTitle(), media.isDownloaded()));
if (media.isDownloaded()) {
// delete downloaded media file
File mediaFile = new File(media.getFile_url());
if (mediaFile.exists() && !mediaFile.delete()) {
MessageEvent evt = new MessageEvent(context.getString(R.string.delete_failed));
EventBus.getDefault().post(evt);
return false;
}
media.setDownloaded(false);
media.setFile_url(null);
media.setHasEmbeddedPicture(false);
PodDBAdapter adapter = PodDBAdapter.getInstance();
adapter.open();
adapter.setMedia(media);
adapter.close();
if (media.getId() == PlaybackPreferences.getCurrentlyPlayingFeedMediaId()) {
PlaybackPreferences.writeNoMediaPlaying();
IntentUtils.sendLocalBroadcast(context, PlaybackService.ACTION_SHUTDOWN_PLAYBACK_SERVICE);
NotificationManagerCompat nm = NotificationManagerCompat.from(context);
nm.cancel(R.id.notification_playing);
}
// Gpodder: queue delete action for synchronization
FeedItem item = media.getItem();
EpisodeAction action = new EpisodeAction.Builder(item, EpisodeAction.DELETE).currentTimestamp().build();
SynchronizationQueueSink.enqueueEpisodeActionIfSynchronizationIsActive(context, action);
}
EventBus.getDefault().post(FeedItemEvent.deletedMedia(Collections.singletonList(media.getItem())));
return true;
}
use of de.danoeh.antennapod.net.sync.model.EpisodeAction in project AntennaPod by AntennaPod.
the class SyncService method syncEpisodeActions.
private void syncEpisodeActions(ISyncService syncServiceImpl) throws SyncServiceException {
final long lastSync = SynchronizationSettings.getLastEpisodeActionSynchronizationTimestamp();
EventBus.getDefault().postSticky(new SyncServiceEvent(R.string.sync_status_episodes_download));
EpisodeActionChanges getResponse = syncServiceImpl.getEpisodeActionChanges(lastSync);
long newTimeStamp = getResponse.getTimestamp();
List<EpisodeAction> remoteActions = getResponse.getEpisodeActions();
processEpisodeActions(remoteActions);
// upload local actions
EventBus.getDefault().postSticky(new SyncServiceEvent(R.string.sync_status_episodes_upload));
List<EpisodeAction> queuedEpisodeActions = synchronizationQueueStorage.getQueuedEpisodeActions();
if (lastSync == 0) {
EventBus.getDefault().postSticky(new SyncServiceEvent(R.string.sync_status_upload_played));
List<FeedItem> readItems = DBReader.getPlayedItems();
Log.d(TAG, "First sync. Upload state for all " + readItems.size() + " played episodes");
for (FeedItem item : readItems) {
FeedMedia media = item.getMedia();
if (media == null) {
continue;
}
EpisodeAction played = new EpisodeAction.Builder(item, EpisodeAction.PLAY).currentTimestamp().started(media.getDuration() / 1000).position(media.getDuration() / 1000).total(media.getDuration() / 1000).build();
queuedEpisodeActions.add(played);
}
}
if (queuedEpisodeActions.size() > 0) {
LockingAsyncExecutor.lock.lock();
try {
Log.d(TAG, "Uploading " + queuedEpisodeActions.size() + " actions: " + StringUtils.join(queuedEpisodeActions, ", "));
UploadChangesResponse postResponse = syncServiceImpl.uploadEpisodeActions(queuedEpisodeActions);
newTimeStamp = postResponse.timestamp;
Log.d(TAG, "Upload episode response: " + postResponse);
synchronizationQueueStorage.clearEpisodeActionQueue();
} finally {
LockingAsyncExecutor.lock.unlock();
}
}
SynchronizationSettings.setLastEpisodeActionSynchronizationAttemptTimestamp(newTimeStamp);
}
use of de.danoeh.antennapod.net.sync.model.EpisodeAction in project AntennaPod by AntennaPod.
the class SynchronizationQueueSink method enqueueEpisodePlayedIfSynchronizationIsActive.
public static void enqueueEpisodePlayedIfSynchronizationIsActive(Context context, FeedMedia media, boolean completed) {
if (!SynchronizationSettings.isProviderConnected()) {
return;
}
if (media.getItem() == null) {
return;
}
if (media.getStartPosition() < 0 || (!completed && media.getStartPosition() >= media.getPosition())) {
return;
}
EpisodeAction action = new EpisodeAction.Builder(media.getItem(), EpisodeAction.PLAY).currentTimestamp().started(media.getStartPosition() / 1000).position((completed ? media.getDuration() : media.getPosition()) / 1000).total(media.getDuration() / 1000).build();
enqueueEpisodeActionIfSynchronizationIsActive(context, action);
}
Aggregations