/**
* Interface to the WordPress.com REST API.
*/
package kr.kdev.dg1s.biowiki.networking;
import android.os.AsyncTask;
import com.android.volley.DefaultRetryPolicy;
import com.android.volley.Request.Method;
import com.android.volley.RequestQueue;
import com.android.volley.RetryPolicy;
import com.android.volley.VolleyError;
import com.wordpress.rest.RestClient;
import com.wordpress.rest.RestRequest;
import com.wordpress.rest.RestRequest.ErrorListener;
import com.wordpress.rest.RestRequest.Listener;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import kr.kdev.dg1s.biowiki.BioWiki;
import kr.kdev.dg1s.biowiki.models.Note;
import kr.kdev.dg1s.biowiki.util.AppLog;
public class RestClientUtils {
/**
* Socket timeout in milliseconds for rest requests
*/
public static final int REST_TIMEOUT_MS = 30000;
/**
* Default number of retries for POST rest requests
*/
public static final int REST_MAX_RETRIES_POST = 0;
/**
* Default number of retries for GET rest requests
*/
public static final int REST_MAX_RETRIES_GET = 3;
/**
* Default backoff multiplier for rest requests
*/
public static final float REST_BACKOFF_MULT = 2f;
private static final String NOTIFICATION_FIELDS = "id,type,unread,body,subject,timestamp,meta";
private static final String COMMENT_REPLY_CONTENT_FIELD = "content";
private RestClient mRestClient;
private Authenticator mAuthenticator;
public RestClientUtils(RequestQueue queue, Authenticator authenticator) {
// load an existing access token from prefs if we have one
mAuthenticator = authenticator;
mRestClient = RestClientFactory.instantiate(queue);
mRestClient.setUserAgent(BioWiki.getUserAgent());
}
/**
* Reply to a comment using a Note.Reply object.
* <p/>
* https://developer.wordpress.com/docs/api/1/post/sites/%24site/posts/%24post_ID/replies/new/
*/
public void replyToComment(Note.Reply reply, Listener listener, ErrorListener errorListener) {
Map<String, String> params = new HashMap<String, String>();
params.put(COMMENT_REPLY_CONTENT_FIELD, reply.getContent());
post(reply.getRestPath(), params, null, listener, errorListener);
}
/**
* Reply to a comment.
* <p/>
* https://developer.wordpress.com/docs/api/1/post/sites/%24site/posts/%24post_ID/replies/new/
*/
public void replyToComment(String siteId, String commentId, String content, Listener listener,
ErrorListener errorListener) {
Map<String, String> params = new HashMap<String, String>();
params.put(COMMENT_REPLY_CONTENT_FIELD, content);
String path = String.format("sites/%s/comments/%s/replies/new", siteId, commentId);
post(path, params, null, listener, errorListener);
}
/**
* Follow a site given an ID or domain
* <p/>
* https://developer.wordpress.com/docs/api/1/post/sites/%24site/follows/new/
*/
public void followSite(String siteId, Listener listener, ErrorListener errorListener) {
String path = String.format("sites/%s/follows/new", siteId);
post(path, listener, errorListener);
}
/**
* Unfollow a site given an ID or domain
* <p/>
* https://developer.wordpress.com/docs/api/1/post/sites/%24site/follows/mine/delete/
*/
public void unfollowSite(String siteId, Listener listener, ErrorListener errorListener) {
String path = String.format("sites/%s/follows/mine/delete", siteId);
post(path, listener, errorListener);
}
/**
* Get a single notification.
* <p/>
* https://developer.wordpress.com/docs/api/1/get/notifications/
*/
public void getNotification(String noteId, Listener listener, ErrorListener errorListener) {
Map<String, String> params = new HashMap<String, String>();
params.put("fields", NOTIFICATION_FIELDS);
get(String.format("notifications/%s", noteId), params, null, listener, errorListener);
}
/**
* Mark a notification as read
* <p/>
* https://developer.wordpress.com/docs/api/1/post/notifications/read/
*/
public void markNoteAsRead(Note note, Listener listener, ErrorListener errorListener) {
String path = "notifications/read";
Map<String, String> params = new HashMap<String, String>();
params.put(String.format("counts[%s]", note.getId()), note.getUnreadCount());
post(path, params, null, listener, errorListener);
}
/**
* Get notifications with the provided params.
* <p/>
* https://developer.wordpress.com/docs/api/1/get/notifications/
*/
public void getNotifications(Map<String, String> params, Listener listener, ErrorListener errorListener) {
params.put("number", "40");
params.put("num_note_items", "20");
params.put("fields", NOTIFICATION_FIELDS);
get("notifications", params, null, listener, errorListener);
}
/**
* Get notifications with default params.
* <p/>
* https://developer.wordpress.com/docs/api/1/get/notifications/
*/
public void getNotifications(Listener listener, ErrorListener errorListener) {
getNotifications(new HashMap<String, String>(), listener, errorListener);
}
/**
* Update the seen timestamp.
* <p/>
* https://developer.wordpress.com/docs/api/1/post/notifications/seen
*/
public void markNotificationsSeen(String timestamp, Listener listener, ErrorListener errorListener) {
Map<String, String> params = new HashMap<String, String>();
params.put("time", timestamp);
post("notifications/seen", params, null, listener, errorListener);
}
/**
* Moderate a comment.
* <p/>
* http://developer.wordpress.com/docs/api/1/sites/%24site/comments/%24comment_ID/
*/
public void moderateComment(String siteId, String commentId, String status, Listener listener,
ErrorListener errorListener) {
Map<String, String> params = new HashMap<String, String>();
params.put("status", status);
String path = String.format("sites/%s/comments/%s/", siteId, commentId);
post(path, params, null, listener, errorListener);
}
/**
* Get all a site's themes
*/
public void getThemes(String siteId, int limit, int offset, Listener listener, ErrorListener errorListener) {
String path = String.format("sites/%s/themes?limit=%d&offset=%d", siteId, limit, offset);
get(path, listener, errorListener);
}
/**
* Set a site's theme
*/
public void setTheme(String siteId, String themeId, Listener listener, ErrorListener errorListener) {
Map<String, String> params = new HashMap<String, String>();
params.put("theme", themeId);
String path = String.format("sites/%s/themes/mine", siteId);
post(path, params, null, listener, errorListener);
}
/**
* Get a site's current theme
*/
public void getCurrentTheme(String siteId, Listener listener, ErrorListener errorListener) {
String path = String.format("sites/%s/themes/mine", siteId);
get(path, listener, errorListener);
}
/**
* Get a site's stats for clicks
*/
public void getStatsClicks(String siteId, String date, Listener listener, ErrorListener errorListener) {
String path = String.format("sites/%s/stats/clicks?date=%s", siteId, date);
get(path, listener, errorListener);
}
/**
* Get a site's stats for geoviews (views by country)
*/
public void getStatsGeoviews(String siteId, String date, Listener listener, ErrorListener errorListener) {
String path = String.format("sites/%s/stats/country-views?date=%s", siteId, date);
get(path, listener, errorListener);
}
/**
* Get a site's stats for most commented posts
*/
public void getStatsMostCommented(String siteId, Listener listener, ErrorListener errorListener) {
String path = "stats/most_commented";
Map<String, String> params = new HashMap<String, String>();
params.put("blog", siteId);
getXL(path, params, listener, errorListener);
}
/**
* Get a site's stats for top commenters
*/
public void getStatsTopCommenters(String siteId, Listener listener, ErrorListener errorListener) {
String path = "stats/top_commenters";
Map<String, String> params = new HashMap<String, String>();
params.put("blog", siteId);
getXL(path, params, listener, errorListener);
}
/**
* Get a site's stats for referrers
*/
public void getStatsReferrers(String siteId, String date, Listener listener, ErrorListener errorListener) {
String path = String.format("sites/%s/stats/referrers?date=%s", siteId, date);
get(path, listener, errorListener);
}
/**
* Get a site's stats for search engine terms
*/
public void getStatsSearchEngineTerms(String siteId, String date, Listener listener, ErrorListener errorListener) {
String path = String.format("sites/%s/stats/search-terms?date=%s", siteId, date);
get(path, listener, errorListener);
}
/**
* Get a site's stats for tags and categories
*/
public void getStatsTagsAndCategories(String siteId, Listener listener, ErrorListener errorListener) {
String path = "stats/tags_and_categories";
Map<String, String> params = new HashMap<String, String>();
params.put("blog", siteId);
getXL(path, params, listener, errorListener);
}
/**
* Get a site's stats for top authors
*/
public void getStatsTopAuthors(String siteId, Listener listener, ErrorListener errorListener) {
String path = "stats/top_authors";
Map<String, String> params = new HashMap<String, String>();
params.put("blog", siteId);
getXL(path, params, listener, errorListener);
}
/**
* Get a site's stats for top posts and pages
*/
public void getStatsTopPosts(String siteId, String date, Listener listener, ErrorListener errorListener) {
String path = String.format("sites/%s/stats/top-posts?date=%s", siteId, date);
get(path, listener, errorListener);
}
/**
* Get a site's stats for video plays
*/
public void getStatsVideoPlays(String siteId, Listener listener, ErrorListener errorListener) {
String path = "stats/video_plays";
Map<String, String> params = new HashMap<String, String>();
params.put("blog", siteId);
getXL(path, params, listener, errorListener);
}
/**
* Get a site's stats summary
*/
public void getStatsSummary(String siteId, Listener listener, ErrorListener errorListener) {
String path = String.format("sites/%s/stats", siteId);
get(path, listener, errorListener);
}
/**
* Get a site's stats summary for videos
*/
public void getStatsVideoSummary(String siteId, Listener listener, ErrorListener errorListener) {
String path = "stats/video_summary";
Map<String, String> params = new HashMap<String, String>();
params.put("blog", siteId);
getXL(path, params, listener, errorListener);
}
/**
* Get a site's views and visitors stats for days, weeks, and months
* Use -1 to get a default value for quantity
* Use empty string for unit to get default value
*/
/*
public void getStatsBarChartData(String siteId, StatsBarChartUnit statsBarChartUnit, int quantity,
Listener listener, ErrorListener errorListener) {
String path = String.format("sites/%s/stats/visits", siteId);
String unit = statsBarChartUnit.name().toLowerCase(Locale.ENGLISH);
path += String.format("?unit=%s", unit);
if (quantity > 0) {
path += String.format("&quantity=%d", quantity);
}
get(path, listener, errorListener);
}
*/
/**
* This method is for simulating stats APIs using the XL Studio API simulator. It should be removed once the other APIs are implemented.
*/
public void getXL(String path, Map<String, String> params, final Listener listener,
final ErrorListener errorListener) {
path = "https://simulator.xlstudio.com/apis/32/" + path;
final String url_path = path;
new AsyncTask<Void, Void, JSONObject>() {
@Override
protected JSONObject doInBackground(Void... params) {
URL url;
HttpURLConnection conn;
BufferedReader rd;
String line;
String result = "";
try {
url = new URL(url_path);
conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("GET");
conn.addRequestProperty("X-SIMULATOR-ACCESS-KEY", "bc88864498a705657486edb636196e31");
rd = new BufferedReader(new InputStreamReader(conn.getInputStream()));
while ((line = rd.readLine()) != null) {
result += line;
}
rd.close();
return new JSONObject(result);
} catch (JSONException e) {
AppLog.e(AppLog.T.UTILS, e);
} catch (Exception e) {
AppLog.e(AppLog.T.UTILS, e);
}
return null;
}
protected void onPostExecute(JSONObject result) {
if (result != null) {
listener.onResponse(result);
} else {
errorListener.onErrorResponse(new VolleyError("JSONObject null"));
}
}
}.execute();
}
/**
* Make GET request
*/
public void get(String path, Listener listener, ErrorListener errorListener) {
get(path, null, null, listener, errorListener);
}
/**
* Make GET request with params
*/
public void get(String path, Map<String, String> params, RetryPolicy retryPolicy, Listener listener,
ErrorListener errorListener) {
// turn params into querystring
RestRequest request = mRestClient.makeRequest(Method.GET, RestClient.getAbsoluteURL(path, params), null,
listener, errorListener);
if (retryPolicy == null) {
retryPolicy = new DefaultRetryPolicy(REST_TIMEOUT_MS, REST_MAX_RETRIES_GET, REST_BACKOFF_MULT);
}
request.setRetryPolicy(retryPolicy);
AuthenticatorRequest authCheck = new AuthenticatorRequest(request, errorListener, mRestClient, mAuthenticator);
authCheck.send();
}
/**
* Make POST request
*/
public void post(String path, Listener listener, ErrorListener errorListener) {
post(path, null, null, listener, errorListener);
}
/**
* Make POST request with params
*/
public void post(final String path, Map<String, String> params, RetryPolicy retryPolicy, Listener listener,
ErrorListener errorListener) {
final RestRequest request = mRestClient.makeRequest(Method.POST, RestClient.getAbsoluteURL(path), params,
listener, errorListener);
if (retryPolicy == null) {
retryPolicy = new DefaultRetryPolicy(REST_TIMEOUT_MS, REST_MAX_RETRIES_POST,
REST_BACKOFF_MULT); //Do not retry on failure
}
request.setRetryPolicy(retryPolicy);
AuthenticatorRequest authCheck = new AuthenticatorRequest(request, errorListener, mRestClient, mAuthenticator);
authCheck.send();
}
}