From f402dd92b57f2307d7bb06380a0901e2342252ee Mon Sep 17 00:00:00 2001 From: seven332 Date: Wed, 2 Mar 2016 14:46:05 +0800 Subject: [PATCH] Improve EhEngine --- .../com/hippo/ehviewer/client/EhClient.java | 142 ++++------- .../com/hippo/ehviewer/client/EhEngine.java | 235 ++++++++---------- .../client/parser/GalleryApiParser.java | 68 +++++ 3 files changed, 214 insertions(+), 231 deletions(-) create mode 100644 app/src/main/java/com/hippo/ehviewer/client/parser/GalleryApiParser.java diff --git a/app/src/main/java/com/hippo/ehviewer/client/EhClient.java b/app/src/main/java/com/hippo/ehviewer/client/EhClient.java index 8f7159ab6..31b826f1a 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/EhClient.java +++ b/app/src/main/java/com/hippo/ehviewer/client/EhClient.java @@ -20,15 +20,19 @@ import android.content.Context; import android.os.AsyncTask; import com.hippo.ehviewer.EhApplication; +import com.hippo.ehviewer.client.data.GalleryInfo; import com.hippo.ehviewer.client.exception.CancelledException; import com.hippo.yorozuya.PriorityThreadFactory; import com.hippo.yorozuya.SimpleHandler; +import java.util.List; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicReference; import okhttp3.Call; import okhttp3.OkHttpClient; @@ -39,11 +43,12 @@ public class EhClient { public static final int METHOD_SIGN_IN = 0; public static final int METHOD_GET_GALLERY_LIST = 1; - public static final int METHOD_GET_GALLERY_DETAIL = 2; - public static final int METHOD_GET_LARGE_PREVIEW_SET = 3; - public static final int METHOD_GET_RATE_GALLERY = 4; - public static final int METHOD_GET_COMMENT_GALLERY = 5; - public static final int METHOD_GET_GALLERY_TOKEN = 6; + public static final int METHOD_GET_FILL_GALLERY_LIST_BY_API = 2; + public static final int METHOD_GET_GALLERY_DETAIL = 3; + public static final int METHOD_GET_LARGE_PREVIEW_SET = 4; + public static final int METHOD_GET_RATE_GALLERY = 5; + public static final int METHOD_GET_COMMENT_GALLERY = 6; + public static final int METHOD_GET_GALLERY_TOKEN = 7; private final ThreadPoolExecutor mRequestThreadPool; private final OkHttpClient mOkHttpClient; @@ -70,12 +75,12 @@ public class EhClient { public class Task extends AsyncTask { - private int mMethod; + private final int mMethod; private Callback mCallback; private EhConfig mEhConfig; - private Call mCall; - private boolean mStop; + private final AtomicReference mCall = new AtomicReference<>(); + private final AtomicBoolean mStop = new AtomicBoolean(); public Task(int method, Callback callback, EhConfig ehConfig) { mMethod = method; @@ -83,11 +88,26 @@ public class EhClient { mEhConfig = ehConfig; } + // Called in Job thread + public void setCall(Call call) throws CancelledException { + if (mStop.get()) { + // Stopped Job thread + throw new CancelledException(); + } else { + mCall.lazySet(call); + } + } + + public EhConfig getEhConfig() { + return mEhConfig; + } + public void stop() { - if (!mStop) { - mStop = true; + if (!mStop.get()) { + mStop.lazySet(true); if (mCallback != null) { + // TODO Avoid new runnable final Callback finalCallback = mCallback; SimpleHandler.getInstance().post(new Runnable() { @Override @@ -101,108 +121,41 @@ public class EhClient { if (status == Status.PENDING) { cancel(false); } else if (status == Status.RUNNING) { - if (mCall != null) { - mCall.cancel(); + // It is running, cancel call if it is created + Call call = mCall.get(); + if (call != null) { + call.cancel(); } } // Clear - mCall = null; mCallback = null; - } - } - - private Object signIn(EhConfig ehConfig, Object... params) throws Exception { - Call call = EhEngine.prepareSignIn(mOkHttpClient, ehConfig, (String) params[0], (String) params[1]); - if (!mStop) { - mCall = call; - return EhEngine.doSignIn(call); - } else { - throw new CancelledException(); - } - } - - private Object getGalleryList(EhConfig ehConfig, Object... params) throws Exception { - Call call = EhEngine.prepareGetGalleryList(mOkHttpClient, ehConfig, (String) params[0]); - if (!mStop) { - mCall = call; - return EhEngine.doGetGalleryList(call, (Boolean) params[1], mOkHttpClient); - } else { - throw new CancelledException(); - } - } - - private Object getGalleryDetail(EhConfig ehConfig, Object... params) throws Exception { - Call call = EhEngine.prepareGetGalleryDetail(mOkHttpClient, ehConfig, (String) params[0]); - if (!mStop) { - mCall = call; - return EhEngine.doGetGalleryDetail(call); - } else { - throw new CancelledException(); - } - } - - private Object getLargePreviewSet(EhConfig ehConfig, Object... params) throws Exception { - Call call = EhEngine.prepareGetLargePreviewSet(mOkHttpClient, ehConfig, (String) params[0]); - if (!mStop) { - mCall = call; - return EhEngine.doGetLargePreviewSet(call); - } else { - throw new CancelledException(); - } - } - - private Object rateGallery(EhConfig ehConfig, Object... params) throws Exception { - Call call = EhEngine.prepareRateGallery(mOkHttpClient, ehConfig, - (Integer) params[0], (String) params[1], (Float) params[2]); - if (!mStop) { - mCall = call; - return EhEngine.doRateGallery(call); - } else { - throw new CancelledException(); - } - } - - private Object commentGallery(EhConfig ehConfig, Object... params) throws Exception { - Call call = EhEngine.prepareCommentGallery(mOkHttpClient, ehConfig, - (String) params[0], (String) params[1]); - if (!mStop) { - mCall = call; - return EhEngine.doCommentGallery(call); - } else { - throw new CancelledException(); - } - } - - private Object getGalleryToken(EhConfig ehConfig, Object... params) throws Exception { - Call call = EhEngine.prepareGetGalleryToken(mOkHttpClient, ehConfig, - (Integer) params[0], (String) params[1], (Integer) params[2]); - if (!mStop) { - mCall = call; - return EhEngine.doGetGalleryToken(call); - } else { - throw new CancelledException(); + mEhConfig = null; + mCall.lazySet(null); } } @Override + @SuppressWarnings("unchecked") protected Object doInBackground(Object... params) { try { switch (mMethod) { case METHOD_SIGN_IN: - return signIn(mEhConfig, params); + return EhEngine.signIn(this, mOkHttpClient, (String) params[0], (String) params[1]); case METHOD_GET_GALLERY_LIST: - return getGalleryList(mEhConfig, params); + return EhEngine.getGalleryList(this, mOkHttpClient, (String) params[0], (Boolean) params[1]); + case METHOD_GET_FILL_GALLERY_LIST_BY_API: + return EhEngine.fillGalleryListByApi(this, mOkHttpClient, (List) params[0]); case METHOD_GET_GALLERY_DETAIL: - return getGalleryDetail(mEhConfig, params); + return EhEngine.getGalleryDetail(this, mOkHttpClient, (String) params[0]); case METHOD_GET_LARGE_PREVIEW_SET: - return getLargePreviewSet(mEhConfig, params); + return EhEngine.getLargePreviewSet(this, mOkHttpClient, (String) params[0]); case METHOD_GET_RATE_GALLERY: - return rateGallery(mEhConfig, params); + return EhEngine.rateGallery(this, mOkHttpClient, (Integer) params[0], (String) params[1], (Float) params[2]); case METHOD_GET_COMMENT_GALLERY: - return commentGallery(mEhConfig, params); + return EhEngine.commentGallery(this, mOkHttpClient, (String) params[0], (String) params[1]); case METHOD_GET_GALLERY_TOKEN: - return getGalleryToken(mEhConfig, params); + return EhEngine.getGalleryToken(this, mOkHttpClient, (Integer) params[0], (String) params[1], (Integer) params[2]); default: return new IllegalStateException("Can't detect method " + mMethod); } @@ -228,8 +181,9 @@ public class EhClient { } // Clear - mCall = null; mCallback = null; + mEhConfig = null; + mCall.lazySet(null); } } diff --git a/app/src/main/java/com/hippo/ehviewer/client/EhEngine.java b/app/src/main/java/com/hippo/ehviewer/client/EhEngine.java index 5bedf388d..e72d71fd2 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/EhEngine.java +++ b/app/src/main/java/com/hippo/ehviewer/client/EhEngine.java @@ -27,19 +27,17 @@ import com.hippo.ehviewer.client.data.LargePreviewSet; import com.hippo.ehviewer.client.exception.CancelledException; import com.hippo.ehviewer.client.exception.EhException; import com.hippo.ehviewer.client.exception.ParseException; +import com.hippo.ehviewer.client.parser.GalleryApiParser; import com.hippo.ehviewer.client.parser.GalleryDetailParser; import com.hippo.ehviewer.client.parser.GalleryListParser; import com.hippo.ehviewer.client.parser.GalleryTokenApiParser; -import com.hippo.ehviewer.client.parser.ParserUtils; import com.hippo.ehviewer.client.parser.RateGalleryParser; import com.hippo.ehviewer.client.parser.SignInParser; import com.hippo.network.StatusCodeException; import org.json.JSONArray; -import org.json.JSONException; import org.json.JSONObject; -import java.net.MalformedURLException; import java.util.ArrayList; import java.util.List; @@ -87,24 +85,24 @@ public class EhEngine { } } - public static Call prepareSignIn(OkHttpClient okHttpClient, - EhConfig ehConfig, String username, String password) throws MalformedURLException { + public static String signIn(EhClient.Task task, OkHttpClient okHttpClient, + String username, String password) throws Exception { FormBody.Builder builder = new FormBody.Builder() .add("UserName", username) .add("PassWord", password) .add("submit", "Log me in") .add("CookieDate", "1") .add("temporary_https", "off"); - String url = EhUrl.API_SIGN_IN; Log.d(TAG, url); - Request request = new EhRequestBuilder(url, ehConfig) + Request request = new EhRequestBuilder(url, task.getEhConfig()) .post(builder.build()) .build(); - return okHttpClient.newCall(request); - } + Call call = okHttpClient.newCall(request); + + // Put call + task.setCall(call); - public static String doSignIn(Call call) throws Exception { String body = null; Headers headers = null; int code = -1; @@ -120,53 +118,60 @@ public class EhEngine { } } - public static Call prepareGetGalleryList(OkHttpClient okHttpClient, - EhConfig ehConfig, String url) throws MalformedURLException { + public static GalleryListParser.Result getGalleryList(EhClient.Task task, OkHttpClient okHttpClient, + String url, boolean callApi) throws Exception { Log.d(TAG, url); - Request request = new EhRequestBuilder(url, ehConfig).build(); - return okHttpClient.newCall(request); + Request request = new EhRequestBuilder(url, task.getEhConfig()).build(); + Call call = okHttpClient.newCall(request); + + // Put call + task.setCall(call); + + String body = null; + Headers headers = null; + GalleryListParser.Result result; + int code = -1; + try { + Response response = call.execute(); + code = response.code(); + headers = response.headers(); + body = response.body().string(); + result = GalleryListParser.parse(body); + } catch (Exception e) { + throwException(call, code, headers, body, e); + throw e; + } + + if (callApi && result.galleryInfos.size() > 0) { + fillGalleryListByApi(task, okHttpClient, result.galleryInfos); + } + + return result; } - private static GalleryInfo getGalleryInfoByGid(List galleryInfos, int gid) { - for (int i = 0, size = galleryInfos.size(); i < size; i++) { - GalleryInfo gi = galleryInfos.get(i); - if (gi.gid == gid) { - return gi; + // At least, GalleryInfo contain valid gid and token + public static Void fillGalleryListByApi(EhClient.Task task, OkHttpClient okHttpClient, + List galleryInfoList) throws Exception { + // We can only request 25 items one time at most + final int MAX_REQUEST_SIZE = 25; + List requestItems = new ArrayList<>(MAX_REQUEST_SIZE); + for (int i = 0, size = galleryInfoList.size(); i < size; i++) { + requestItems.add(galleryInfoList.get(i)); + if (requestItems.size() == MAX_REQUEST_SIZE || i == size - 1) { + doFillGalleryListByApi(task, okHttpClient, requestItems); + requestItems.clear(); } } return null; } - private static void parseGalleryApi(String body, List galleryInfos) throws JSONException { - JSONObject jo = new JSONObject(body); - JSONArray ja = jo.getJSONArray("gmetadata"); - - for (int i = 0, length = ja.length(); i < length; i++) { - JSONObject g = ja.getJSONObject(i); - int gid = g.getInt("gid"); - GalleryInfo gi = getGalleryInfoByGid(galleryInfos, gid); - if (gi == null) { - continue; - } - gi.titleJpn = ParserUtils.trim(g.getString("title_jpn")); - // tags - JSONArray tagJa = g.getJSONArray("tags"); - int tagLength = tagJa.length(); - String[] tags = new String[tagLength]; - for (int j = 0; j < tagLength; j++) { - tags[j] = tagJa.getString(j); - } - gi.simpleTags = tags; - } - } - - private static void doRequestGalleryApi(List galleryInfos, OkHttpClient okHttpClient) - throws Exception { + private static void doFillGalleryListByApi(EhClient.Task task, OkHttpClient okHttpClient, + List galleryInfoList) throws Exception { JSONObject json = new JSONObject(); json.put("method", "gdata"); JSONArray ja = new JSONArray(); - for (int i = 0, size = galleryInfos.size(); i < size; i++) { - GalleryInfo gi = galleryInfos.get(i); + for (int i = 0, size = galleryInfoList.size(); i < size; i++) { + GalleryInfo gi = galleryInfoList.get(i); JSONArray g = new JSONArray(); g.put(gi.gid); g.put(gi.token); @@ -174,15 +179,16 @@ public class EhEngine { } json.put("gidlist", ja); json.put("namespace", 1); - String url = EhUrl.API_EX; Log.d(TAG, url); - Request request = new EhRequestBuilder(url) .post(RequestBody.create(JSON, json.toString())) .build(); Call call = okHttpClient.newCall(request); + // Put call + task.setCall(call); + String body = null; Headers headers = null; int code = -1; @@ -191,55 +197,22 @@ public class EhEngine { code = response.code(); headers = response.headers(); body = response.body().string(); - parseGalleryApi(body, galleryInfos); + GalleryApiParser.parse(body, galleryInfoList); } catch (Exception e) { throwException(call, code, headers, body, e); throw e; } } - private static void requestGalleryApi(List galleryInfos, - OkHttpClient okHttpClient) throws Exception { - final int MAX_REQUEST_SIZE = 25; - List requestItems = new ArrayList<>(MAX_REQUEST_SIZE); - for (int i = 0, size = galleryInfos.size(); i < size; i++) { - requestItems.add(galleryInfos.get(i)); - if (requestItems.size() == MAX_REQUEST_SIZE || i == size - 1) { - doRequestGalleryApi(requestItems, okHttpClient); - requestItems.clear(); - } - } - } - - public static GalleryListParser.Result doGetGalleryList(Call call, boolean callApi, - OkHttpClient okHttpClient) throws Exception { - String body = null; - Headers headers = null; - int code = -1; - try { - Response response = call.execute(); - code = response.code(); - headers = response.headers(); - body = response.body().string(); - GalleryListParser.Result result = GalleryListParser.parse(body); - if (callApi && result.galleryInfos.size() > 0) { - requestGalleryApi(result.galleryInfos, okHttpClient); - } - return result; - } catch (Exception e) { - throwException(call, code, headers, body, e); - throw e; - } - } - - public static Call prepareGetGalleryDetail(OkHttpClient okHttpClient, - EhConfig ehConfig, String url) throws MalformedURLException { + public static GalleryDetail getGalleryDetail(EhClient.Task task, OkHttpClient okHttpClient, + String url) throws Exception { Log.d(TAG, url); - Request request = new EhRequestBuilder(url, ehConfig).build(); - return okHttpClient.newCall(request); - } + Request request = new EhRequestBuilder(url, task.getEhConfig()).build(); + Call call = okHttpClient.newCall(request); + + // Put call + task.setCall(call); - public static GalleryDetail doGetGalleryDetail(Call call) throws Exception { String body = null; Headers headers = null; int code = -1; @@ -255,14 +228,16 @@ public class EhEngine { } } - public static Call prepareGetLargePreviewSet(OkHttpClient okHttpClient, - EhConfig ehConfig, String url) throws MalformedURLException { - Log.d(TAG, url); - Request request = new EhRequestBuilder(url, ehConfig).build(); - return okHttpClient.newCall(request); - } - public static Pair doGetLargePreviewSet(Call call) throws Exception { + public static Pair getLargePreviewSet( + EhClient.Task task, OkHttpClient okHttpClient, String url) throws Exception { + Log.d(TAG, url); + Request request = new EhRequestBuilder(url, task.getEhConfig()).build(); + Call call = okHttpClient.newCall(request); + + // Put call + task.setCall(call); + String body = null; Headers headers = null; int code = -1; @@ -271,16 +246,16 @@ public class EhEngine { code = response.code(); headers = response.headers(); body = response.body().string(); - return Pair.create(GalleryDetailParser.parseLargePreview(body),GalleryDetailParser.parsePreviewPages(body)); + return Pair.create(GalleryDetailParser.parseLargePreview(body), + GalleryDetailParser.parsePreviewPages(body)); } catch (Exception e) { throwException(call, code, headers, body, e); throw e; } } - // rating 0.0 - 0.5 - public static Call prepareRateGallery(OkHttpClient okHttpClient, - EhConfig ehConfig, int gid, String token, float rating) throws JSONException, MalformedURLException { + public static RateGalleryParser.Result rateGallery(EhClient.Task task, + OkHttpClient okHttpClient, int gid, String token, float rating) throws Exception { final JSONObject json = new JSONObject(); json.put("method", "rategallery"); json.put("apiuid", APIUID); @@ -288,19 +263,17 @@ public class EhEngine { json.put("gid", gid); json.put("token", token); json.put("rating", (int) Math.ceil(rating * 2)); - - final RequestBody body = RequestBody.create(JSON, json.toString()); - + final RequestBody requestBody = RequestBody.create(JSON, json.toString()); String url = EhUrl.API_EX; Log.d(TAG, url); - - Request request = new EhRequestBuilder(url, ehConfig) - .post(body) + Request request = new EhRequestBuilder(url, task.getEhConfig()) + .post(requestBody) .build(); - return okHttpClient.newCall(request); - } + Call call = okHttpClient.newCall(request); + + // Put call + task.setCall(call); - public static RateGalleryParser.Result doRateGallery(Call call) throws Exception { String body = null; Headers headers = null; int code = -1; @@ -316,20 +289,20 @@ public class EhEngine { } } - public static Call prepareCommentGallery(OkHttpClient okHttpClient, - EhConfig ehConfig, String url, String comment) throws MalformedURLException { + public static GalleryComment[] commentGallery(EhClient.Task task, + OkHttpClient okHttpClient, String url, String comment) throws Exception { FormBody.Builder builder = new FormBody.Builder() .add("commenttext", comment) .add("postcomment", "Post New"); - Log.d(TAG, url); - Request request = new EhRequestBuilder(url, ehConfig) + Request request = new EhRequestBuilder(url, task.getEhConfig()) .post(builder.build()) .build(); - return okHttpClient.newCall(request); - } + Call call = okHttpClient.newCall(request); + + // Put call + task.setCall(call); - public static GalleryComment[] doCommentGallery(Call call) throws Exception { String body = null; Headers headers = null; int code = -1; @@ -345,33 +318,23 @@ public class EhEngine { } } - /** - * - * { - * "method": "gtoken", - * "pagelist": [ - * [902127,"5a4ee2caff",3] - * ] - * } - */ - public static Call prepareGetGalleryToken(OkHttpClient okHttpClient, - EhConfig ehConfig, int gid, String gtoken, int page) throws JSONException, MalformedURLException { + public static String getGalleryToken(EhClient.Task task, OkHttpClient okHttpClient, + int gid, String gtoken, int page) throws Exception { JSONObject json = new JSONObject() .put("method", "gtoken") .put("pagelist", new JSONArray().put( new JSONArray().put(gid).put(gtoken).put(page + 1))); - final RequestBody body = RequestBody.create(JSON, json.toString()); - + final RequestBody requestBody = RequestBody.create(JSON, json.toString()); String url = EhUrl.API_EX; Log.d(TAG, url); - - Request request = new EhRequestBuilder(url, ehConfig) - .post(body) + Request request = new EhRequestBuilder(url, task.getEhConfig()) + .post(requestBody) .build(); - return okHttpClient.newCall(request); - } + Call call = okHttpClient.newCall(request); + + // Put call + task.setCall(call); - public static String doGetGalleryToken(Call call) throws Exception { String body = null; Headers headers = null; int code = -1; @@ -386,6 +349,4 @@ public class EhEngine { throw e; } } - - // TODO Add get gallery api info } diff --git a/app/src/main/java/com/hippo/ehviewer/client/parser/GalleryApiParser.java b/app/src/main/java/com/hippo/ehviewer/client/parser/GalleryApiParser.java new file mode 100644 index 000000000..67fbe8984 --- /dev/null +++ b/app/src/main/java/com/hippo/ehviewer/client/parser/GalleryApiParser.java @@ -0,0 +1,68 @@ +/* + * Copyright 2016 Hippo Seven + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hippo.ehviewer.client.parser; + +import com.hippo.ehviewer.client.EhUtils; +import com.hippo.ehviewer.client.data.GalleryInfo; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.List; + +public class GalleryApiParser { + + public static void parse(String body, List galleryInfoList) throws JSONException { + JSONObject jo = new JSONObject(body); + JSONArray ja = jo.getJSONArray("gmetadata"); + + for (int i = 0, length = ja.length(); i < length; i++) { + JSONObject g = ja.getJSONObject(i); + int gid = g.getInt("gid"); + GalleryInfo gi = getGalleryInfoByGid(galleryInfoList, gid); + if (gi == null) { + continue; + } + gi.title = g.getString("title"); + gi.titleJpn = g.getString("title_jpn"); + gi.category = EhUtils.getCategory(g.getString("category")); + gi.thumb = g.getString("thumb"); + gi.uploader = g.getString("uploader"); + gi.posted = g.getString("posted"); // TODO long to date + gi.rating = Float.parseFloat(g.getString("rating")); + // tags + JSONArray tagJa = g.getJSONArray("tags"); + int tagLength = tagJa.length(); + String[] tags = new String[tagLength]; + for (int j = 0; j < tagLength; j++) { + tags[j] = tagJa.getString(j); + } + gi.simpleTags = tags; + } + } + + private static GalleryInfo getGalleryInfoByGid(List galleryInfoList, int gid) { + for (int i = 0, size = galleryInfoList.size(); i < size; i++) { + GalleryInfo gi = galleryInfoList.get(i); + if (gi.gid == gid) { + return gi; + } + } + return null; + } +}