use of com.battlelancer.seriesguide.model.SgMovieFlags in project SeriesGuide by UweTrottmann.
the class TraktMovieSync method syncLists.
/**
* Updates the local movie database against trakt movie watchlist, collection and watched
* movies. Adds or updates movies in the database. Movies not in any list or not watched must be
* removed afterwards.
*
* <p> When syncing the first time, will upload any local movies missing from trakt collection
* or watchlist or are not watched on Trakt instead of removing them locally.
*
* <p> Performs <b>synchronous network access</b>, make sure to run this on a background
* thread.
*/
boolean syncLists(LastActivityMore activity) {
if (activity.collected_at == null) {
Timber.e("syncLists: null collected_at");
return false;
}
if (activity.watchlisted_at == null) {
Timber.e("syncLists: null watchlisted_at");
return false;
}
if (activity.watched_at == null) {
Timber.e("syncLists: null watched_at");
return false;
}
final boolean merging = !TraktSettings.hasMergedMovies(context);
if (!merging && !TraktSettings.isMovieListsChanged(context, activity.collected_at, activity.watchlisted_at, activity.watched_at)) {
Timber.d("syncLists: no changes");
return true;
}
if (!TraktCredentials.get(context).hasCredentials()) {
return false;
}
// download trakt state
Set<Integer> collection = downloadCollection();
if (collection == null) {
return false;
}
Set<Integer> watchlist = downloadWatchlist();
if (watchlist == null) {
return false;
}
Map<Integer, Integer> watchedWithPlays = downloadWatched();
if (watchedWithPlays == null) {
return false;
}
// Loop through local movies to build updates.
List<SgMovieFlags> localMovies;
try {
localMovies = SgRoomDatabase.getInstance(context).movieHelper().getMovieFlags();
} catch (Exception e) {
Errors.logAndReport("syncLists: query local movies", e);
return false;
}
// only when merging
Set<Integer> toCollectOnTrakt = new HashSet<>();
// only when merging
Set<Integer> toWatchlistOnTrakt = new HashSet<>();
// only when merging
Set<Integer> toSetWatchedOnTrakt = new HashSet<>();
ArrayList<ContentProviderOperation> batch = new ArrayList<>();
for (SgMovieFlags localMovie : localMovies) {
// Is local movie in trakt collection, watchlist or watched?
int tmdbId = localMovie.getTmdbId();
boolean inCollectionOnTrakt = collection.remove(tmdbId);
boolean inWatchlistOnTrakt = watchlist.remove(tmdbId);
Integer plays = watchedWithPlays.remove(tmdbId);
boolean isWatchedOnTrakt = plays != null;
if (merging) {
if (localMovie.getInCollection() && !inCollectionOnTrakt) {
toCollectOnTrakt.add(tmdbId);
}
if (localMovie.getInWatchlist() && !inWatchlistOnTrakt) {
toWatchlistOnTrakt.add(tmdbId);
}
if (localMovie.getWatched() && !isWatchedOnTrakt) {
toSetWatchedOnTrakt.add(tmdbId);
}
// in later sync step.
if (inCollectionOnTrakt || inWatchlistOnTrakt || isWatchedOnTrakt) {
ContentProviderOperation.Builder builder = ContentProviderOperation.newUpdate(Movies.buildMovieUri(tmdbId));
boolean changed = false;
if (!localMovie.getInCollection() && inCollectionOnTrakt) {
builder.withValue(Movies.IN_COLLECTION, true);
changed = true;
}
if (!localMovie.getInWatchlist() && inWatchlistOnTrakt) {
builder.withValue(Movies.IN_WATCHLIST, true);
changed = true;
}
if (!localMovie.getWatched() && isWatchedOnTrakt) {
builder.withValue(Movies.WATCHED, true);
builder.withValue(Movies.PLAYS, plays >= 1 ? plays : 1);
changed = true;
}
if (changed) {
batch.add(builder.build());
}
}
} else {
// Performance: only add op if any flag differs or if watched and plays have changed.
if (localMovie.getInCollection() != inCollectionOnTrakt || localMovie.getInWatchlist() != inWatchlistOnTrakt || localMovie.getWatched() != isWatchedOnTrakt || (isWatchedOnTrakt && plays >= 1 && localMovie.getPlays() != plays)) {
// Mirror Trakt collection, watchlist, watched flag and plays.
// Note: unneeded (not watched or in any list) movies
// are removed in a later sync step.
ContentProviderOperation.Builder op = ContentProviderOperation.newUpdate(Movies.buildMovieUri(tmdbId)).withValue(Movies.IN_COLLECTION, inCollectionOnTrakt).withValue(Movies.IN_WATCHLIST, inWatchlistOnTrakt).withValue(Movies.WATCHED, isWatchedOnTrakt);
int playsValue;
if (isWatchedOnTrakt) {
playsValue = plays >= 1 ? plays : 1;
} else {
playsValue = 0;
}
op.withValue(Movies.PLAYS, playsValue);
batch.add(op.build());
}
}
}
// apply updates to existing movies
try {
DBUtils.applyInSmallBatches(context, batch);
Timber.d("syncLists: updated %s", batch.size());
} catch (OperationApplicationException e) {
Timber.e(e, "syncLists: database updates failed");
return false;
}
// release for gc
batch.clear();
// merge on first run
if (merging) {
// Upload movies not in Trakt collection, watchlist or watched history.
if (uploadFlagsNotOnTrakt(toCollectOnTrakt, toWatchlistOnTrakt, toSetWatchedOnTrakt)) {
// set merge successful
PreferenceManager.getDefaultSharedPreferences(context).edit().putBoolean(TraktSettings.KEY_HAS_MERGED_MOVIES, true).apply();
} else {
return false;
}
}
// add movies from trakt missing locally
// all local movies were removed from trakt collection, watchlist, and watched list
// so they only contain movies missing locally
boolean addingSuccessful = movieTools.addMovies(collection, watchlist, watchedWithPlays);
if (addingSuccessful) {
// store last activity timestamps
TraktSettings.storeLastMoviesChangedAt(context, activity.collected_at, activity.watchlisted_at, activity.watched_at);
// if movies were added, ensure ratings for them are downloaded next
if (collection.size() > 0 || watchlist.size() > 0 || watchedWithPlays.size() > 0) {
TraktSettings.resetMoviesLastRatedAt(context);
}
}
return addingSuccessful;
}
use of com.battlelancer.seriesguide.model.SgMovieFlags in project SeriesGuide by UweTrottmann.
the class MovieTools method removeFromList.
/**
* Removes the movie from the given list.
*
* <p>If it would not be on any list afterwards, deletes the movie from the local database.
*
* @return If the database operation was successful.
*/
public static boolean removeFromList(Context context, int movieTmdbId, Lists listToRemoveFrom) {
SgMovieFlags movieFlags = SgRoomDatabase.getInstance(context).movieHelper().getMovieFlags(movieTmdbId);
if (movieFlags == null) {
// query failed
return false;
}
boolean removeMovie = false;
if (listToRemoveFrom == Lists.COLLECTION) {
removeMovie = !movieFlags.getInWatchlist() && !movieFlags.getWatched();
} else if (listToRemoveFrom == Lists.WATCHLIST) {
removeMovie = !movieFlags.getInCollection() && !movieFlags.getWatched();
} else if (listToRemoveFrom == Lists.WATCHED) {
removeMovie = !movieFlags.getInCollection() && !movieFlags.getInWatchlist();
}
// if movie will not be in any list, remove it completely
if (removeMovie) {
return deleteMovie(context, movieTmdbId);
} else {
// otherwise, just update
return updateMovie(context, movieTmdbId, listToRemoveFrom, false);
}
}
Aggregations