package com.battlelancer.seriesguide.loaders;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import com.battlelancer.seriesguide.SgApp;
import com.battlelancer.seriesguide.items.MovieDetails;
import com.battlelancer.seriesguide.util.DBUtils;
import com.battlelancer.seriesguide.util.MovieTools;
import com.uwetrottmann.androidutils.GenericSimpleLoader;
import com.uwetrottmann.tmdb2.entities.Movie;
import com.uwetrottmann.trakt5.entities.Ratings;
import static com.battlelancer.seriesguide.provider.SeriesGuideContract.Movies;
/**
* Tries to load current movie details from trakt and TMDb, if failing tries to fall back to local
* database copy.
*/
public class MovieLoader extends GenericSimpleLoader<MovieDetails> {
private final SgApp app;
private int mTmdbId;
public MovieLoader(SgApp app, int tmdbId) {
super(app);
this.app = app;
mTmdbId = tmdbId;
}
@Override
public MovieDetails loadInBackground() {
// try loading from trakt and tmdb, this might return a cached response
MovieDetails details = app.getMovieTools().getMovieDetails(mTmdbId);
// update local database
updateLocalMovie(getContext(), details, mTmdbId);
// fill in details from local database
Cursor movieQuery = getContext().getContentResolver()
.query(Movies.buildMovieUri(mTmdbId), MovieQuery.PROJECTION, null, null, null);
if (movieQuery == null || !movieQuery.moveToFirst() || movieQuery.getCount() < 1) {
if (movieQuery != null) {
movieQuery.close();
}
// ensure list flags and watched flag are false on failure
// (assumption: movie not in db, it has the truth, so can't be in any lists or watched)
details.inCollection = false;
details.inWatchlist = false;
details.isWatched = false;
return details;
}
// set local state for watched, collected and watchlist status
// assumption: local db has the truth for these
details.inCollection = DBUtils.restoreBooleanFromInt(
movieQuery.getInt(MovieQuery.IN_COLLECTION));
details.inWatchlist = DBUtils.restoreBooleanFromInt(
movieQuery.getInt(MovieQuery.IN_WATCHLIST));
details.isWatched = DBUtils.restoreBooleanFromInt(movieQuery.getInt(MovieQuery.WATCHED));
// also use local state of user rating
details.userRating = movieQuery.getInt(MovieQuery.RATING_USER);
// only overwrite other info if remote data failed to load
if (details.traktRatings() == null) {
details.traktRatings(new Ratings());
details.traktRatings().rating = (double) movieQuery.getInt(MovieQuery.RATING_TRAKT);
details.traktRatings().votes = movieQuery.getInt(MovieQuery.RATING_VOTES_TRAKT);
}
if (details.tmdbMovie() == null) {
details.tmdbMovie(new Movie());
details.tmdbMovie().imdb_id = movieQuery.getString(MovieQuery.IMDB_ID);
details.tmdbMovie().title = movieQuery.getString(MovieQuery.TITLE);
details.tmdbMovie().overview = movieQuery.getString(MovieQuery.OVERVIEW);
details.tmdbMovie().poster_path = movieQuery.getString(MovieQuery.POSTER);
details.tmdbMovie().runtime = movieQuery.getInt(MovieQuery.RUNTIME_MIN);
details.tmdbMovie().vote_average = movieQuery.getDouble(MovieQuery.RATING_TMDB);
details.tmdbMovie().vote_count = movieQuery.getInt(MovieQuery.RATING_VOTES_TMDB);
// if stored release date is Long.MAX, movie has no release date
long releaseDateMs = movieQuery.getLong(MovieQuery.RELEASED_UTC_MS);
details.tmdbMovie().release_date = MovieTools.movieReleaseDateFrom(releaseDateMs);
}
// clean up
movieQuery.close();
return details;
}
private static void updateLocalMovie(Context context,
MovieDetails details, int tmdbId) {
ContentValues values = MovieTools.buildBasicMovieContentValues(details);
if (values.size() == 0) {
// nothing to update, downloading probably failed :(
return;
}
// if movie does not exist in database, will do nothing
context.getContentResolver().update(Movies.buildMovieUri(tmdbId), values, null, null);
}
private interface MovieQuery {
String[] PROJECTION = {
Movies.TITLE, // 0
Movies.OVERVIEW,
Movies.RELEASED_UTC_MS,
Movies.POSTER,
Movies.WATCHED, // 4
Movies.IN_COLLECTION,
Movies.IN_WATCHLIST,
Movies.IMDB_ID,
Movies.RUNTIME_MIN,
Movies.RATING_TMDB, // 9
Movies.RATING_VOTES_TMDB,
Movies.RATING_TRAKT,
Movies.RATING_VOTES_TRAKT,
Movies.RATING_USER // 13
};
int TITLE = 0;
int OVERVIEW = 1;
int RELEASED_UTC_MS = 2;
int POSTER = 3;
int WATCHED = 4;
int IN_COLLECTION = 5;
int IN_WATCHLIST = 6;
int IMDB_ID = 7;
int RUNTIME_MIN = 8;
int RATING_TMDB = 9;
int RATING_VOTES_TMDB = 10;
int RATING_TRAKT = 11;
int RATING_VOTES_TRAKT = 12;
int RATING_USER = 13;
}
}