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);
}
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;
}
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);
}
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);
}
Aggregations