Search in sources :

Example 1 with SgEpisode2UpdateByNumber

use of com.battlelancer.seriesguide.provider.SgEpisode2UpdateByNumber in project SeriesGuide by UweTrottmann.

the class HexagonEpisodeSync method downloadFlagsByTmdbId.

private DownloadFlagsResult downloadFlagsByTmdbId(long showId, int showTmdbId) {
    List<SgCloudEpisode> episodes;
    boolean onFirstPage = true;
    boolean hasMoreEpisodes = true;
    String cursor = null;
    Long lastWatchedMs = null;
    while (hasMoreEpisodes) {
        // abort if connection is lost
        if (!AndroidUtils.isNetworkConnected(context)) {
            Timber.e("downloadFlags: no network connection");
            return DownloadFlagsResult.FAILED;
        }
        try {
            // get service each time to check if auth was removed
            Episodes episodesService = hexagonTools.getEpisodesService();
            if (episodesService == null) {
                return DownloadFlagsResult.FAILED;
            }
            // build request
            Episodes.GetSgEpisodes request = episodesService.getSgEpisodes().setShowTmdbId(// use default server limit
            showTmdbId);
            if (!TextUtils.isEmpty(cursor)) {
                request.setCursor(cursor);
            }
            // execute request
            SgCloudEpisodeList response = request.execute();
            if (response == null) {
                // If empty should send status 200 and empty list, so no body is a failure.
                return DownloadFlagsResult.FAILED;
            }
            episodes = response.getEpisodes();
            // check for more items
            if (response.getCursor() != null) {
                cursor = response.getCursor();
            } else {
                hasMoreEpisodes = false;
            }
        } catch (IOException | IllegalArgumentException e) {
            // Note: JSON parser may throw IllegalArgumentException.
            Errors.logAndReportHexagon("get episodes of show", e);
            return DownloadFlagsResult.FAILED;
        }
        if (episodes == null || episodes.size() == 0) {
            if (onFirstPage) {
                // If there is no data by TMDB ID at all, try again using TVDB ID.
                return DownloadFlagsResult.NO_DATA;
            } else {
                // no more updates to apply
                break;
            }
        }
        onFirstPage = false;
        // build batch of episode flag updates
        ArrayList<SgEpisode2UpdateByNumber> batch = new ArrayList<>();
        for (SgCloudEpisode episode : episodes) {
            Pair<SgEpisode2UpdateByNumber, Long> update = buildSgEpisodeUpdate(episode.getWatchedFlag(), episode.getPlays(), episode.getIsInCollection(), episode.getUpdatedAt(), episode.getEpisodeNumber(), episode.getSeasonNumber(), showId, lastWatchedMs);
            if (update != null) {
                batch.add(update.first);
                lastWatchedMs = update.second;
            }
        }
        // execute database update
        SgRoomDatabase.getInstance(context).sgEpisode2Helper().updateWatchedAndCollectedByNumber(batch);
    }
    return new DownloadFlagsResult(true, false, lastWatchedMs);
}
Also used : SgCloudEpisode(com.uwetrottmann.seriesguide.backend.episodes.model.SgCloudEpisode) SgCloudEpisodeList(com.uwetrottmann.seriesguide.backend.episodes.model.SgCloudEpisodeList) ArrayList(java.util.ArrayList) IOException(java.io.IOException) SgEpisode2UpdateByNumber(com.battlelancer.seriesguide.provider.SgEpisode2UpdateByNumber) Episodes(com.uwetrottmann.seriesguide.backend.episodes.Episodes)

Example 2 with SgEpisode2UpdateByNumber

use of com.battlelancer.seriesguide.provider.SgEpisode2UpdateByNumber in project SeriesGuide by UweTrottmann.

the class HexagonEpisodeSync method downloadChangedFlags.

/**
 * Downloads all episodes changed since the last time this was called and applies changes to
 * the database.
 */
public boolean downloadChangedFlags(@NonNull Map<Integer, Long> tmdbIdsToShowIds) {
    long currentTime = System.currentTimeMillis();
    SgRoomDatabase database = SgRoomDatabase.getInstance(context);
    DateTime lastSyncTime = new DateTime(HexagonSettings.getLastEpisodesSyncTime(context));
    Timber.d("downloadChangedFlags: since %s", lastSyncTime);
    List<SgCloudEpisode> episodes;
    String cursor = null;
    boolean hasMoreEpisodes = true;
    Map<Long, ShowLastWatchedInfo> showIdsToLastWatched = new HashMap<>();
    while (hasMoreEpisodes) {
        try {
            // get service each time to check if auth was removed
            Episodes episodesService = hexagonTools.getEpisodesService();
            if (episodesService == null) {
                return false;
            }
            Episodes.GetSgEpisodes request = episodesService.getSgEpisodes().setUpdatedSince(// use default server limit
            lastSyncTime);
            if (!TextUtils.isEmpty(cursor)) {
                request.setCursor(cursor);
            }
            SgCloudEpisodeList response = request.execute();
            if (response == null) {
                // we're done here
                Timber.d("downloadChangedFlags: response was null, done here");
                break;
            }
            episodes = response.getEpisodes();
            // check for more items
            if (response.getCursor() != null) {
                cursor = response.getCursor();
            } else {
                hasMoreEpisodes = false;
            }
        } catch (IOException | IllegalArgumentException e) {
            // Note: JSON parser may throw IllegalArgumentException.
            Errors.logAndReportHexagon("get updated episodes", e);
            return false;
        }
        if (episodes == null || episodes.size() == 0) {
            // nothing to do here
            break;
        }
        // build batch of episode flag updates
        ArrayList<SgEpisode2UpdateByNumber> batch = new ArrayList<>();
        for (SgCloudEpisode episode : episodes) {
            Integer showTmdbId = episode.getShowTmdbId();
            Long showId = tmdbIdsToShowIds.get(showTmdbId);
            if (showId == null) {
                // ignore, show not added on this device
                continue;
            }
            Integer watchedFlag = episode.getWatchedFlag();
            Integer playsOrNull = null;
            if (watchedFlag != null) {
                if (watchedFlag == EpisodeFlags.WATCHED) {
                    // Note: plays may be null for legacy data. Protect against invalid data.
                    if (episode.getPlays() != null && episode.getPlays() >= 1) {
                        playsOrNull = episode.getPlays();
                    } else {
                        playsOrNull = 1;
                    }
                } else {
                    // Skipped or not watched.
                    playsOrNull = 0;
                }
                // record the latest last watched time and episode ID for a show
                if (!EpisodeTools.isUnwatched(watchedFlag)) {
                    ShowLastWatchedInfo lastWatchedInfo = showIdsToLastWatched.get(showId);
                    // episodes returned in reverse chrono order, so just get the first time
                    if (lastWatchedInfo == null && episode.getUpdatedAt() != null) {
                        long updatedAtMs = episode.getUpdatedAt().getValue();
                        showIdsToLastWatched.put(showId, new ShowLastWatchedInfo(updatedAtMs, episode.getSeasonNumber(), episode.getEpisodeNumber()));
                    }
                }
            }
            batch.add(new SgEpisode2UpdateByNumber(showId, episode.getEpisodeNumber(), episode.getSeasonNumber(), watchedFlag, playsOrNull, episode.getIsInCollection()));
        }
        // execute database update
        database.sgEpisode2Helper().updateWatchedAndCollectedByNumber(batch);
    }
    if (!showIdsToLastWatched.isEmpty()) {
        // Note: it is possible that this overwrites a more recently watched episode,
        // however, the next sync should contain this episode and restore it.
        database.sgShow2Helper().updateLastWatchedMsIfLaterAndLastWatchedEpisodeId(showIdsToLastWatched, database.sgEpisode2Helper());
    }
    // store new last sync time
    PreferenceManager.getDefaultSharedPreferences(context).edit().putLong(HexagonSettings.KEY_LAST_SYNC_EPISODES, currentTime).apply();
    return true;
}
Also used : SgCloudEpisode(com.uwetrottmann.seriesguide.backend.episodes.model.SgCloudEpisode) SgRoomDatabase(com.battlelancer.seriesguide.provider.SgRoomDatabase) HashMap(java.util.HashMap) SgCloudEpisodeList(com.uwetrottmann.seriesguide.backend.episodes.model.SgCloudEpisodeList) ArrayList(java.util.ArrayList) IOException(java.io.IOException) DateTime(com.google.api.client.util.DateTime) SgEpisode2UpdateByNumber(com.battlelancer.seriesguide.provider.SgEpisode2UpdateByNumber) Episodes(com.uwetrottmann.seriesguide.backend.episodes.Episodes)

Example 3 with SgEpisode2UpdateByNumber

use of com.battlelancer.seriesguide.provider.SgEpisode2UpdateByNumber in project SeriesGuide by UweTrottmann.

the class HexagonEpisodeSync method downloadFlagsByTvdbId.

private DownloadFlagsResult downloadFlagsByTvdbId(long showId, int showTvdbId) {
    List<Episode> episodes;
    boolean hasMoreEpisodes = true;
    String cursor = null;
    Long lastWatchedMs = null;
    while (hasMoreEpisodes) {
        // abort if connection is lost
        if (!AndroidUtils.isNetworkConnected(context)) {
            Timber.e("downloadFlags: no network connection");
            return DownloadFlagsResult.FAILED;
        }
        try {
            // get service each time to check if auth was removed
            Episodes episodesService = hexagonTools.getEpisodesService();
            if (episodesService == null) {
                return DownloadFlagsResult.FAILED;
            }
            // build request
            Episodes.Get request = episodesService.get().setShowTvdbId(// use default server limit
            showTvdbId);
            if (!TextUtils.isEmpty(cursor)) {
                request.setCursor(cursor);
            }
            // execute request
            EpisodeList response = request.execute();
            if (response == null) {
                // If empty should send status 200 and empty list, so no body is a failure.
                return DownloadFlagsResult.FAILED;
            }
            episodes = response.getEpisodes();
            // check for more items
            if (response.getCursor() != null) {
                cursor = response.getCursor();
            } else {
                hasMoreEpisodes = false;
            }
        } catch (IOException | IllegalArgumentException e) {
            // Note: JSON parser may throw IllegalArgumentException.
            Errors.logAndReportHexagon("get episodes of show", e);
            return DownloadFlagsResult.FAILED;
        }
        if (episodes == null || episodes.size() == 0) {
            // nothing to do here
            break;
        }
        // build batch of episode flag updates
        ArrayList<SgEpisode2UpdateByNumber> batch = new ArrayList<>();
        for (Episode episode : episodes) {
            Pair<SgEpisode2UpdateByNumber, Long> update = buildSgEpisodeUpdate(episode.getWatchedFlag(), episode.getPlays(), episode.getIsInCollection(), episode.getUpdatedAt(), episode.getEpisodeNumber(), episode.getSeasonNumber(), showId, lastWatchedMs);
            if (update != null) {
                batch.add(update.first);
                lastWatchedMs = update.second;
            }
        }
        // execute database update
        SgRoomDatabase.getInstance(context).sgEpisode2Helper().updateWatchedAndCollectedByNumber(batch);
    }
    return new DownloadFlagsResult(true, false, lastWatchedMs);
}
Also used : ArrayList(java.util.ArrayList) IOException(java.io.IOException) SgCloudEpisode(com.uwetrottmann.seriesguide.backend.episodes.model.SgCloudEpisode) Episode(com.uwetrottmann.seriesguide.backend.episodes.model.Episode) EpisodeList(com.uwetrottmann.seriesguide.backend.episodes.model.EpisodeList) SgCloudEpisodeList(com.uwetrottmann.seriesguide.backend.episodes.model.SgCloudEpisodeList) SgEpisode2UpdateByNumber(com.battlelancer.seriesguide.provider.SgEpisode2UpdateByNumber) Episodes(com.uwetrottmann.seriesguide.backend.episodes.Episodes)

Example 4 with SgEpisode2UpdateByNumber

use of com.battlelancer.seriesguide.provider.SgEpisode2UpdateByNumber in project SeriesGuide by UweTrottmann.

the class HexagonEpisodeSync method buildSgEpisodeUpdate.

@Nullable
private Pair<SgEpisode2UpdateByNumber, Long> buildSgEpisodeUpdate(Integer watchedFlag, Integer plays, Boolean isInCollection, DateTime updatedAt, int episodeNumber, int seasonNumber, long showId, Long lastWatchedMs) {
    Integer watchedFlagOrNull = null;
    Integer playsOrNull = null;
    if (watchedFlag != null && watchedFlag != EpisodeFlags.UNWATCHED) {
        // Watched or skipped.
        watchedFlagOrNull = watchedFlag;
        if (watchedFlag == EpisodeFlags.WATCHED) {
            // Note: plays may be null for legacy data. Protect against invalid data.
            if (plays != null && plays >= 1) {
                playsOrNull = plays;
            } else {
                playsOrNull = 1;
            }
        }
        // record last watched time by taking latest updatedAt of watched/skipped
        if (updatedAt != null) {
            long lastWatchedMsNew = updatedAt.getValue();
            if (lastWatchedMs == null || lastWatchedMs < lastWatchedMsNew) {
                lastWatchedMs = lastWatchedMsNew;
            }
        }
    }
    boolean inCollection = isInCollection != null && isInCollection;
    if (watchedFlag == null && !inCollection) {
        // skip if episode has no watched flag and is not in collection
        return null;
    }
    return new Pair<>(new SgEpisode2UpdateByNumber(showId, episodeNumber, seasonNumber, watchedFlagOrNull, playsOrNull, isInCollection), lastWatchedMs);
}
Also used : SgEpisode2UpdateByNumber(com.battlelancer.seriesguide.provider.SgEpisode2UpdateByNumber) Pair(androidx.core.util.Pair) Nullable(androidx.annotation.Nullable)

Aggregations

SgEpisode2UpdateByNumber (com.battlelancer.seriesguide.provider.SgEpisode2UpdateByNumber)4 Episodes (com.uwetrottmann.seriesguide.backend.episodes.Episodes)3 SgCloudEpisode (com.uwetrottmann.seriesguide.backend.episodes.model.SgCloudEpisode)3 SgCloudEpisodeList (com.uwetrottmann.seriesguide.backend.episodes.model.SgCloudEpisodeList)3 IOException (java.io.IOException)3 ArrayList (java.util.ArrayList)3 Nullable (androidx.annotation.Nullable)1 Pair (androidx.core.util.Pair)1 SgRoomDatabase (com.battlelancer.seriesguide.provider.SgRoomDatabase)1 DateTime (com.google.api.client.util.DateTime)1 Episode (com.uwetrottmann.seriesguide.backend.episodes.model.Episode)1 EpisodeList (com.uwetrottmann.seriesguide.backend.episodes.model.EpisodeList)1 HashMap (java.util.HashMap)1