use of com.battlelancer.seriesguide.thetvdbapi.TvdbException in project SeriesGuide by UweTrottmann.
the class AnalyticsTree method log.
@Override
protected void log(int priority, String tag, String message, Throwable t) {
if (priority == Log.ERROR) {
// remove any stack trace attached by Timber
if (message != null) {
int newLine = message.indexOf('\n');
if (newLine > 0) {
message = message.substring(0, newLine);
}
}
// special treatment for some exceptions
if (t instanceof TvdbException) {
TvdbException e = (TvdbException) t;
Utils.trackCustomEvent(context, CATEGORY_THETVDB_ERROR, tag + ": " + message, e.getMessage());
return;
} else if (t instanceof OAuthProblemException) {
// log trakt OAuth failures
OAuthProblemException e = (OAuthProblemException) t;
StringBuilder exceptionMessage = new StringBuilder();
if (!TextUtils.isEmpty(e.getError())) {
exceptionMessage.append(e.getError());
}
if (!TextUtils.isEmpty(e.getDescription())) {
exceptionMessage.append(", ").append(e.getDescription());
}
if (!TextUtils.isEmpty(e.getUri())) {
exceptionMessage.append(", ").append(e.getUri());
}
Utils.trackCustomEvent(context, "OAuth Error", tag + ": " + message, exceptionMessage.toString());
return;
} else if (t instanceof OAuthSystemException) {
// log trakt OAuth failures
OAuthSystemException e = (OAuthSystemException) t;
Utils.trackCustomEvent(context, "OAuth Error", tag + ": " + message, e.getMessage());
return;
}
}
// drop empty messages
if (message == null) {
return;
}
// drop debug and verbose logs
if (priority == Log.DEBUG || priority == Log.VERBOSE) {
return;
}
// transform priority into string
String level = null;
switch(priority) {
case Log.INFO:
level = "INFO";
break;
case Log.WARN:
level = "WARN";
break;
case Log.ERROR:
level = "ERROR";
break;
}
// finally log to crashlytics
Crashlytics.log(level + "/" + tag + ": " + message);
// track some non-fatal exceptions with crashlytics
if (priority == Log.ERROR) {
if (t instanceof SQLiteException) {
Crashlytics.logException(t);
}
}
}
use of com.battlelancer.seriesguide.thetvdbapi.TvdbException in project SeriesGuide by UweTrottmann.
the class TvdbAddLoader method loadInBackground.
@Override
public Result loadInBackground() {
List<SearchResult> results;
if (TextUtils.isEmpty(query)) {
// no query? load a list of trending shows from trakt
List<TrendingShow> trendingShows = SgTrakt.executeCall(app, traktShows.get().trending(1, 35, Extended.FULL), "get trending shows");
if (trendingShows != null) {
List<Show> shows = new LinkedList<>();
for (TrendingShow show : trendingShows) {
if (show.show == null || show.show.ids == null || show.show.ids.tvdb == null) {
// skip if required values are missing
continue;
}
shows.add(show.show);
}
// manually set the language to the current search language
results = TraktAddLoader.parseTraktShowsToSearchResults(getContext(), shows, language);
return buildResultSuccess(results, R.string.add_empty);
} else {
return buildResultFailure(R.string.trakt);
}
} else {
// use TheTVDB search for all other (or any) languages
if (DisplaySettings.LANGUAGE_EN.equals(language)) {
List<com.uwetrottmann.trakt5.entities.SearchResult> searchResults = SgTrakt.executeCall(app, traktSearch.get().textQueryShow(query, null, null, null, null, null, null, null, null, null, Extended.FULL, 1, 30), "search shows");
if (searchResults != null) {
List<Show> shows = new LinkedList<>();
for (com.uwetrottmann.trakt5.entities.SearchResult result : searchResults) {
if (result.show == null || result.show.ids == null || result.show.ids.tvdb == null) {
// skip, TVDB id required
continue;
}
shows.add(result.show);
}
// manually set the language to English
results = TraktAddLoader.parseTraktShowsToSearchResults(getContext(), shows, DisplaySettings.LANGUAGE_EN);
return buildResultSuccess(results, R.string.no_results);
} else {
return buildResultFailure(R.string.trakt);
}
} else {
try {
if (TextUtils.isEmpty(language)) {
// use the v1 API to do an any language search not supported by v2
results = TvdbTools.getInstance(app).searchShow(query, null);
} else {
results = TvdbTools.getInstance(app).searchSeries(query, language);
}
markLocalShows(results);
return buildResultSuccess(results, R.string.no_results);
} catch (TvdbException e) {
Timber.e(e, "Searching show failed");
}
return buildResultFailure(R.string.tvdb);
}
}
}
use of com.battlelancer.seriesguide.thetvdbapi.TvdbException in project SeriesGuide by UweTrottmann.
the class SgSyncAdapter method onPerformSync.
@SuppressLint("CommitPrefEdits")
@Override
public void onPerformSync(Account account, Bundle extras, String authority, ContentProviderClient provider, SyncResult syncResult) {
// determine type of sync
final boolean syncImmediately = extras.getBoolean(SyncInitBundle.SYNC_IMMEDIATE, false);
final SyncType syncType = SyncType.from(extras.getInt(SyncInitBundle.SYNC_TYPE, SyncType.DELTA.id));
Timber.i("Syncing...%s%s", syncType, (syncImmediately ? "_IMMEDIATE" : "_REGULAR"));
// should we sync?
final long currentTime = System.currentTimeMillis();
if (!syncImmediately && syncType != SyncType.SINGLE) {
if (!isTimeForSync(getContext(), currentTime)) {
Timber.d("Syncing...ABORT_DID_JUST_SYNC");
return;
}
}
// build a list of shows to update
int[] showsToUpdate;
if (syncType == SyncType.SINGLE) {
int showTvdbId = extras.getInt(SyncInitBundle.SYNC_SHOW_TVDB_ID, 0);
if (showTvdbId == 0) {
Timber.e("Syncing...ABORT_INVALID_SHOW_TVDB_ID");
return;
}
showsToUpdate = new int[] { showTvdbId };
} else {
showsToUpdate = getShowsToUpdate(syncType, currentTime);
if (showsToUpdate == null) {
Timber.e("Syncing...ABORT_SHOW_QUERY_FAILED");
return;
}
}
// from here on we need more sophisticated abort handling, so keep track of errors
UpdateResult resultCode = UpdateResult.SUCCESS;
// loop through shows and download latest data from TVDb
Timber.d("Syncing...TVDb");
final AtomicInteger updateCount = new AtomicInteger();
final ContentResolver resolver = getContext().getContentResolver();
for (int i = updateCount.get(); i < showsToUpdate.length; i++) {
int id = showsToUpdate[i];
// stop sync if connectivity is lost
if (!AndroidUtils.isNetworkConnected(getContext())) {
resultCode = UpdateResult.INCOMPLETE;
break;
}
try {
TvdbTools.getInstance(app).updateShow(id);
// make sure other loaders (activity, overview, details) are notified
resolver.notifyChange(Episodes.CONTENT_URI_WITHSHOW, null);
} catch (TvdbException e) {
// failed, continue with other shows
resultCode = UpdateResult.INCOMPLETE;
Timber.e(e, "Updating show failed");
}
updateCount.incrementAndGet();
}
// do some more things if this is not a quick update
if (syncType != SyncType.SINGLE) {
final SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
// get latest TMDb configuration
Timber.d("Syncing...TMDb config");
getTmdbConfiguration(prefs);
// sync with Hexagon or trakt
final HashSet<Integer> showsExisting = ShowTools.getShowTvdbIdsAsSet(getContext());
@SuppressLint("UseSparseArrays") final HashMap<Integer, SearchResult> showsNew = new HashMap<>();
if (showsExisting == null) {
resultCode = UpdateResult.INCOMPLETE;
} else {
if (HexagonSettings.isEnabled(getContext())) {
// sync with hexagon...
Timber.d("Syncing...Hexagon");
boolean success = HexagonTools.syncWithHexagon(app, showsExisting, showsNew);
// don't overwrite failure
if (resultCode == UpdateResult.SUCCESS) {
resultCode = success ? UpdateResult.SUCCESS : UpdateResult.INCOMPLETE;
}
} else {
// ...OR sync with trakt
Timber.d("Syncing...trakt");
UpdateResult resultTrakt = performTraktSync(showsExisting, currentTime);
// don't overwrite failure
if (resultCode == UpdateResult.SUCCESS) {
resultCode = resultTrakt;
}
// add shows newly discovered on trakt
if (showsNew.size() > 0) {
List<SearchResult> showsNewList = new LinkedList<>(showsNew.values());
TaskManager.getInstance(getContext()).performAddTask(app, showsNewList, true, false);
}
}
// make sure other loaders (activity, overview, details) are notified of changes
resolver.notifyChange(Episodes.CONTENT_URI_WITHSHOW, null);
}
// renew search table if shows were updated and it will not be renewed by add task
if (updateCount.get() > 0 && showsToUpdate.length > 0 && showsNew.size() == 0) {
DBUtils.rebuildFtsTable(getContext());
}
// update next episodes for all shows
TaskManager.getInstance(getContext()).tryNextEpisodeUpdateTask();
// store time of update, set retry counter on failure
if (resultCode == UpdateResult.SUCCESS) {
// we were successful, reset failed counter
prefs.edit().putLong(UpdateSettings.KEY_LASTUPDATE, currentTime).putInt(UpdateSettings.KEY_FAILED_COUNTER, 0).commit();
} else {
int failed = UpdateSettings.getFailedNumberOfUpdates(getContext());
/*
* Back off by 2**(failure + 2) * minutes. Purposely set a fake
* last update time, because the next update will be triggered
* UPDATE_INTERVAL minutes after the last update time. This way
* we can trigger it earlier (4min up to 32min).
*/
long fakeLastUpdateTime;
if (failed < 4) {
fakeLastUpdateTime = currentTime - ((SYNC_INTERVAL_MINIMUM_MINUTES - (int) Math.pow(2, failed + 2)) * DateUtils.MINUTE_IN_MILLIS);
} else {
fakeLastUpdateTime = currentTime;
}
failed += 1;
prefs.edit().putLong(UpdateSettings.KEY_LASTUPDATE, fakeLastUpdateTime).putInt(UpdateSettings.KEY_FAILED_COUNTER, failed).commit();
}
}
// There could have been new episodes added after an update
Utils.runNotificationService(getContext());
Timber.i("Syncing...%s", resultCode.toString());
}
use of com.battlelancer.seriesguide.thetvdbapi.TvdbException in project SeriesGuide by UweTrottmann.
the class AddShowTask method doInBackground.
@Override
protected Void doInBackground(Void... params) {
Timber.d("Starting to add shows...");
// don't even get started
if (addQueue.isEmpty()) {
Timber.d("Finished. Queue was empty.");
return null;
}
// set values required for progress update
SearchResult nextShow = addQueue.peek();
currentShowName = nextShow.title;
currentShowTvdbId = nextShow.tvdbid;
if (!AndroidUtils.isNetworkConnected(app)) {
Timber.d("Finished. No internet connection.");
publishProgress(RESULT_OFFLINE);
return null;
}
if (isCancelled()) {
Timber.d("Finished. Cancelled.");
return null;
}
// if not connected to Hexagon, get episodes from trakt
HashMap<Integer, BaseShow> traktCollection = null;
HashMap<Integer, BaseShow> traktWatched = null;
if (!HexagonSettings.isEnabled(app) && TraktCredentials.get(app).hasCredentials()) {
Timber.d("Getting watched and collected episodes from trakt.");
// get collection
HashMap<Integer, BaseShow> traktShows = getTraktShows("get collection", true);
if (traktShows == null) {
// can not get collected state from trakt, give up.
return null;
}
traktCollection = traktShows;
// get watched
traktShows = getTraktShows("get watched", false);
if (traktShows == null) {
// can not get watched state from trakt, give up.
return null;
}
traktWatched = traktShows;
}
int result;
boolean addedAtLeastOneShow = false;
boolean failedMergingShows = false;
while (!addQueue.isEmpty()) {
Timber.d("Starting to add next show...");
if (isCancelled()) {
Timber.d("Finished. Cancelled.");
// table yet
return null;
}
nextShow = addQueue.removeFirst();
// set values required for progress update
currentShowName = nextShow.title;
currentShowTvdbId = nextShow.tvdbid;
if (!AndroidUtils.isNetworkConnected(app)) {
Timber.d("Finished. No connection.");
publishProgress(RESULT_OFFLINE);
failedMergingShows = true;
break;
}
try {
boolean addedShow = TvdbTools.getInstance(app).addShow(nextShow.tvdbid, nextShow.language, traktCollection, traktWatched);
result = addedShow ? PROGRESS_SUCCESS : PROGRESS_EXISTS;
addedAtLeastOneShow = addedShow || // do not overwrite previous success
addedAtLeastOneShow;
} catch (TvdbException e) {
// because it does not exist (any longer)
if (!(isMergingShows && e.itemDoesNotExist())) {
failedMergingShows = true;
}
if (e.service() == TvdbException.Service.TVDB) {
if (e.itemDoesNotExist()) {
result = PROGRESS_ERROR_TVDB_NOT_EXISTS;
} else {
result = PROGRESS_ERROR_TVDB;
}
} else if (e.service() == TvdbException.Service.HEXAGON) {
result = PROGRESS_ERROR_HEXAGON;
} else if (e.service() == TvdbException.Service.DATA) {
result = PROGRESS_ERROR_DATA;
} else {
result = PROGRESS_ERROR;
}
Timber.e(e, "Adding show failed");
}
publishProgress(result);
Timber.d("Finished adding show. (Result code: %s)", result);
}
isFinishedAddingShows = true;
// when merging shows down from Hexagon, set success flag
if (isMergingShows && !failedMergingShows) {
HexagonSettings.setHasMergedShows(app, true);
}
if (addedAtLeastOneShow) {
// make sure the next sync will download all ratings
PreferenceManager.getDefaultSharedPreferences(app).edit().putLong(TraktSettings.KEY_LAST_SHOWS_RATED_AT, 0).putLong(TraktSettings.KEY_LAST_EPISODES_RATED_AT, 0).apply();
// renew FTS3 table
Timber.d("Renewing search table.");
DBUtils.rebuildFtsTable(app);
}
Timber.d("Finished adding shows.");
return null;
}
Aggregations