/** * Just fetch all series and episode details and overwrite, add. * * @param showId * @throws SAXException * @throws IOException */ public static void updateShow(String showId, Context context) throws SAXException { String language = getTheTVDBLanguage(context); Series show = fetchShow(showId, language, context); final ArrayList<ContentProviderOperation> batch = Lists.newArrayList(); batch.add(DBUtils.buildShowOp(show, context, false)); batch.addAll(importShowEpisodes(showId, show.getAirsTime(), language, context)); try { context.getContentResolver().applyBatch(SeriesContract.CONTENT_AUTHORITY, batch); } catch (RemoteException e) { // Failed binder transactions aren't recoverable throw new RuntimeException("Problem applying batch operation", e); } catch (OperationApplicationException e) { // Failures like constraint violation aren't recoverable throw new RuntimeException("Problem applying batch operation", e); } }
public static ArrayList<ContentProviderOperation> parseEpisodes( String url, String showId, final long showAirtime, Context context) throws SAXException { RootElement root = new RootElement("Data"); Element episode = root.getChild("Episode"); final ArrayList<ContentProviderOperation> batch = Lists.newArrayList(); final HashSet<Long> episodeIDs = DBUtils.getEpisodeIDsForShow(showId, context); final HashSet<Long> existingSeasonIDs = DBUtils.getSeasonIDsForShow(showId, context); final HashSet<Long> updatedSeasonIDs = new HashSet<Long>(); final ContentValues values = new ContentValues(); // set handlers for elements we want to react to episode.setEndElementListener( new EndElementListener() { public void end() { // add insert/update op for episode batch.add( DBUtils.buildEpisodeOp( values, !episodeIDs.contains(values.getAsLong(Episodes._ID)))); long seasonid = values.getAsLong(Seasons.REF_SEASON_ID); if (!updatedSeasonIDs.contains(seasonid)) { // add insert/update op for season batch.add(DBUtils.buildSeasonOp(values, !existingSeasonIDs.contains(seasonid))); updatedSeasonIDs.add(values.getAsLong(Seasons.REF_SEASON_ID)); } values.clear(); } }); episode .getChild("id") .setEndTextElementListener( new EndTextElementListener() { public void end(String body) { values.put(Episodes._ID, body.trim()); } }); episode .getChild("EpisodeNumber") .setEndTextElementListener( new EndTextElementListener() { public void end(String body) { values.put(Episodes.NUMBER, body.trim()); } }); episode .getChild("SeasonNumber") .setEndTextElementListener( new EndTextElementListener() { public void end(String body) { values.put(Episodes.SEASON, body.trim()); } }); episode .getChild("DVD_episodenumber") .setEndTextElementListener( new EndTextElementListener() { public void end(String body) { values.put(Episodes.DVDNUMBER, body.trim()); } }); episode .getChild("FirstAired") .setEndTextElementListener( new EndTextElementListener() { public void end(String body) { long episodeAirTime = Utils.buildEpisodeAirtime(body, showAirtime); values.put(Episodes.FIRSTAIREDMS, episodeAirTime); values.put(Episodes.FIRSTAIRED, body.trim()); } }); episode .getChild("EpisodeName") .setEndTextElementListener( new EndTextElementListener() { public void end(String body) { values.put(Episodes.TITLE, body.trim()); } }); episode .getChild("Overview") .setEndTextElementListener( new EndTextElementListener() { public void end(String body) { values.put(Episodes.OVERVIEW, body.trim()); } }); episode .getChild("seasonid") .setEndTextElementListener( new EndTextElementListener() { public void end(String body) { values.put(Seasons.REF_SEASON_ID, body.trim()); } }); episode .getChild("seriesid") .setEndTextElementListener( new EndTextElementListener() { public void end(String body) { values.put(Shows.REF_SHOW_ID, body.trim()); } }); episode .getChild("Director") .setEndTextElementListener( new EndTextElementListener() { public void end(String body) { values.put(Episodes.DIRECTORS, body.trim()); } }); episode .getChild("GuestStars") .setEndTextElementListener( new EndTextElementListener() { public void end(String body) { values.put(Episodes.GUESTSTARS, body.trim()); } }); episode .getChild("Writer") .setEndTextElementListener( new EndTextElementListener() { public void end(String body) { values.put(Episodes.WRITERS, body.trim()); } }); episode .getChild("Rating") .setEndTextElementListener( new EndTextElementListener() { public void end(String body) { values.put(Episodes.RATING, body.trim()); } }); episode .getChild("filename") .setEndTextElementListener( new EndTextElementListener() { public void end(String body) { values.put(Episodes.IMAGE, body.trim()); } }); HttpUriRequest request = new HttpGet(url); HttpClient httpClient = getHttpClient(); execute(request, httpClient, root.getContentHandler(), true); return batch; }
/** * Adds a show and its episodes. If it already exists updates them. This uses two consequent * connections. The first one downloads the base series record, to check if the show is already in * the database. The second downloads all episode information. This allows for a smaller download, * if a show already exists in your database. * * @param showId * @param seenShows * @return true if show and its episodes were added, false if it already exists * @throws IOException * @throws SAXException */ public static boolean addShow(String showId, List<TvShow> seenShows, Context context) throws SAXException { String language = getTheTVDBLanguage(context); Series show = fetchShow(showId, language, context); boolean isShowExists = DBUtils.isShowExists(showId, context); final ArrayList<ContentProviderOperation> batch = Lists.newArrayList(); batch.add(DBUtils.buildShowOp(show, context, !isShowExists)); batch.addAll(importShowEpisodes(showId, show.getAirsTime(), language, context)); try { context.getContentResolver().applyBatch(SeriesContract.CONTENT_AUTHORITY, batch); } catch (RemoteException e) { // Failed binder transactions aren't recoverable throw new RuntimeException("Problem applying batch operation", e); } catch (OperationApplicationException e) { // Failures like constraint violation aren't recoverable throw new RuntimeException("Problem applying batch operation", e); } // try to find seen episodes from trakt for (TvShow tvShow : seenShows) { if (showId.equals(tvShow.tvdbId)) { batch.clear(); // try to find matching seasons final List<TvShowSeason> seasons = tvShow.seasons; for (TvShowSeason season : seasons) { final Cursor seasonMatch = context .getContentResolver() .query( Seasons.buildSeasonsOfShowUri(showId), new String[] {Seasons._ID}, Seasons.COMBINED + "=?", new String[] {season.season.toString()}, null); // add ops to mark episodes as watched if (seasonMatch.moveToFirst()) { final String seasonId = seasonMatch.getString(0); for (Integer episode : season.episodes.numbers) { batch.add( ContentProviderOperation.newUpdate(Episodes.buildEpisodesOfSeasonUri(seasonId)) .withSelection(Episodes.NUMBER + "=?", new String[] {episode.toString()}) .withValue(Episodes.WATCHED, true) .build()); } } seasonMatch.close(); } try { context.getContentResolver().applyBatch(SeriesContract.CONTENT_AUTHORITY, batch); } catch (RemoteException e) { // Failed binder transactions aren't recoverable throw new RuntimeException("Problem applying batch operation", e); } catch (OperationApplicationException e) { // Failures like constraint violation aren't // recoverable throw new RuntimeException("Problem applying batch operation", e); } break; } } DBUtils.updateLatestEpisode(context, showId); return !isShowExists; }