Search in sources :

Example 1 with SearchResult

use of com.battlelancer.seriesguide.items.SearchResult 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);
        }
    }
}
Also used : SearchResult(com.battlelancer.seriesguide.items.SearchResult) TrendingShow(com.uwetrottmann.trakt5.entities.TrendingShow) LinkedList(java.util.LinkedList) Show(com.uwetrottmann.trakt5.entities.Show) TrendingShow(com.uwetrottmann.trakt5.entities.TrendingShow) TvdbException(com.battlelancer.seriesguide.thetvdbapi.TvdbException)

Example 2 with SearchResult

use of com.battlelancer.seriesguide.items.SearchResult 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());
}
Also used : SharedPreferences(android.content.SharedPreferences) HashMap(java.util.HashMap) SearchResult(com.battlelancer.seriesguide.items.SearchResult) SuppressLint(android.annotation.SuppressLint) LinkedList(java.util.LinkedList) ContentResolver(android.content.ContentResolver) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) SuppressLint(android.annotation.SuppressLint) TvdbException(com.battlelancer.seriesguide.thetvdbapi.TvdbException) SuppressLint(android.annotation.SuppressLint)

Example 3 with SearchResult

use of com.battlelancer.seriesguide.items.SearchResult in project SeriesGuide by UweTrottmann.

the class TvdbTools method searchSeries.

@Nullable
public List<SearchResult> searchSeries(@NonNull String query, @Nullable final String language) throws TvdbException {
    retrofit2.Response<SeriesResultsResponse> response;
    try {
        response = tvdbSearch.get().series(query, null, null, language).execute();
    } catch (IOException e) {
        throw new TvdbException("searchSeries: " + e.getMessage(), e);
    }
    if (response.code() == 404) {
        // API returns 404 if there are no search results
        return null;
    }
    ensureSuccessfulResponse(response.raw(), "searchSeries: ");
    List<Series> tvdbResults = response.body().data;
    if (tvdbResults == null || tvdbResults.size() == 0) {
        // no results from tvdb
        return null;
    }
    // parse into our data format
    List<SearchResult> results = new ArrayList<>(tvdbResults.size());
    for (Series tvdbResult : tvdbResults) {
        SearchResult result = new SearchResult();
        result.tvdbid = tvdbResult.id;
        result.title = tvdbResult.seriesName;
        result.overview = tvdbResult.overview;
        result.language = language;
        results.add(result);
    }
    return results;
}
Also used : TheTvdbSeries(com.uwetrottmann.thetvdb.services.TheTvdbSeries) Series(com.uwetrottmann.thetvdb.entities.Series) SeriesResultsResponse(com.uwetrottmann.thetvdb.entities.SeriesResultsResponse) ArrayList(java.util.ArrayList) SearchResult(com.battlelancer.seriesguide.items.SearchResult) IOException(java.io.IOException) Nullable(android.support.annotation.Nullable)

Example 4 with SearchResult

use of com.battlelancer.seriesguide.items.SearchResult in project SeriesGuide by UweTrottmann.

the class TraktAddFragment method onOptionsItemSelected.

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    int itemId = item.getItemId();
    if (itemId == R.id.menu_add_all) {
        if (searchResults != null) {
            List<SearchResult> showsToAdd = new LinkedList<>();
            // only include shows not already added
            for (SearchResult result : searchResults) {
                if (result.state == SearchResult.STATE_ADD) {
                    showsToAdd.add(result);
                    result.state = SearchResult.STATE_ADDING;
                }
            }
            EventBus.getDefault().post(new OnAddingShowEvent());
            TaskManager.getInstance(getActivity()).performAddTask(SgApp.from(getActivity()), showsToAdd, false, false);
        }
        // disable the item so the user has to come back
        item.setEnabled(false);
        return true;
    }
    return super.onOptionsItemSelected(item);
}
Also used : SearchResult(com.battlelancer.seriesguide.items.SearchResult) LinkedList(java.util.LinkedList)

Example 5 with SearchResult

use of com.battlelancer.seriesguide.items.SearchResult in project SeriesGuide by UweTrottmann.

the class AddShowDialogFragment method showAddDialog.

/**
     * Display a {@link com.battlelancer.seriesguide.ui.dialogs.AddShowDialogFragment} for the given
     * show.
     *
     * <p> Use if there is no actual search result, but just a TheTVDB id available.
     */
public static void showAddDialog(int showTvdbId, FragmentManager fm) {
    SearchResult fakeResult = new SearchResult();
    fakeResult.tvdbid = showTvdbId;
    showAddDialog(fakeResult, fm);
}
Also used : SearchResult(com.battlelancer.seriesguide.items.SearchResult)

Aggregations

SearchResult (com.battlelancer.seriesguide.items.SearchResult)11 TvdbException (com.battlelancer.seriesguide.thetvdbapi.TvdbException)3 ArrayList (java.util.ArrayList)3 LinkedList (java.util.LinkedList)3 BaseShow (com.uwetrottmann.trakt5.entities.BaseShow)2 Show (com.uwetrottmann.trakt5.entities.Show)2 SuppressLint (android.annotation.SuppressLint)1 ContentResolver (android.content.ContentResolver)1 SharedPreferences (android.content.SharedPreferences)1 Element (android.sax.Element)1 EndElementListener (android.sax.EndElementListener)1 EndTextElementListener (android.sax.EndTextElementListener)1 RootElement (android.sax.RootElement)1 Nullable (android.support.annotation.Nullable)1 Series (com.uwetrottmann.thetvdb.entities.Series)1 SeriesResultsResponse (com.uwetrottmann.thetvdb.entities.SeriesResultsResponse)1 TheTvdbSeries (com.uwetrottmann.thetvdb.services.TheTvdbSeries)1 TrendingShow (com.uwetrottmann.trakt5.entities.TrendingShow)1 IOException (java.io.IOException)1 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1