Florianschmidtwelzow has uploaded a new change for review. ( https://gerrit.wikimedia.org/r/354940 )
Change subject: WIP: Use MediaWiki API for Random page if restbase is turned off ...................................................................... WIP: Use MediaWiki API for Random page if restbase is turned off Until now, random pages will work with restbase only, or when the user has lists and pages can be selected randomly from there. If a third-party wiki does not have restbase, the random page will now be retrieved using the mediawiki api endpoint query->random. Things to do: * The tests are failing for some reason, clarifying with Bernd. Bug: T165960 Change-Id: Ie37fb2004c9a9785f53689385f293134ee43d2f0 --- A app/src/main/java/org/wikipedia/dataclient/mwapi/MwQueryRandom.java M app/src/main/java/org/wikipedia/feed/random/RandomCardView.java M app/src/main/java/org/wikipedia/random/RandomSummaryClient.java M app/src/test/java/org/wikipedia/random/RandomSummaryClientTest.java 4 files changed, 167 insertions(+), 42 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/apps/android/wikipedia refs/changes/40/354940/1 diff --git a/app/src/main/java/org/wikipedia/dataclient/mwapi/MwQueryRandom.java b/app/src/main/java/org/wikipedia/dataclient/mwapi/MwQueryRandom.java new file mode 100644 index 0000000..6a0a09d --- /dev/null +++ b/app/src/main/java/org/wikipedia/dataclient/mwapi/MwQueryRandom.java @@ -0,0 +1,65 @@ +package org.wikipedia.dataclient.mwapi; + +import android.support.annotation.Nullable; + +import com.google.gson.annotations.SerializedName; + +import org.wikipedia.dataclient.ServiceError; +import org.wikipedia.dataclient.page.PageSummary; +import org.wikipedia.model.BaseModel; + +/** + * A class representing a response from the random query api. + */ +public class MwQueryRandom extends BaseModel implements PageSummary { + @SuppressWarnings("unused") @Nullable private MwQuery query; + @SuppressWarnings("unused") @SerializedName("error") @Nullable + private MwServiceError error; + + @Override + public boolean hasError() { + return error != null; + } + + @Override @Nullable + public ServiceError getError() { + return error; + } + + @Override @Nullable + public String getTitle() { + if (query != null && query.getFirstRandom() != null) { + return query.getFirstRandom().getTitle(); + } + return null; + } + + @Override @Nullable + public String getExtract() { + return null; + } + + @Override @Nullable + public String getThumbnailUrl() { + return null; + } + + private static class MwQuery { + @SuppressWarnings("unused,MismatchedReadAndWriteOfArray") + @Nullable private MwRandom[] random; + + @Nullable + MwRandom getFirstRandom() { + return random != null && random.length >= 1 ? random[0] : null; + } + } + + private static class MwRandom { + @SuppressWarnings("unused") @Nullable private String title; + + @Nullable + public String getTitle() { + return this.title; + } + } +} diff --git a/app/src/main/java/org/wikipedia/feed/random/RandomCardView.java b/app/src/main/java/org/wikipedia/feed/random/RandomCardView.java index f843607..91eb6a9 100644 --- a/app/src/main/java/org/wikipedia/feed/random/RandomCardView.java +++ b/app/src/main/java/org/wikipedia/feed/random/RandomCardView.java @@ -7,13 +7,13 @@ import org.wikipedia.R; import org.wikipedia.concurrency.CallbackTask; -import org.wikipedia.dataclient.restbase.page.RbPageSummary; import org.wikipedia.feed.view.FeedAdapter; import org.wikipedia.feed.view.StaticCardView; import org.wikipedia.history.HistoryEntry; import org.wikipedia.page.PageTitle; import org.wikipedia.random.RandomSummaryClient; import org.wikipedia.readinglist.page.database.ReadingListPageDao; +import org.wikipedia.settings.RbSwitch; import org.wikipedia.util.log.L; import retrofit2.Call; @@ -40,13 +40,18 @@ public void onClick(View view) { if (getCallback() != null && getCard() != null) { setProgress(true); - new RandomSummaryClient().request(getCard().wikiSite(), serviceCallback); + RandomSummaryClient randomSummaryClient = new RandomSummaryClient(); + if (RbSwitch.INSTANCE.isRestBaseEnabled(getCard().wikiSite())) { + randomSummaryClient.requestRestbase(getCard().wikiSite(), serviceCallback); + } else { + randomSummaryClient.requestMwapi(getCard().wikiSite(), serviceCallback); + } } } private RandomSummaryClient.Callback serviceCallback = new RandomSummaryClient.Callback() { @Override - public void onSuccess(@NonNull Call<RbPageSummary> call, @NonNull PageTitle title) { + public void onSuccess(@NonNull Call call, @NonNull PageTitle title) { setProgress(false); if (getCallback() != null && getCard() != null) { getCallback().onSelectPage(getCard(), @@ -55,7 +60,7 @@ } @Override - public void onError(@NonNull Call<RbPageSummary> call, @NonNull Throwable t) { + public void onError(@NonNull Call call, @NonNull Throwable t) { L.w("Failed to get random card from network. Falling back to reading lists.", t); getRandomReadingListPage(t); setProgress(false); diff --git a/app/src/main/java/org/wikipedia/random/RandomSummaryClient.java b/app/src/main/java/org/wikipedia/random/RandomSummaryClient.java index a8b794f..c182404 100644 --- a/app/src/main/java/org/wikipedia/random/RandomSummaryClient.java +++ b/app/src/main/java/org/wikipedia/random/RandomSummaryClient.java @@ -6,7 +6,10 @@ import com.google.gson.JsonParseException; import org.wikipedia.dataclient.WikiSite; +import org.wikipedia.dataclient.mwapi.MwQueryRandom; +import org.wikipedia.dataclient.page.PageSummary; import org.wikipedia.dataclient.restbase.page.RbPageSummary; +import org.wikipedia.dataclient.retrofit.MwCachedService; import org.wikipedia.dataclient.retrofit.RbCachedService; import org.wikipedia.dataclient.retrofit.WikiCachedService; import org.wikipedia.page.PageTitle; @@ -20,47 +23,82 @@ import static org.wikipedia.Constants.ACCEPT_HEADER_SUMMARY; public class RandomSummaryClient { - @NonNull private final WikiCachedService<Service> cachedService - = new RbCachedService<>(Service.class); + @NonNull private final WikiCachedService<RbService> cachedRbService + = new RbCachedService<>(RbService.class); - public Call<RbPageSummary> request(@NonNull WikiSite wiki, @NonNull Callback cb) { - return request(cachedService.service(wiki), wiki, cb); + @NonNull private final WikiCachedService<MwService> cachedMwService = + new MwCachedService<>(MwService.class); + + public Call<RbPageSummary> requestRestbase(@NonNull WikiSite wiki, @NonNull Callback cb) { + return requestRestbase(cachedRbService.service(wiki), wiki, cb); } - @VisibleForTesting Call<RbPageSummary> request(@NonNull Service service, - @NonNull final WikiSite wiki, - @NonNull final Callback cb) { - Call<RbPageSummary> call = service.get(); - call.enqueue(new retrofit2.Callback<RbPageSummary>() { - @Override - public void onResponse(@NonNull Call<RbPageSummary> call, - @NonNull Response<RbPageSummary> response) { - if (response.body() == null) { - cb.onError(call, new JsonParseException("Response missing required field(s)")); - return; - } - RbPageSummary item = response.body(); - PageTitle title = new PageTitle(null, item.getTitle(), wiki); - cb.onSuccess(call, title); - } + public Call<MwQueryRandom> requestMwapi(@NonNull WikiSite wiki, @NonNull Callback cb) { + return requestMwapi(cachedMwService.service(wiki), wiki, cb); + } - @Override - public void onFailure(@NonNull Call<RbPageSummary> call, @NonNull Throwable t) { - L.w("Failed to get random page title/summary", t); - cb.onError(call, t); - } - }); + @VisibleForTesting Call<MwQueryRandom> requestMwapi(@NonNull MwService service, + @NonNull final WikiSite wiki, + @NonNull final Callback cb) { + Call<MwQueryRandom> call = service.get(); + call.enqueue(new RandomCallback<MwQueryRandom>(cb, wiki)); + return call; } - @VisibleForTesting interface Service { + @VisibleForTesting Call<RbPageSummary> requestRestbase(@NonNull RbService service, + @NonNull final WikiSite wiki, + @NonNull final Callback cb) { + Call<RbPageSummary> call = service.get(); + call.enqueue(new RandomCallback<RbPageSummary>(cb, wiki)); + + return call; + } + + private class RandomCallback<T extends PageSummary> implements retrofit2.Callback<T> { + private Callback callback; + private final WikiSite wiki; + + RandomCallback(Callback cb, WikiSite wiki) { + this.callback = cb; + this.wiki = wiki; + } + @Override + public void onResponse(@NonNull Call<T> call, + @NonNull Response<T> response) { + if (response.body() == null) { + callback.onError(call, new JsonParseException("Response missing required field(s)")); + return; + } + T item = response.body(); + if (item.getTitle() == null) { + callback.onError(call, new JsonParseException("Response is missing title.")); + return; + } + PageTitle title = new PageTitle(null, item.getTitle(), wiki); + callback.onSuccess(call, title); + } + + @Override + public void onFailure(@NonNull Call<T> call, @NonNull Throwable t) { + L.w("Failed to get random page title/summary", t); + callback.onError(call, t); + } + } + + @VisibleForTesting interface RbService { @Headers(ACCEPT_HEADER_SUMMARY) @GET("page/random/summary") @NonNull Call<RbPageSummary> get(); } + @VisibleForTesting interface MwService { + @GET("w/api.php?action=query&list=random&rnnamespace=0&format=json") + @NonNull Call<MwQueryRandom> get(); + } + public interface Callback { - void onSuccess(@NonNull Call<RbPageSummary> call, @NonNull PageTitle title); - void onError(@NonNull Call<RbPageSummary> call, @NonNull Throwable t); + void onSuccess(@NonNull Call call, @NonNull PageTitle title); + void onError(@NonNull Call call, @NonNull Throwable t); } } diff --git a/app/src/test/java/org/wikipedia/random/RandomSummaryClientTest.java b/app/src/test/java/org/wikipedia/random/RandomSummaryClientTest.java index bf845ad..d5cacc7 100644 --- a/app/src/test/java/org/wikipedia/random/RandomSummaryClientTest.java +++ b/app/src/test/java/org/wikipedia/random/RandomSummaryClientTest.java @@ -7,10 +7,12 @@ import org.junit.Test; import org.wikipedia.dataclient.WikiSite; +import org.wikipedia.dataclient.mwapi.MwQueryRandom; import org.wikipedia.dataclient.restbase.page.RbPageSummary; import org.wikipedia.page.PageTitle; import org.wikipedia.random.RandomSummaryClient.Callback; -import org.wikipedia.random.RandomSummaryClient.Service; +import org.wikipedia.random.RandomSummaryClient.MwService; +import org.wikipedia.random.RandomSummaryClient.RbService; import org.wikipedia.test.MockWebServerTest; import java.io.IOException; @@ -28,21 +30,32 @@ @NonNull private RandomSummaryClient client = new RandomSummaryClient(); @Test - public void testRequestEligible() throws Throwable { + public void testRequestEligibleRestbase() throws Throwable { enqueueFromFile("rb_page_summary_valid.json"); Callback cb = mock(Callback.class); - Call<RbPageSummary> call = request(cb); + Call<RbPageSummary> call = requestRestbase(cb); server().takeRequest(); assertCallbackSuccess(call, cb); + } + + @Test + public void testRequestEligibleMwApi() throws Throwable { + enqueueFromFile("api_error.json"); + + Callback cb = mock(Callback.class); + Call<MwQueryRandom> call = requestMwapi(cb); + + server().takeRequest(); + assertCallbackFailure(call, cb, JsonParseException.class); } @Test public void testRequestMalformed() throws Throwable { enqueueFromFile("rb_page_summary_malformed.json"); Callback cb = mock(Callback.class); - Call<RbPageSummary> call = request(cb); + Call<RbPageSummary> call = requestRestbase(cb); server().takeRequest(); assertCallbackFailure(call, cb, JsonParseException.class); @@ -52,24 +65,28 @@ enqueue404(); Callback cb = mock(Callback.class); - Call<RbPageSummary> call = request(cb); + Call<RbPageSummary> call = requestRestbase(cb); server().takeRequest(); assertCallbackFailure(call, cb, IOException.class); } - @NonNull private Call<RbPageSummary> request(@NonNull Callback cb) { - return client.request(service(Service.class), WikiSite.forLanguageCode("test"), cb); + @NonNull private Call<RbPageSummary> requestRestbase(@NonNull Callback cb) { + return client.requestRestbase(service(RbService.class), WikiSite.forLanguageCode("test"), cb); } - private void assertCallbackSuccess(@NonNull Call<RbPageSummary> call, + @NonNull private Call<MwQueryRandom> requestMwapi(@NonNull Callback cb) { + return client.requestMwapi(service(MwService.class), WikiSite.forLanguageCode("test"), cb); + } + + private void assertCallbackSuccess(@NonNull Call call, @NonNull Callback cb) { verify(cb).onSuccess(eq(call), any(PageTitle.class)); //noinspection unchecked verify(cb, never()).onError(any(Call.class), any(Throwable.class)); } - private void assertCallbackFailure(@NonNull Call<RbPageSummary> call, + private void assertCallbackFailure(@NonNull Call call, @NonNull Callback cb, @NonNull Class<? extends Throwable> expectedThrowable) { //noinspection unchecked -- To view, visit https://gerrit.wikimedia.org/r/354940 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Ie37fb2004c9a9785f53689385f293134ee43d2f0 Gerrit-PatchSet: 1 Gerrit-Project: apps/android/wikipedia Gerrit-Branch: master Gerrit-Owner: Florianschmidtwelzow <florian.schmidt.stargatewis...@gmail.com> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits