Search in sources :

Example 11 with EpisodeAction

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);
}
Also used : FeedItem(de.danoeh.antennapod.model.feed.FeedItem) ArrayList(java.util.ArrayList) LongList(de.danoeh.antennapod.core.util.LongList) EpisodeAction(de.danoeh.antennapod.net.sync.model.EpisodeAction) Pair(androidx.core.util.Pair)

Example 12 with EpisodeAction

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);
    }
}
Also used : MalformedURLException(java.net.MalformedURLException) JSONArray(org.json.JSONArray) Request(okhttp3.Request) JSONException(org.json.JSONException) URISyntaxException(java.net.URISyntaxException) URI(java.net.URI) URL(java.net.URL) EpisodeAction(de.danoeh.antennapod.net.sync.model.EpisodeAction) JSONObject(org.json.JSONObject) SyncServiceException(de.danoeh.antennapod.net.sync.model.SyncServiceException) RequestBody(okhttp3.RequestBody)

Example 13 with EpisodeAction

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;
}
Also used : FeedItem(de.danoeh.antennapod.model.feed.FeedItem) MessageEvent(de.danoeh.antennapod.event.MessageEvent) NotificationManagerCompat(androidx.core.app.NotificationManagerCompat) File(java.io.File) EpisodeAction(de.danoeh.antennapod.net.sync.model.EpisodeAction)

Example 14 with EpisodeAction

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);
}
Also used : FeedItem(de.danoeh.antennapod.model.feed.FeedItem) FeedMedia(de.danoeh.antennapod.model.feed.FeedMedia) SyncServiceEvent(de.danoeh.antennapod.event.SyncServiceEvent) UploadChangesResponse(de.danoeh.antennapod.net.sync.model.UploadChangesResponse) EpisodeActionChanges(de.danoeh.antennapod.net.sync.model.EpisodeActionChanges) EpisodeAction(de.danoeh.antennapod.net.sync.model.EpisodeAction)

Example 15 with EpisodeAction

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);
}
Also used : EpisodeAction(de.danoeh.antennapod.net.sync.model.EpisodeAction)

Aggregations

EpisodeAction (de.danoeh.antennapod.net.sync.model.EpisodeAction)17 ArrayList (java.util.ArrayList)8 Pair (androidx.core.util.Pair)7 FeedItem (de.danoeh.antennapod.model.feed.FeedItem)5 Date (java.util.Date)5 SimpleDateFormat (java.text.SimpleDateFormat)4 JSONArray (org.json.JSONArray)4 FeedMedia (de.danoeh.antennapod.model.feed.FeedMedia)3 JSONException (org.json.JSONException)3 JSONObject (org.json.JSONObject)3 DownloadStatus (de.danoeh.antennapod.core.service.download.DownloadStatus)2 EpisodeActionChanges (de.danoeh.antennapod.net.sync.model.EpisodeActionChanges)2 SyncServiceException (de.danoeh.antennapod.net.sync.model.SyncServiceException)2 File (java.io.File)2 MalformedURLException (java.net.MalformedURLException)2 ExecutionException (java.util.concurrent.ExecutionException)2 RequestBody (okhttp3.RequestBody)2 Context (android.content.Context)1 MediaMetadataRetriever (android.media.MediaMetadataRetriever)1 NonNull (androidx.annotation.NonNull)1