package org.wikipedia.readinglist; import android.support.annotation.NonNull; import android.text.TextUtils; import org.wikipedia.dataclient.WikiSite; import org.wikipedia.dataclient.mwapi.MwQueryPage; import org.wikipedia.dataclient.mwapi.MwQueryResponse; import org.wikipedia.page.PageTitle; import org.wikipedia.readinglist.page.ReadingListPage; import org.wikipedia.readinglist.page.database.ReadingListDaoProxy; import org.wikipedia.readinglist.page.database.ReadingListPageDao; import org.wikipedia.util.BatchUtil; import org.wikipedia.util.log.L; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import retrofit2.Call; final class ReadingListPageDetailFetcher { public interface Callback{ void success(); void failure(Throwable caught); } private static ReadingListPageInfoClient CLIENT = new ReadingListPageInfoClient(); static void updateInfo(@NonNull ReadingList readingList, @NonNull final Callback cb) { Map<WikiSite, List<PageTitle>> titlesPerSite = new HashMap<>(); for (ReadingListPage page : readingList.getPages()) { if (TextUtils.isEmpty(page.thumbnailUrl()) || TextUtils.isEmpty(page.description())) { PageTitle title = ReadingListDaoProxy.pageTitle(page); WikiSite wikiKey = null; for (WikiSite wiki : titlesPerSite.keySet()) { if (wiki.equals(title.getWikiSite())) { wikiKey = wiki; break; } } if (wikiKey == null) { wikiKey = title.getWikiSite(); titlesPerSite.put(wikiKey, new ArrayList<PageTitle>()); } titlesPerSite.get(wikiKey).add(title); } } for (WikiSite wiki : titlesPerSite.keySet()) { getInfoForTitles(readingList, titlesPerSite.get(wiki), wiki, cb); } } private static void getInfoForTitles(@NonNull final ReadingList readingList, @NonNull final List<PageTitle> titles, @NonNull WikiSite wiki, @NonNull final Callback cb) { BatchUtil.makeBatches(titles, new RequestHandler(), new PagesForWikiCallback(readingList, wiki, cb)); } private static class RequestHandler implements BatchUtil.Handler<MwQueryPage> { private final List<MwQueryPage> results = new ArrayList<>(); @Override public void handleBatch(@NonNull final List<PageTitle> titles, final int total, final BatchUtil.Callback<MwQueryPage> outerCallback) { CLIENT.request(titles.get(0).getWikiSite(), titles, new ReadingListPageInfoClient.Callback() { @Override public void success(@NonNull Call<MwQueryResponse<MwQueryResponse.Pages>> call, @NonNull List<MwQueryPage> queryResults) { results.addAll(queryResults); if (results.size() == total) { outerCallback.success(results); } } @Override public void failure(@NonNull Call<MwQueryResponse<MwQueryResponse.Pages>> call, @NonNull Throwable caught) { L.w(caught); outerCallback.failure(caught); } }); } } private static class PagesForWikiCallback implements BatchUtil.Callback<MwQueryPage> { @NonNull private ReadingList readingList; @NonNull private WikiSite wiki; @NonNull private Callback callback; PagesForWikiCallback(@NonNull final ReadingList readingList, @NonNull WikiSite wiki, @NonNull final Callback cb) { this.readingList = readingList; this.wiki = wiki; this.callback = cb; } @Override public void success(@NonNull List<MwQueryPage> result) { Map<String, MwQueryPage> resultMap = makeQueryPageMap(result); for (ReadingListPage page : readingList.getPages()) { if ((isFromRequestWiki(page)) && resultMap.containsKey(page.title())) { page.setThumbnailUrl(resultMap.get(page.title()).thumbUrl()); page.setDescription(resultMap.get(page.title()).description()); ReadingListPageDao.instance().upsert(page); } } callback.success(); } @Override public void failure(@NonNull Throwable caught) { callback.failure(caught); L.w(caught); } @NonNull private Map<String, MwQueryPage> makeQueryPageMap(@NonNull List<MwQueryPage> pages) { Map<String, MwQueryPage> result = new HashMap<>(); for (MwQueryPage page : pages) { result.put(page.title(), page); } return result; } private boolean isFromRequestWiki(@NonNull ReadingListPage page) { return wiki.equals(page.wikiSite()); } } private ReadingListPageDetailFetcher() { } }