Niedzielski has uploaded a new change for review.
https://gerrit.wikimedia.org/r/270246
Change subject: Add user option data client
......................................................................
Add user option data client
No functional changes intended at this time. This code is exercised by a
subsequent patch.
Change-Id: I7a3f3663dcd9c383d84bf2ca16eafb8a1469e491
---
A app/src/main/java/org/wikipedia/dataclient/mwapi/MwQueryResponse.java
A app/src/main/java/org/wikipedia/useroption/UserInfo.java
A app/src/main/java/org/wikipedia/useroption/UserOption.java
A
app/src/main/java/org/wikipedia/useroption/dataclient/DefaultUserOptionDataClient.java
A
app/src/main/java/org/wikipedia/useroption/dataclient/UserInfoDataClientSingleton.java
A
app/src/main/java/org/wikipedia/useroption/dataclient/UserOptionDataClient.java
6 files changed, 269 insertions(+), 0 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/apps/android/wikipedia
refs/changes/46/270246/1
diff --git
a/app/src/main/java/org/wikipedia/dataclient/mwapi/MwQueryResponse.java
b/app/src/main/java/org/wikipedia/dataclient/mwapi/MwQueryResponse.java
new file mode 100644
index 0000000..1982a82
--- /dev/null
+++ b/app/src/main/java/org/wikipedia/dataclient/mwapi/MwQueryResponse.java
@@ -0,0 +1,17 @@
+package org.wikipedia.dataclient.mwapi;
+
+import com.google.gson.annotations.SerializedName;
+
+public class MwQueryResponse<T> {
+ @SerializedName("batchcomplete")
+ private boolean batchComplete;
+ private T query;
+
+ public boolean batchComplete() {
+ return batchComplete;
+ }
+
+ public T query() {
+ return query;
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/wikipedia/useroption/UserInfo.java
b/app/src/main/java/org/wikipedia/useroption/UserInfo.java
new file mode 100644
index 0000000..48ad343
--- /dev/null
+++ b/app/src/main/java/org/wikipedia/useroption/UserInfo.java
@@ -0,0 +1,46 @@
+package org.wikipedia.useroption;
+
+import android.support.annotation.NonNull;
+import android.support.annotation.Nullable;
+
+import com.google.gson.annotations.SerializedName;
+
+import java.util.Map;
+
+public class UserInfo {
+ @SerializedName("name")
+ private String username;
+ private int id;
+
+ // Object type is a JSON primitive.
+ @NonNull private Map<String, Object> options;
+
+ public int id() {
+ return id;
+ }
+
+ @NonNull
+ public String username() {
+ return username;
+ }
+
+ public boolean hasOption(String key) {
+ return options.containsKey(key);
+ }
+
+ @Nullable
+ public <T> T option(String key) {
+ //noinspection unchecked
+ return (T) options.get(key);
+ }
+
+ // Auto-generated
+ @Override
+ public String toString() {
+ return "UserInfo{"
+ + "username='" + username + '\''
+ + ", id=" + id
+ + ", options=" + options
+ + '}';
+ }
+}
\ No newline at end of file
diff --git a/app/src/main/java/org/wikipedia/useroption/UserOption.java
b/app/src/main/java/org/wikipedia/useroption/UserOption.java
new file mode 100644
index 0000000..be537ba
--- /dev/null
+++ b/app/src/main/java/org/wikipedia/useroption/UserOption.java
@@ -0,0 +1,30 @@
+package org.wikipedia.useroption;
+
+import android.support.annotation.NonNull;
+
+public class UserOption {
+ @NonNull private final String key;
+ private final boolean enabled;
+
+ public UserOption(@NonNull String key, boolean enabled) {
+ this.key = key;
+ this.enabled = enabled;
+ }
+
+ @NonNull public String key() {
+ return key;
+ }
+
+ public boolean enabled() {
+ return enabled;
+ }
+
+ // Auto-generated
+ @Override
+ public String toString() {
+ return "UserOption{"
+ + "key='" + key + '\''
+ + ", enabled=" + enabled
+ + '}';
+ }
+}
\ No newline at end of file
diff --git
a/app/src/main/java/org/wikipedia/useroption/dataclient/DefaultUserOptionDataClient.java
b/app/src/main/java/org/wikipedia/useroption/dataclient/DefaultUserOptionDataClient.java
new file mode 100644
index 0000000..007371d
--- /dev/null
+++
b/app/src/main/java/org/wikipedia/useroption/dataclient/DefaultUserOptionDataClient.java
@@ -0,0 +1,143 @@
+package org.wikipedia.useroption.dataclient;
+
+import android.support.annotation.NonNull;
+
+import com.google.gson.annotations.SerializedName;
+
+import org.wikipedia.Site;
+import org.wikipedia.WikipediaApp;
+import org.wikipedia.dataclient.RestAdapterFactory;
+import org.wikipedia.dataclient.mwapi.MwQueryResponse;
+import org.wikipedia.editing.EditTokenStorage;
+import org.wikipedia.useroption.UserInfo;
+import org.wikipedia.useroption.UserOption;
+
+import java.io.IOException;
+
+import retrofit.Callback;
+import retrofit.RetrofitError;
+import retrofit.client.Response;
+import retrofit.http.Field;
+import retrofit.http.FormUrlEncoded;
+import retrofit.http.GET;
+import retrofit.http.POST;
+import retrofit.http.Query;
+
+public class DefaultUserOptionDataClient implements UserOptionDataClient {
+ @NonNull private final Site site;
+ @NonNull private final Client client;
+
+ public DefaultUserOptionDataClient(@NonNull Site site) {
+ this.site = site;
+ client = RestAdapterFactory.newInstance(site).create(Client.class);
+ }
+
+ @Override
+ public void get(@NonNull Callback<UserInfo> callback) {
+ client.get(new GetCallback(callback));
+ }
+
+ @Override
+ public void post(@NonNull UserOption option, @NonNull Callback<Void>
callback) {
+ getToken(new TokenCallback(option, callback));
+ }
+
+ private void getToken(@NonNull TokenCallback callback) {
+ WikipediaApp.getInstance().getEditTokenStorage().get(site, callback);
+ }
+
+ private interface Client {
+ String ACTION = "/w/api.php?format=json&formatversion=2&action=";
+
+ @GET(ACTION + "query&meta=userinfo&uiprop=options")
+ void get(@NonNull Callback<MwQueryResponse<QueryUserInfo>> callback);
+
+ @FormUrlEncoded
+ @POST(ACTION + "options")
+ void post(@Field("token") @NonNull String token,
+ @Query("optionname") @NonNull String key,
+ @Query("optionvalue") @NonNull String value,
+ @NonNull Callback<PostResponse> callback);
+ }
+
+ private static class PostResponse {
+ private String options;
+
+ public boolean success() {
+ return "success".equals(options);
+ }
+ }
+
+ private static class QueryUserInfo {
+ @SerializedName("userinfo")
+ private UserInfo userInfo;
+
+ public UserInfo userInfo() {
+ return userInfo;
+ }
+ }
+
+ private class TokenCallback implements
EditTokenStorage.TokenRetrievedCallback {
+ @NonNull private final UserOption option;
+ @NonNull private final PostCallback callback;
+
+ TokenCallback(@NonNull UserOption option, @NonNull Callback<Void>
callback) {
+ this.option = option;
+ this.callback = new PostCallback(callback);
+ }
+
+ @Override
+ public void onTokenRetrieved(String token) {
+ client.post(token, option.key(), String.valueOf(option.enabled()),
callback);
+ }
+
+ @Override
+ public void onTokenFailed(Throwable caught) {
+ // TODO: pass actual URL.
+ callback.failure(RetrofitError.unexpectedError(option.key(),
caught));
+ }
+ }
+
+ private static class PostCallback extends CallbackWrapper<PostResponse,
Void> {
+ PostCallback(@NonNull Callback<Void> callback) {
+ super(callback);
+ }
+
+ @Override
+ public void success(PostResponse result, Response response) {
+ if (result.success()) {
+ callback().success(null, response);
+ } else {
+ failure(RetrofitError.networkError(response.getUrl(), new
IOException()));
+ }
+ }
+ }
+
+ private static class GetCallback extends
CallbackWrapper<MwQueryResponse<QueryUserInfo>, UserInfo> {
+ GetCallback(@NonNull Callback<UserInfo> callback) {
+ super(callback);
+ }
+
+ @Override
+ public void success(MwQueryResponse<QueryUserInfo> result, Response
response) {
+ callback().success(result.query().userInfo(), response);
+ }
+ }
+
+ private abstract static class CallbackWrapper<Wrapper, Wrapped> implements
Callback<Wrapper> {
+ @NonNull private final Callback<Wrapped> callback;
+
+ CallbackWrapper(@NonNull Callback<Wrapped> callback) {
+ this.callback = callback;
+ }
+
+ @Override
+ public void failure(RetrofitError error) {
+ callback.failure(error);
+ }
+
+ protected Callback<Wrapped> callback() {
+ return callback;
+ }
+ }
+}
\ No newline at end of file
diff --git
a/app/src/main/java/org/wikipedia/useroption/dataclient/UserInfoDataClientSingleton.java
b/app/src/main/java/org/wikipedia/useroption/dataclient/UserInfoDataClientSingleton.java
new file mode 100644
index 0000000..ec13e04
--- /dev/null
+++
b/app/src/main/java/org/wikipedia/useroption/dataclient/UserInfoDataClientSingleton.java
@@ -0,0 +1,20 @@
+package org.wikipedia.useroption.dataclient;
+
+import org.wikipedia.Site;
+
+public final class UserInfoDataClientSingleton {
+ public static UserOptionDataClient instance() {
+ return LazyHolder.INSTANCE;
+ }
+
+ private UserInfoDataClientSingleton() { }
+
+ private static class LazyHolder {
+ private static final UserOptionDataClient INSTANCE = instance();
+
+ private static UserOptionDataClient instance() {
+ Site site = new Site("meta.wikimedia.org");
+ return new DefaultUserOptionDataClient(site);
+ }
+ }
+}
\ No newline at end of file
diff --git
a/app/src/main/java/org/wikipedia/useroption/dataclient/UserOptionDataClient.java
b/app/src/main/java/org/wikipedia/useroption/dataclient/UserOptionDataClient.java
new file mode 100644
index 0000000..f9347ac
--- /dev/null
+++
b/app/src/main/java/org/wikipedia/useroption/dataclient/UserOptionDataClient.java
@@ -0,0 +1,13 @@
+package org.wikipedia.useroption.dataclient;
+
+import android.support.annotation.NonNull;
+
+import org.wikipedia.useroption.UserInfo;
+import org.wikipedia.useroption.UserOption;
+
+import retrofit.Callback;
+
+public interface UserOptionDataClient {
+ void get(@NonNull Callback<UserInfo> callback);
+ void post(@NonNull UserOption option, @NonNull Callback<Void> callback);
+}
\ No newline at end of file
--
To view, visit https://gerrit.wikimedia.org/r/270246
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I7a3f3663dcd9c383d84bf2ca16eafb8a1469e491
Gerrit-PatchSet: 1
Gerrit-Project: apps/android/wikipedia
Gerrit-Branch: master
Gerrit-Owner: Niedzielski <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits