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

Reply via email to