package com.thebluealliance.androidclient.datafeed; import com.google.gson.Gson; import com.google.gson.JsonElement; import com.thebluealliance.androidclient.api.rx.TbaApiV3; import com.thebluealliance.androidclient.database.Database; import com.thebluealliance.androidclient.database.DatabaseWriter; import com.thebluealliance.androidclient.database.tables.EventDetailsTable; import com.thebluealliance.androidclient.database.tables.EventsTable; import com.thebluealliance.androidclient.database.tables.MatchesTable; import com.thebluealliance.androidclient.datafeed.combiners.TeamAndEventTeamCombiner; import com.thebluealliance.androidclient.datafeed.maps.AddDistrictKeys; import com.thebluealliance.androidclient.datafeed.maps.AddDistrictTeamKey; import com.thebluealliance.androidclient.datafeed.maps.AddEventKeyToRankings; import com.thebluealliance.androidclient.datafeed.maps.AllianceEventKeyAdder; import com.thebluealliance.androidclient.datafeed.maps.DistrictTeamExtractor; import com.thebluealliance.androidclient.datafeed.maps.EventAlliancesToEventDetail; import com.thebluealliance.androidclient.datafeed.maps.JsonToEventDetail; import com.thebluealliance.androidclient.datafeed.maps.RetrofitResponseMap; import com.thebluealliance.androidclient.datafeed.maps.TeamAtEventStatusExtractor; import com.thebluealliance.androidclient.datafeed.maps.TeamAtEventStatusToEventTeam; import com.thebluealliance.androidclient.datafeed.maps.TeamMediaKeyAdder; import com.thebluealliance.androidclient.datafeed.maps.TeamStatsExtractor; import com.thebluealliance.androidclient.datafeed.maps.WeekEventsExtractor; import com.thebluealliance.androidclient.datafeed.maps.YearsParticipatedInfoMap; import com.thebluealliance.androidclient.models.Award; import com.thebluealliance.androidclient.models.District; import com.thebluealliance.androidclient.models.DistrictRanking; import com.thebluealliance.androidclient.models.Event; import com.thebluealliance.androidclient.models.EventAlliance; import com.thebluealliance.androidclient.models.EventDetail; import com.thebluealliance.androidclient.models.Match; import com.thebluealliance.androidclient.models.Media; import com.thebluealliance.androidclient.models.RankingResponseObject; import com.thebluealliance.androidclient.models.Team; import com.thebluealliance.androidclient.models.TeamAtEventStatus; import com.thebluealliance.androidclient.types.EventDetailType; import java.util.List; import javax.inject.Inject; import javax.inject.Named; import javax.inject.Singleton; import rx.Observable; @Singleton public class CacheableDatafeed { private final TbaApiV3 mApiv3; private final APICache mAPICache; private final DatabaseWriter mWriter; private final Gson mGson; private final RetrofitResponseMap mResponseMap; @Inject public CacheableDatafeed( @Named("tba_apiv3") TbaApiV3 apiv3, @Named("cache") APICache apiCache, DatabaseWriter writer, Gson gson, RetrofitResponseMap responseMap) { mApiv3 = apiv3; mAPICache = apiCache; mWriter = writer; mGson = gson; mResponseMap = responseMap; } public APICache getCache() { return mAPICache; } public Observable<List<Team>> fetchTeamPage(int pageNum, String cacheHeader) { Observable<List<Team>> apiData = mResponseMap.getAndWriteResponseBody( mApiv3.fetchTeamPage(pageNum, cacheHeader), mWriter.getTeamListWriter().get()); return mAPICache.fetchTeamPage(pageNum).concatWith(apiData); } public Observable<Team> fetchTeam(String teamKey, String cacheHeader) { Observable<Team> apiData = mResponseMap.getAndWriteResponseBody( mApiv3.fetchTeam(teamKey, cacheHeader), mWriter.getTeamWriter().get()); return mAPICache.fetchTeam(teamKey).concatWith(apiData); } public Observable<List<Event>> fetchTeamEvents(String teamKey, int year, String cacheHeader) { Observable<List<Event>> apiData = mResponseMap.getAndWriteResponseBody( mApiv3.fetchTeamEvents(teamKey, year, cacheHeader), mWriter.getEventListWriter().get()); return mAPICache.fetchTeamEvents(teamKey, year).concatWith(apiData); } public Observable<List<Event>> fetchEventsInWeek(int year, int week, String cacheHeader) { WeekEventsExtractor extractor = new WeekEventsExtractor(week); Observable<List<Event>> apiData = mResponseMap.getAndWriteResponseBody( mApiv3.fetchEventsInYear(year, cacheHeader), mWriter.getEventListWriter().get(), Database.TABLE_EVENTS, EventsTable.WEEK + " = ?", new String[]{Integer.toString(week)}); return mAPICache.fetchEventsInWeek(year, week).concatWith(apiData.map(extractor)); } public Observable<List<Award>> fetchTeamAtEventAwards( String teamKey, String eventKey, String cacheHeader) { Observable<List<Award>> apiData = mResponseMap.getAndWriteResponseBody( mApiv3.fetchTeamAtEventAwards(teamKey, eventKey, cacheHeader), mWriter.getAwardListWriter().get()); return mAPICache.fetchTeamAtEventAwards(teamKey, eventKey).concatWith(apiData); } public Observable<List<Match>> fetchTeamAtEventMatches( String teamKey, String eventKey, String cacheHeader) { Observable<List<Match>> apiData = mResponseMap.getAndWriteResponseBody( mApiv3.fetchTeamAtEventMatches(teamKey, eventKey, cacheHeader), mWriter.getMatchListWriter().get()); return mAPICache.fetchTeamAtEventMatches(teamKey, eventKey).concatWith(apiData); } public Observable<TeamAtEventStatus> fetchTeamAtEventStatus( String teamKey, String eventKey, String cacheHeader) { Observable<TeamAtEventStatus> apiData = mResponseMap.getAndWriteMappedResponseBody( mApiv3.fetchTeamAtEventStatus(teamKey, eventKey, cacheHeader), new TeamAtEventStatusToEventTeam(teamKey, eventKey), mWriter.getEventTeamWriter().get()); return mAPICache.fetchEventTeam(teamKey, eventKey) .map(new TeamAtEventStatusExtractor()) .concatWith(apiData); } public Observable<List<Integer>> fetchTeamYearsParticipated(String teamKey, String cacheHeader) { Observable<List<Integer>> apiData = mResponseMap.getAndWriteMappedResponseBody( mApiv3.fetchTeamYearsParticipated(teamKey, cacheHeader), new YearsParticipatedInfoMap(teamKey), mWriter.getYearsParticipatedWriter().get()); return mAPICache.fetchTeamYearsParticipated(teamKey).concatWith(apiData); } public Observable<List<Media>> fetchTeamMediaInYear(String teamKey, int year, String cacheHeader) { Observable<List<Media>> apiData = mResponseMap.mapAndWriteResponseBody( mApiv3.fetchTeamMediaInYear(teamKey, year, cacheHeader), new TeamMediaKeyAdder(teamKey, year), mWriter.getMediaListWriter().get()); return mAPICache.fetchTeamMediaInYear(teamKey, year).concatWith(apiData); } public Observable<List<Media>> fetchTeamSocialMedia(String teamKey, String cacheHeader) { Observable<List<Media>> apiData = mResponseMap.mapAndWriteResponseBody( mApiv3.fetchTeamSocialMedia(teamKey, cacheHeader), new TeamMediaKeyAdder(teamKey, -1), // Social media don't have a specific year mWriter.getMediaListWriter().get()); return mAPICache.fetchTeamSocialMedia(teamKey).concatWith(apiData); } public Observable<List<Event>> fetchEventsInYear(int year, String cacheHeader) { Observable<List<Event>> apiData = mResponseMap.getAndWriteResponseBody( mApiv3.fetchEventsInYear(year, cacheHeader), mWriter.getEventListWriter().get(), Database.TABLE_EVENTS, EventsTable.YEAR + " = ?", new String[]{Integer.toString(year)}); return mAPICache.fetchEventsInYear(year).concatWith(apiData); } public Observable<Event> fetchEvent(String eventKey, String cacheHeader) { Observable<Event> apiData = mResponseMap.getAndWriteResponseBody( mApiv3.fetchEvent(eventKey, cacheHeader), mWriter.getEventWriter().get()); return mAPICache.fetchEvent(eventKey).concatWith(apiData); } public Observable<List<Team>> fetchEventTeams(String eventKey, String cacheHeader) { Observable<List<Team>> apiData = mResponseMap.getAndWriteMappedResponseBody( mApiv3.fetchEventTeams(eventKey, cacheHeader), new TeamAndEventTeamCombiner(eventKey), mWriter.getEventTeamAndTeamListWriter().get()); return mAPICache.fetchEventTeams(eventKey).concatWith(apiData); } public Observable<RankingResponseObject> fetchEventRankings(String eventKey, String cacheHeader) { Observable<RankingResponseObject> apiData = mResponseMap.getAndWriteMappedResponseBody( mApiv3.fetchEventRankings(eventKey, cacheHeader), new AddEventKeyToRankings(eventKey, mGson), mWriter.getEventDetailWriter().get(), Database.TABLE_EVENTDETAILS, EventDetailsTable.KEY + " = ?", new String[]{EventDetail.buildKey(eventKey, EventDetailType.RANKINGS)} ).map(new AddEventKeyToRankings.ApiMap(eventKey)); return mAPICache.fetchEventRankings(eventKey).concatWith(apiData); } public Observable<List<EventAlliance>> fetchEventAlliances(String eventKey, String cacheHeader) { Observable<List<EventAlliance>> apiData = mResponseMap.getAndWriteMappedResponseBody( mApiv3.fetchEventAlliances(eventKey, cacheHeader), new EventAlliancesToEventDetail(eventKey, mGson), mWriter.getEventDetailWriter().get(), Database.TABLE_EVENTDETAILS, EventDetailsTable.KEY + " = ?", new String[]{EventDetail.buildKey(eventKey, EventDetailType.RANKINGS)} ).map(new AllianceEventKeyAdder(eventKey)); return mAPICache.fetchEventAlliances(eventKey).concatWith(apiData); } public Observable<List<Match>> fetchEventMatches(String eventKey, String cacheHeader) { Observable<List<Match>> apiData = mResponseMap.getAndWriteResponseBody( mApiv3.fetchEventMatches(eventKey, cacheHeader), mWriter.getMatchListWriter().get(), Database.TABLE_MATCHES, MatchesTable.EVENT + " = ?", new String[]{eventKey}); return mAPICache.fetchEventMatches(eventKey).concatWith(apiData); } public Observable<? extends JsonElement> fetchEventStats(String eventKey, String cacheHeader) { Observable<JsonElement> apiData = mResponseMap.getAndWriteMappedResponseBody( mApiv3.fetchEventOPR(eventKey, cacheHeader), new JsonToEventDetail(eventKey, EventDetailType.OPRS), mWriter.getEventDetailWriter().get()); return mAPICache.fetchJsonEventDetail(eventKey, EventDetailType.OPRS).concatWith(apiData); } public Observable<? extends JsonElement> fetchEventInsights(String eventKey, String cacheHeader) { Observable<JsonElement> apiData = mResponseMap.getAndWriteMappedResponseBody( mApiv3.fetchEventInsights(eventKey, cacheHeader), new JsonToEventDetail(eventKey, EventDetailType.INSIGHTS), mWriter.getEventDetailWriter().get() ); return mAPICache.fetchJsonEventDetail(eventKey, EventDetailType.INSIGHTS).concatWith(apiData); } public Observable<? extends JsonElement> fetchTeamAtEventStats( String eventKey, String teamKey, String cacheHeader) { TeamStatsExtractor extractor = new TeamStatsExtractor(teamKey); return fetchEventStats(eventKey, cacheHeader).map(extractor); } public Observable<List<Award>> fetchEventAwards(String eventKey, String cacheHeader) { Observable<List<Award>> apiData = mResponseMap.getAndWriteResponseBody( mApiv3.fetchEventAwards(eventKey, cacheHeader), mWriter.getAwardListWriter().get()); return mAPICache.fetchEventAwards(eventKey).concatWith(apiData); } public Observable<? extends JsonElement> fetchEventDistrictPoints(String eventKey, String cacheHeader) { Observable<JsonElement> apiData = mResponseMap.getAndWriteMappedResponseBody( mApiv3.fetchEventDistrictPoints(eventKey, cacheHeader), new JsonToEventDetail(eventKey, EventDetailType.DISTRICT_POINTS), mWriter.getEventDetailWriter().get()); return mAPICache.fetchJsonEventDetail(eventKey, EventDetailType.DISTRICT_POINTS).concatWith(apiData); } public Observable<List<District>> fetchDistrictList(int year, String cacheHeader) { Observable<List<District>> apiData = mResponseMap.mapAndWriteResponseBody( mApiv3.fetchDistrictList(year, cacheHeader), new AddDistrictKeys(year), mWriter.getDistrictListWriter().get()); return mAPICache.fetchDistrictList(year).concatWith(apiData); } public Observable<List<Event>> fetchDistrictEvents(String districtKey, String cacheHeader) { Observable<List<Event>> apiData = mResponseMap.getAndWriteResponseBody( mApiv3.fetchDistrictEvents(districtKey, cacheHeader), mWriter.getEventListWriter().get()); return mAPICache.fetchDistrictEvents(districtKey).concatWith(apiData); } public Observable<List<DistrictRanking>> fetchDistrictRankings(String districtKey, String cacheHeader) { Observable<List<DistrictRanking>> apiData = mResponseMap.mapAndWriteResponseBody( mApiv3.fetchDistrictRankings(districtKey, cacheHeader), new AddDistrictTeamKey(districtKey), mWriter.getDistrictTeamListWriter().get()); return mAPICache.fetchDistrictRankings(districtKey).concatWith(apiData); } public Observable<DistrictRanking> fetchTeamAtDistrictRankings( String teamKey, String districtKey, String cacheHeader) { return fetchDistrictRankings(districtKey, cacheHeader) .map(new DistrictTeamExtractor(teamKey)); } public Observable<Match> fetchMatch(String matchKey, String cacheHeader) { Observable<Match> apiData = mResponseMap.getAndWriteResponseBody( mApiv3.fetchMatch(matchKey, cacheHeader), mWriter.getMatchWriter().get()); return mAPICache.fetchMatch(matchKey).concatWith(apiData); } }