From b7f8cda3045185ff279643e2326a228fa2df3d4a Mon Sep 17 00:00:00 2001 From: seven332 Date: Mon, 18 May 2015 19:53:59 +0800 Subject: [PATCH] Use OkHttpClient --- app/app.iml | 10 +- app/build.gradle | 2 + .../com/hippo/ehviewer/EhApplication.java | 8 +- .../com/hippo/ehviewer/client/EhClient.java | 132 ++- .../hippo/ehviewer/client/SignInParser.java | 45 + .../hippo/ehviewer/network/EhHttpHelper.java | 62 -- .../ehviewer/network/EhOkHttpClient.java | 192 ++++ .../hippo/ehviewer/ui/ContentActivity.java | 5 +- .../hippo/ehviewer/ui/scene/SignInScene.java | 36 +- .../java/com/hippo/ehviewer/util/Config.java | 38 +- .../ehviewer/widget/DrawerLeftPanel.java | 16 +- .../main/java/com/hippo/network/Cookie.java | 85 ++ .../java/com/hippo/network/HttpHelper.java | 951 ------------------ .../hippo/network/RedirectionException.java | 23 - .../hippo/network/StopRequestException.java | 23 - .../hippo/network/UncompletedException.java | 27 - .../java/com/hippo/util/ExceptionUtils.java | 7 +- app/src/main/java/com/hippo/util/Utils.java | 10 + 18 files changed, 551 insertions(+), 1121 deletions(-) create mode 100644 app/src/main/java/com/hippo/ehviewer/client/SignInParser.java delete mode 100644 app/src/main/java/com/hippo/ehviewer/network/EhHttpHelper.java create mode 100644 app/src/main/java/com/hippo/ehviewer/network/EhOkHttpClient.java create mode 100644 app/src/main/java/com/hippo/network/Cookie.java delete mode 100644 app/src/main/java/com/hippo/network/HttpHelper.java delete mode 100644 app/src/main/java/com/hippo/network/RedirectionException.java delete mode 100644 app/src/main/java/com/hippo/network/StopRequestException.java delete mode 100644 app/src/main/java/com/hippo/network/UncompletedException.java diff --git a/app/app.iml b/app/app.iml index c6f071f28..dd73d6260 100644 --- a/app/app.iml +++ b/app/app.iml @@ -74,6 +74,7 @@ + @@ -92,15 +93,18 @@ - + + + - + - + + \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index 662e50019..d8104ea48 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -28,5 +28,7 @@ dependencies { compile 'com.android.support:appcompat-v7:22.1.1' compile 'com.github.japgolly.android:svg-android:2.0.6' compile 'com.facebook.fresco:fresco:0.5.0' + compile 'com.facebook.fresco:imagepipeline-okhttp:0.5.0' + compile 'com.squareup.okhttp:okhttp:2.4.0-RC1' compile fileTree(dir: 'libs', include: ['*.jar']) } diff --git a/app/src/main/java/com/hippo/ehviewer/EhApplication.java b/app/src/main/java/com/hippo/ehviewer/EhApplication.java index 003b38dc8..81c03e171 100644 --- a/app/src/main/java/com/hippo/ehviewer/EhApplication.java +++ b/app/src/main/java/com/hippo/ehviewer/EhApplication.java @@ -18,7 +18,10 @@ package com.hippo.ehviewer; import android.content.Context; import com.facebook.drawee.backends.pipeline.Fresco; +import com.facebook.imagepipeline.backends.okhttp.OkHttpImagePipelineConfigFactory; +import com.facebook.imagepipeline.core.ImagePipelineConfig; import com.hippo.content.VectorContext; +import com.hippo.ehviewer.network.EhOkHttpClient; import com.hippo.ehviewer.util.Config; import com.hippo.scene.SceneApplication; import com.hippo.util.Log; @@ -29,7 +32,10 @@ public class EhApplication extends SceneApplication { public void onCreate() { super.onCreate(); - Fresco.initialize(this); + ImagePipelineConfig config = OkHttpImagePipelineConfigFactory + .newBuilder(this, EhOkHttpClient.getInstance()) + .build(); + Fresco.initialize(this, config); Config.initialize(this); } 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 cd65830e3..14a257809 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/EhClient.java +++ b/app/src/main/java/com/hippo/ehviewer/client/EhClient.java @@ -19,9 +19,14 @@ import android.os.AsyncTask; import android.os.Process; import com.hippo.ehviewer.data.GalleryInfo; -import com.hippo.ehviewer.network.EhHttpHelper; +import com.hippo.ehviewer.network.EhOkHttpClient; import com.hippo.network.ResponseCodeException; import com.hippo.util.PriorityThreadFactory; +import com.squareup.okhttp.FormEncodingBuilder; +import com.squareup.okhttp.MediaType; +import com.squareup.okhttp.Request; +import com.squareup.okhttp.RequestBody; +import com.squareup.okhttp.Response; import org.json.JSONObject; @@ -35,9 +40,10 @@ import java.util.concurrent.TimeUnit; @SuppressWarnings("unchecked") public final class EhClient { - @SuppressWarnings("unused") private static final String TAG = EhClient.class.getSimpleName(); + public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8"); + public static final int SOURCE_G = 0x0; public static final int SOURCE_EX = 0x1; public static final int SOURCE_LOFI = 0x2; @@ -47,7 +53,7 @@ public final class EhClient { public static final long APIUID = 1363542; public static final String APIKEY = "f4b5407ab1727b9d08d7"; - private static final String LOGIN_URL = + private static final String SIGN_IN_URL = "http://forums.e-hentai.org/index.php?act=Login&CODE=01"; private static final String FORUMS_URL = "http://forums.e-hentai.org/index.php"; @@ -61,8 +67,14 @@ public final class EhClient { public static final String API_EHVIEWER = "http://www.ehviewer.com/API"; + private static final String SAD_PANDA_DISPOSITION = "inline; filename=\"sadpanda.jpg\""; + private static final String SAD_PANDA_TYPE = "image/gif"; + private static final String SAD_PANDA_LENGTH = "9615"; + private final ThreadPoolExecutor mRequestThreadPool; + private final EhOkHttpClient mHttpClient; + private static final EhClient sInstance; static { @@ -80,6 +92,8 @@ public final class EhClient { Process.THREAD_PRIORITY_BACKGROUND); mRequestThreadPool = new ThreadPoolExecutor(poolSize, poolSize, 1L, TimeUnit.SECONDS, requestWorkQueue, threadFactory); + + mHttpClient = EhOkHttpClient.getInstance(); } public static String getReadableHost(int source) { @@ -106,7 +120,7 @@ public final class EhClient { } } - public interface EhClientListener { + public interface SimpleListener { void onFailure(Exception e); } @@ -134,10 +148,10 @@ public final class EhClient { private abstract class SimpleBgJobHelper implements BgJobHelper { - private EhClientListener mListener; + private SimpleListener mListener; private Exception mException; - public SimpleBgJobHelper(EhClientListener listener) { + public SimpleBgJobHelper(SimpleListener listener) { mListener = listener; } @@ -166,26 +180,37 @@ public final class EhClient { public abstract void doSuccessCallback(); } - private void checkRequest(EhHttpHelper ehh) throws ResponseCodeException { - final int responseCode = ehh.getResponseCode(); + private void checkResponse(Response response) throws Exception { + final int responseCode = response.code(); if (responseCode >= 400) { throw new ResponseCodeException(responseCode); } + + String disposition = response.header("Content-Disposition", null); + String type = response.header("Content-Type", null); + String length = response.header("Content-Length", null); + + if (SAD_PANDA_DISPOSITION.equals(disposition) && SAD_PANDA_TYPE.equals(type) && + SAD_PANDA_LENGTH.equals(length)) { + throw new EhException("Sad Panda"); + } } - private Object[] doGetGalleryList(int source, String url) throws Exception { - EhHttpHelper ehh = EhHttpHelper.obtain(); - String body = ehh.get(url); - checkRequest(ehh); - EhHttpHelper.recycle(ehh); + private Object[] doGetGalleryList(int source, String url) throws Exception { + Request request = new Request.Builder() + .url(url) + .build(); + Response response = mHttpClient.newCall(request).execute(); + + checkResponse(response); GalleryListParser parser = new GalleryListParser(); - parser.parse(body, source); + parser.parse(response.body().string(), source); return new Object[]{parser.giList, parser.pageNum}; } - public abstract static class OnGetGalleryListListener implements EhClientListener { + public abstract static class OnGetGalleryListListener implements SimpleListener { public abstract void onSuccess(List glList, int pageNum); } @@ -230,26 +255,29 @@ public final class EhClient { doBgJob(new GetGalleryListHelper(source, url, listener)); } + private Object[] doGetPopular() throws Exception { final JSONObject json = new JSONObject(); json.put("method", "popular"); + RequestBody body = RequestBody.create(JSON, json.toString()); - EhHttpHelper ehh = EhHttpHelper.obtain(); - String body = ehh.postJson(API_EHVIEWER, json); + Request request = new Request.Builder() + .url(API_EHVIEWER) + .post(body) + .build(); + Response response = mHttpClient.newCall(request).execute(); - checkRequest(ehh); - EhHttpHelper.recycle(ehh); + checkResponse(response); PopularParser parser = new PopularParser(); - parser.parse(body); + parser.parse(response.body().string()); return new Object[]{parser.galleryInfoList, parser.timeStamp}; } - public abstract static class OnGetPopularListener implements EhClientListener { + public abstract static class OnGetPopularListener implements SimpleListener { public abstract void onSuccess(List giList, long timeStamp); } - private final class GetPopularHelper extends SimpleBgJobHelper { private OnGetPopularListener mListener; @@ -283,4 +311,64 @@ public final class EhClient { public void getPopular(OnGetPopularListener listener) { doBgJob(new GetPopularHelper(listener)); } + + + private String doSignIn(String username, String password) throws Exception { + RequestBody formBody = new FormEncodingBuilder() + .add("UserName", username) + .add("PassWord", password) + .add("submit", "Log me in") + .add("CookieDate", "1") + .add("temporary_https", "off") + .build(); + + Request request = new Request.Builder() + .url(SIGN_IN_URL) + .post(formBody) + .build(); + Response response = mHttpClient.newCall(request).execute(); + + checkResponse(response); + + SignInParser parser = new SignInParser(); + parser.parse(response.body().string()); + return parser.displayname; + } + + public abstract static class OnSignInListener implements SimpleListener { + public abstract void onSuccess(String displayname); + } + + private final class SignInHelper extends SimpleBgJobHelper { + + private String mUsername; + private String mPassword; + private OnSignInListener mListener; + + private String mDisplayname; + + public SignInHelper(String username, String password, OnSignInListener listener) { + super(listener); + mUsername = username; + mPassword = password; + mListener = listener; + } + + @Override + public void doBgJob() throws Exception { + mDisplayname = doSignIn(mUsername, mPassword); + } + + @Override + public void doSuccessCallback() { + mListener.onSuccess(mDisplayname); + } + } + + /** + * Sign in + */ + public void signIn(String username, String password, OnSignInListener listener) { + doBgJob(new SignInHelper(username, password, listener)); + } } diff --git a/app/src/main/java/com/hippo/ehviewer/client/SignInParser.java b/app/src/main/java/com/hippo/ehviewer/client/SignInParser.java new file mode 100644 index 000000000..68979b411 --- /dev/null +++ b/app/src/main/java/com/hippo/ehviewer/client/SignInParser.java @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2015 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 + * 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; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +public class SignInParser { + public String displayname; + + public boolean parse(String body) throws Exception { + Pattern p; + Matcher m; + + p = Pattern.compile("

You are now logged in as: (.+?)
"); + m = p.matcher(body); + if (m.find()) { + displayname = m.group(1); + return true; + } else { + p = Pattern.compile("(?:

The error returned was:

\\s*

(.+?)

)" + + "|(?:(.+?))"); + m = p.matcher(body); + + if (m.find()) { + throw new EhException(m.group(1) == null ? m.group(2) : m.group(1)); + } else { + throw new EhException("Unknown error"); // TODO + } + } + } +} diff --git a/app/src/main/java/com/hippo/ehviewer/network/EhHttpHelper.java b/app/src/main/java/com/hippo/ehviewer/network/EhHttpHelper.java deleted file mode 100644 index 35a2cd19f..000000000 --- a/app/src/main/java/com/hippo/ehviewer/network/EhHttpHelper.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2015 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 - * 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.network; - -import android.support.annotation.NonNull; - -import com.hippo.network.HttpHelper; -import com.hippo.util.Pool; - -import java.net.HttpURLConnection; -import java.net.URL; - -public class EhHttpHelper extends HttpHelper { - - private static final Pool sPool = new Pool<>(10); - - private static String[] EHENTAI_DOMAIN = { - "exhentai.org", - "e-hentai.org" - }; - - public static @NonNull EhHttpHelper obtain() { - EhHttpHelper ehh = sPool.obtain(); - if (ehh == null) { - ehh = new EhHttpHelper(); - } - return ehh; - } - - public static void recycle(@NonNull EhHttpHelper ehh) { - ehh.reset(); - sPool.recycle(ehh); - } - - @Override - protected String getCookie(URL url) { - return super.getCookie(url); - } - - @Override - protected void storeCookie(URL url, String value) { - super.storeCookie(url, value); - } - - @Override - protected void onBeforeConnect(HttpURLConnection conn) { - super.onBeforeConnect(conn); - } -} diff --git a/app/src/main/java/com/hippo/ehviewer/network/EhOkHttpClient.java b/app/src/main/java/com/hippo/ehviewer/network/EhOkHttpClient.java new file mode 100644 index 000000000..c1ec61118 --- /dev/null +++ b/app/src/main/java/com/hippo/ehviewer/network/EhOkHttpClient.java @@ -0,0 +1,192 @@ +/* + * Copyright (C) 2015 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 + * 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.network; + +import android.webkit.CookieManager; + +import com.hippo.ehviewer.util.Config; +import com.hippo.network.Cookie; +import com.hippo.util.MathUtils; +import com.hippo.util.Utils; +import com.squareup.okhttp.Interceptor; +import com.squareup.okhttp.OkHttpClient; +import com.squareup.okhttp.Request; +import com.squareup.okhttp.Response; + +import java.io.IOException; +import java.net.CookieHandler; +import java.net.URI; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +public class EhOkHttpClient extends OkHttpClient { + + public static final String DEFAULT_USER_AGENT = + "Mozilla/5.0 (Windows NT 6.1; WOW64) " + + "AppleWebKit/537.36 (KHTML, like Gecko) " + + "Chrome/39.0.2171.95 Safari/537.36"; + public static final String USER_AGENT = + System.getProperty("http.agent", DEFAULT_USER_AGENT); + + private static String[] EHENTAI_DOMAIN = { + "exhentai.org", + "e-hentai.org" + }; + + private static final String HOST_EX = "exhentai.org"; + private static final String HOST_LOFI = "lofi.e-hentai.org"; + + private static final String KEY_IPD_MEMBER_ID = "ipb_member_id"; + private static final String KEY_IPD_PASS_HASH = "ipb_pass_hash"; + private static final String KEY_IGNEOUS = "igneous"; + private static final String KEY_UCONFIG = "uconfig"; + private static final String KEY_XRES = "xres"; + private static final String KEY_YAY = "yay"; + + private static CookieHandler mCookieHandler = new CookieHandler() { + + private final CookieManager mCookieManager = CookieManager.getInstance(); + + public String getDomain(URI uri) { + String host = uri.getHost(); + int length = host.length(); + int dotCount = 0; + int i = length; + while(i-- != 0) { + char ch = host.charAt(i); + if (ch == '.') { + dotCount++; + } + if (dotCount == 2) { + // Get it + break; + } + } + return host.substring(MathUtils.clamp(i + 1, 0, length)); + } + + @Override + public Map> get(URI uri, Map> requestHeaders) throws IOException { + boolean isSignIn = Config.getSignIn(); + String host = uri.getHost(); + Cookie cookie = new Cookie(); + + if (!isSignIn && HOST_EX.equals(host)) { + cookie.put("yay", "louder"); + } else { + cookie.putRaw(mCookieManager.getCookie(uri.toString())); + + if (isSignIn && Utils.contain(EHENTAI_DOMAIN, getDomain(uri))) { + String ipdMemberId = Config.getIpdNumberId(); + String ipdPassHash = Config.getIpdPassHash(); + String igneous = Config.getIgneous(); + if (ipdMemberId != null) { + cookie.put(KEY_IPD_MEMBER_ID, ipdMemberId); + } + if (ipdPassHash != null) { + cookie.put(KEY_IPD_PASS_HASH, ipdPassHash); + } + if (igneous != null) { + cookie.put(KEY_IGNEOUS, igneous); + } + // TODO cookie.put(KEY_UCONFIG, Config.getUconfig()); + } + + if (HOST_LOFI.equals(host)) { + // TODO cookie.put(KEY_XRES, Config.getXres()); + } + } + + List cookieList = new ArrayList<>(); + cookieList.add(cookie.toString()); + // Map to return + Map> cookieMap = new HashMap<>(requestHeaders); + cookieMap.put("Cookie" , cookieList); + + return Collections.unmodifiableMap(cookieMap); + } + + @Override + public void put(URI uri, Map> responseHeaders) throws IOException { + Cookie cookie = new Cookie(); + + List cookieList = responseHeaders.get("Set-Cookie"); + if (cookieList != null) { + for (String cookieString : cookieList) { + cookie.putRaw(cookieString); + } + } + + String ipdMemberId = cookie.get(KEY_IPD_MEMBER_ID); + String ipdPassHash = cookie.get(KEY_IPD_PASS_HASH); + String igneous = cookie.get(KEY_IGNEOUS); + if (ipdMemberId != null) { + Config.putIpdMemberId(ipdMemberId); + } + if (ipdPassHash != null) { + Config.putIpdPassHash(ipdPassHash); + } + if (igneous != null) { + Config.putIgneous(igneous); + } + + cookie.remove(KEY_IPD_MEMBER_ID); + cookie.remove(KEY_IPD_MEMBER_ID); + cookie.remove(KEY_UCONFIG); + cookie.remove(KEY_XRES); + cookie.remove(KEY_YAY); + + mCookieManager.setCookie(uri.toString(), cookie.toString()); + } + }; + + public static class UserAgentInterceptor implements Interceptor { + + private String mUserAgent; + + public UserAgentInterceptor(String userAgent) { + mUserAgent = userAgent; + } + + @Override + public Response intercept(Chain chain) throws IOException { + Request originalRequest = chain.request(); + Request requestWithUserAgent = originalRequest.newBuilder() + .removeHeader("User-Agent") + .addHeader("User-Agent", mUserAgent) + .build(); + return chain.proceed(requestWithUserAgent); + } + } + + private static final EhOkHttpClient sInstance = new EhOkHttpClient(); + + public static EhOkHttpClient getInstance() { + return sInstance; + } + + private EhOkHttpClient() { + setCookieHandler(mCookieHandler); + setConnectTimeout(5, TimeUnit.SECONDS); + setReadTimeout(5, TimeUnit.SECONDS); + setFollowRedirects(true); + networkInterceptors().add(new UserAgentInterceptor(USER_AGENT)); + } +} diff --git a/app/src/main/java/com/hippo/ehviewer/ui/ContentActivity.java b/app/src/main/java/com/hippo/ehviewer/ui/ContentActivity.java index 18e5ef58d..fe16d21b6 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/ContentActivity.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/ContentActivity.java @@ -27,6 +27,7 @@ import android.view.View; import android.widget.AdapterView; import com.hippo.content.VectorContext; +import com.hippo.ehviewer.Constants; import com.hippo.ehviewer.R; import com.hippo.ehviewer.ui.scene.GalleryListScene; import com.hippo.ehviewer.ui.scene.SignInScene; @@ -37,6 +38,7 @@ import com.hippo.scene.Announcer; import com.hippo.scene.SimpleCurtain; import com.hippo.scene.StageActivity; import com.hippo.scene.StageLayout; +import com.hippo.util.Messenger; import com.hippo.widget.DrawerListView; public final class ContentActivity extends StageActivity @@ -188,6 +190,7 @@ public final class ContentActivity extends StageActivity @Override public void onClickSignOut() { - + Config.putSignIn(false); + Messenger.getInstance().notify(Constants.MESSENGER_ID_SIGN_IN_OR_OUT, null); } } diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/SignInScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/SignInScene.java index 9984aed64..cd4e4f1ad 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/SignInScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/SignInScene.java @@ -18,18 +18,39 @@ package com.hippo.ehviewer.ui.scene; import android.annotation.Nullable; import android.os.Bundle; import android.view.View; +import android.widget.EditText; import android.widget.TextView; import com.hippo.effect.ripple.RippleSalon; +import com.hippo.ehviewer.Constants; import com.hippo.ehviewer.R; +import com.hippo.ehviewer.client.EhClient; +import com.hippo.ehviewer.util.Config; import com.hippo.scene.Scene; +import com.hippo.util.Messenger; -public class SignInScene extends Scene { +public final class SignInScene extends Scene implements View.OnClickListener { private View mMainView; + private EditText mUsername; + private EditText mPassword; private TextView mSignUp; private TextView mSignIn; + private EhClient.OnSignInListener mSignInListener = new EhClient.OnSignInListener() { + @Override + public void onSuccess(String displayname) { + Config.putSignIn(true); + Config.putDisplayName(displayname); + Messenger.getInstance().notify(Constants.MESSENGER_ID_SIGN_IN_OR_OUT, displayname); + } + + @Override + public void onFailure(Exception e) { + e.printStackTrace(); + } + }; + @Override public int getLaunchMode() { return LAUNCH_MODE_SINGLE_TOP; @@ -41,11 +62,15 @@ public class SignInScene extends Scene { setContentView(R.layout.scene_sign_in); mMainView = findViewById(R.id.sigin_in_main); + mUsername = (EditText) mMainView.findViewById(R.id.username); + mPassword = (EditText) mMainView.findViewById(R.id.password); mSignUp = (TextView) mMainView.findViewById(R.id.sign_up); mSignIn = (TextView) mMainView.findViewById(R.id.sign_in); RippleSalon.addRipple(mSignUp, false); RippleSalon.addRipple(mSignIn, false); + mSignUp.setOnClickListener(this); + mSignIn.setOnClickListener(this); } @Override @@ -54,4 +79,13 @@ public class SignInScene extends Scene { mMainView.getPaddingTop(), mMainView.getPaddingRight(), b); } + + @Override + public void onClick(View v) { + if (v == mSignIn) { + String username = mUsername.getText().toString(); + String password = mPassword.getText().toString(); + EhClient.getInstance().signIn(username, password, mSignInListener); + } + } } diff --git a/app/src/main/java/com/hippo/ehviewer/util/Config.java b/app/src/main/java/com/hippo/ehviewer/util/Config.java index 174a1d773..c3baaf8b8 100644 --- a/app/src/main/java/com/hippo/ehviewer/util/Config.java +++ b/app/src/main/java/com/hippo/ehviewer/util/Config.java @@ -79,11 +79,17 @@ public final class Config { private static final String KEY_EH_SOURCE = "eh_source"; private static final int DEFAULT_EH_SOURCE = BuildConfig.DEBUG ? - EhClient.SOURCE_LOFI : EhClient.SOURCE_G; + EhClient.SOURCE_EX : EhClient.SOURCE_G; + private static final String KEY_SIGN_IN = "sign_in"; + private static final boolean DEFAULT_SIGN_IN = false; + private static final String KEY_DISPLAY_NAME = "display_name"; + private static final String DEFAULT_DISPLAY_NAME = null; private static final String KEY_IPD_MEMBER_ID = "ipb_member_id"; private static final String DEFAULT_IPD_MEMBER_ID = null; private static final String KEY_IPD_PASS_HASH = "ipb_pass_hash"; private static final String DEFAULT_IPD_PASS_HASH = null; + private static final String KEY_IGNEOUS = "igneous"; + private static final String DEFAULT_IGNEOUS = null; public static int getEhSource() { int value = getInt(KEY_EH_SOURCE, DEFAULT_EH_SOURCE); @@ -101,6 +107,22 @@ public final class Config { Messenger.getInstance().notify(Constants.MESSENGER_ID_EH_SOURCE, value); } + public static boolean getSignIn() { + return getBoolean(KEY_SIGN_IN, DEFAULT_SIGN_IN); + } + + public static void putSignIn(boolean value) { + putBoolean(KEY_SIGN_IN, value); + } + + public static String getDisplayName() { + return getString(KEY_DISPLAY_NAME, DEFAULT_DISPLAY_NAME); + } + + public static void putDisplayName(String value) { + putString(KEY_DISPLAY_NAME, value); + } + public static String getIpdNumberId() { return getString(KEY_IPD_MEMBER_ID, DEFAULT_IPD_MEMBER_ID); } @@ -117,6 +139,20 @@ public final class Config { putString(KEY_IPD_PASS_HASH, value); } + public static String getIgneous() { + String igneous = getString(KEY_IGNEOUS, DEFAULT_IGNEOUS); + if ("mystery".equals(igneous)) { + return null; + } else { + return igneous; + } + } + + public static void putIgneous(String value) { + if (!"mystery".equals(value)) { + putString(KEY_IGNEOUS, value); + } + } /****** Advance ******/ diff --git a/app/src/main/java/com/hippo/ehviewer/widget/DrawerLeftPanel.java b/app/src/main/java/com/hippo/ehviewer/widget/DrawerLeftPanel.java index a7e9a8734..e91e864ae 100644 --- a/app/src/main/java/com/hippo/ehviewer/widget/DrawerLeftPanel.java +++ b/app/src/main/java/com/hippo/ehviewer/widget/DrawerLeftPanel.java @@ -33,6 +33,7 @@ import com.facebook.drawee.view.SimpleDraweeView; import com.hippo.effect.ripple.RippleSalon; import com.hippo.ehviewer.Constants; import com.hippo.ehviewer.R; +import com.hippo.ehviewer.util.Config; import com.hippo.util.FrescoUtils; import com.hippo.util.Messenger; import com.hippo.widget.DrawerListView; @@ -136,10 +137,17 @@ public class DrawerLeftPanel extends LinearLayout { mUserPanelOriginalPaddingTop = mUserPanel.getPaddingTop(); mDrawerListViewOriginalPaddingBottom = mDrawerListView.getPaddingBottom(); - // TODO - mAvatar.setImageURI(DEFAULT_AVATAR_URI); - mUsename.setText(""); - mAction.setText(mContext.getString(R.string.signin)); + mSignIn = Config.getSignIn(); + if (mSignIn) { + // TODO + mAvatar.setImageURI(DEFAULT_AVATAR_URI); + mUsename.setText(Config.getDisplayName()); + mAction.setText(mContext.getString(R.string.signout)); + } else { + mAvatar.setImageURI(DEFAULT_AVATAR_URI); + mUsename.setText(""); + mAction.setText(mContext.getString(R.string.signin)); + } } public DrawerListView getDrawerListView() { diff --git a/app/src/main/java/com/hippo/network/Cookie.java b/app/src/main/java/com/hippo/network/Cookie.java new file mode 100644 index 000000000..52f61636d --- /dev/null +++ b/app/src/main/java/com/hippo/network/Cookie.java @@ -0,0 +1,85 @@ +/* + * Copyright (C) 2015 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 + * 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.network; + +import com.hippo.util.Utils; + +import java.util.HashMap; +import java.util.Map; + +public class Cookie { + + private static final String KEY_DOMAIN = "domain"; + private static final String KEY_PATH = "path"; + private static final String KEY_EXPIRES = "expires"; + + private static final String[] UNSUPPORT_KEY = { + KEY_DOMAIN, + KEY_PATH, + KEY_EXPIRES + }; + + private Map mItems = new HashMap<>(); + + public void putRaw(String cookieString) { + if (cookieString != null) { + String[] pieces = cookieString.split(";"); + for (String p : pieces) { + int index = p.indexOf('='); + if (index != -1) { + String key = p.substring(0, index).trim(); + String value = p.substring(index + 1).trim(); + if (!Utils.contain(UNSUPPORT_KEY, key)) { + mItems.put(key, value); + } + } + } + } + } + + public void put(String key, String value) { + if (!Utils.contain(UNSUPPORT_KEY, key)) { + mItems.put(key, value); + } + } + + public void remove(String key) { + mItems.remove(key); + } + + public String get(String key) { + return mItems.get(key); + } + + public String toString() { + StringBuilder sb = new StringBuilder(); + String separator1 = "; "; + String separator2 = "="; + boolean first = true; + + for (String key : mItems.keySet()) { + String value = mItems.get(key); + if (first) { + first = false; + } else { + sb.append(separator1); + } + sb.append(key).append(separator2).append(value); + } + + return sb.toString(); + } +} diff --git a/app/src/main/java/com/hippo/network/HttpHelper.java b/app/src/main/java/com/hippo/network/HttpHelper.java deleted file mode 100644 index 0e6427892..000000000 --- a/app/src/main/java/com/hippo/network/HttpHelper.java +++ /dev/null @@ -1,951 +0,0 @@ -/* - * Copyright (C) 2014-2015 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 - * 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.network; - -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; -import android.webkit.CookieManager; -import android.webkit.MimeTypeMap; - -import com.hippo.util.FastByteArrayOutputStream; -import com.hippo.util.Log; -import com.hippo.util.Utils; - -import org.json.JSONObject; - -import java.io.ByteArrayOutputStream; -import java.io.DataOutputStream; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.FileOutputStream; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.net.HttpURLConnection; -import java.net.MalformedURLException; -import java.net.URL; -import java.net.URLConnection; -import java.net.URLEncoder; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; -import java.util.zip.GZIPInputStream; - -/** - * It is not thread safe - */ -public class HttpHelper { - private static final String TAG = HttpHelper.class.getSimpleName(); - - private static final int MAX_RETRY = 3; - private static final int MAX_REDIRECTS = 3; - private static final int CONNECT_TIMEOUT = 5000; - private static final int READ_TIMEOUT = 5000; - - public static final String DEFAULT_USER_AGENT = - "Mozilla/5.0 (Windows NT 6.1; WOW64) " + - "AppleWebKit/537.36 (KHTML, like Gecko) " + - "Chrome/39.0.2171.95 Safari/537.36"; - public static final String USER_AGENT = - System.getProperty("http.agent", DEFAULT_USER_AGENT); - - private static final int HTTP_TEMP_REDIRECT = 307; - - private static final String DEFAULT_CHARSET = "utf-8"; - private static final String CHARSET_KEY = "charset="; - - private static final CookieManager sCookieManager = CookieManager.getInstance(); - - private int mResponseCode = -1; - - public void reset() { - mResponseCode = -1; - } - - public int getResponseCode() { - return mResponseCode; - } - - /** - * Get cookie for the url - * @param url the URL - * @return the cookie for the URL - */ - protected String getCookie(URL url) { - return sCookieManager.getCookie(url.toString()); - } - - /** - * Store cookie for the url - * @param url the URL - * @param value the cookie for the URL - */ - protected void storeCookie(URL url, String value) { - sCookieManager.setCookie(url.toString(), value); - } - - /** - * Prepare before connecting - * @param conn the connection - */ - protected void onBeforeConnect(HttpURLConnection conn) { - conn.setInstanceFollowRedirects(true); - conn.setRequestProperty("User-Agent", USER_AGENT); - conn.setConnectTimeout(CONNECT_TIMEOUT); - conn.setReadTimeout(READ_TIMEOUT); - } - - /** - * Is URL.toString is same - */ - public static boolean isURLEquals(URL url1, URL url2) { - if (url1 != null && url2 != null) { - String urlStr1 = url1.toString(); - String urlStr2 = url2.toString(); - if (urlStr1 != null && urlStr2 != null) { - return urlStr1.equals(urlStr2); - } - } - return false; - } - - /** - * parse string like haha=hehe; fere=bfdgds - * - * @param raw the raw string - * @return the key is toLowerCase - */ - public static @NonNull Map parseMap(@Nullable String raw) { - Map map = new HashMap<>(); - if (raw != null) { - String[] pieces = raw.split(";"); - for (String p : pieces) { - int index = p.indexOf('='); - if (index != -1) { - String key = p.substring(0, index).trim(); - String value = p.substring(index + 1).trim(); - - // value might be "blabla", remove " - int valueLength = value.length(); - if (value.length() > 1 && value.charAt(0) == '"' && - value.charAt(valueLength - 1) == '"') { - value = value.substring(1, valueLength - 1); - } - map.put(key.toLowerCase(), value); - } - } - } - - return map; - } - - private Object doRequst(RequestHelper rh) throws Exception { - URL url; - HttpURLConnection conn = null; - int redirectionCount = 0; - try { - url = rh.getUrl(); - while (redirectionCount++ < MAX_REDIRECTS) { - Log.d(TAG, "Request: " + url.toString()); - conn = (HttpURLConnection) url.openConnection(); - // Prepare before connecting - onBeforeConnect(conn); - // Set cookie - String cookie = getCookie(url); - if (cookie != null) { - conn.setRequestProperty("Cookie", cookie); - } - // Do custom staff - rh.onBeforeConnect(conn); - - conn.connect(); - // Store cookie - List cookieList = conn.getHeaderFields().get("Set-Cookie"); - if (cookieList != null) { - for (String cookieTemp : cookieList) { - if (cookieTemp != null) { - storeCookie(url, cookieTemp); - } - } - } - final int responseCode = conn.getResponseCode(); - mResponseCode = responseCode; - Log.d(TAG, "Response code: " + responseCode); - switch (responseCode) { - case HttpURLConnection.HTTP_MOVED_PERM: - case HttpURLConnection.HTTP_MOVED_TEMP: - case HttpURLConnection.HTTP_SEE_OTHER: - case HTTP_TEMP_REDIRECT: - // Should not come here, - // because conn.setInstanceFollowRedirects(true) - final String location = conn.getHeaderField("Location"); - Log.d(TAG, "New location: " + location); - conn.disconnect(); - url = new URL(url, location); - break; - default: - // Check redirect - URL finalURL = conn.getURL(); - if (!isURLEquals(url, finalURL)) { - rh.onRedirect(finalURL); - } - return rh.onAfterConnect(conn); - } - } - } finally { - if (conn != null) - conn.disconnect(); - } - - throw new RedirectionException(); - } - - protected Object requst(@NonNull RequestHelper rh) throws Exception { - Exception exception = null; - for ( - int times = 0; - times < MAX_RETRY && (times == 0 || rh.onRetry(exception)); - times++) { - try { - return doRequst(rh); - } catch (Exception e) { - exception = e; - } - } - - rh.onRequestFailed(exception); - - throw exception; - } - - public interface RequestHelper { - - /** - * Get the URL to connect - * @return the URL to connect - */ - URL getUrl() throws MalformedURLException; - - /** - * Add header or do something else for HttpURLConnection before connect - * - * @param conn the connection - * @throws Exception - */ - void onBeforeConnect(HttpURLConnection conn) throws Exception; - - /** - * If get redirect - * - * @param newURL the new URL - */ - void onRedirect(URL newURL); - - /** - * Get what do you need from HttpURLConnection after connect - * Return null means get error - * - * @param conn the connection - * @return what you want to return - * @throws Exception - */ - Object onAfterConnect(HttpURLConnection conn) throws Exception; - - /** - * Retry http connecting, or stop - * - * @param previousException previous thrown - * @return true for retry, false for stop - */ - boolean onRetry(Exception previousException); - - /** - * Called when request failed by exception - * - * @param exception the final exception - */ - void onRequestFailed(Exception exception); - } - - public static abstract class GetStringHelper implements RequestHelper { - private final String mUrl; - - public GetStringHelper(String url) { - mUrl = url; - } - - @Override - public URL getUrl() throws MalformedURLException { - return new URL(mUrl); - } - - @Override - public void onBeforeConnect(HttpURLConnection conn) - throws Exception { - conn.addRequestProperty("Accept-Encoding", "gzip"); - } - - private String getCharset(HttpURLConnection conn) { - String charset = parseMap(conn.getContentType()).get("charset"); - if (charset != null) { - return charset; - } else { - return DEFAULT_CHARSET; - } - } - - private String getBody(HttpURLConnection conn) - throws Exception { - String body = null; - InputStream is = null; - ByteArrayOutputStream baos = null; - try { - try { - // First try to get input stream - is = conn.getInputStream(); - } catch (Exception t){ - // If we get error, get error stream - is = conn.getErrorStream(); - } - String encoding = conn.getContentEncoding(); - if (encoding != null && encoding.equalsIgnoreCase("gzip")) - is = new GZIPInputStream(is); - - int length = conn.getContentLength(); - if (length >= 0) { - baos = new ByteArrayOutputStream(length); - } else { - baos = new ByteArrayOutputStream(); - } - - Utils.copy(is, baos); - - body = baos.toString(getCharset(conn)); - - } finally { - Utils.closeQuietly(is); - Utils.closeQuietly(baos); - } - - return body; - } - - @Override - public void onRedirect(@NonNull URL newURL) { - // Empty - } - - @Override - public Object onAfterConnect(@NonNull HttpURLConnection conn) - throws Exception { - return getBody(conn); - } - - @Override - public boolean onRetry(@NonNull Exception previousException) { - // Do not care about exception, just retry - return true; - } - - @Override - public void onRequestFailed(@NonNull Exception exception) { - // Empty - } - } - - /** - * RequstHelper for GET method - */ - public static class GetHelper extends GetStringHelper { - - public GetHelper(String url) { - super(url); - } - - @Override - public void onBeforeConnect(@NonNull HttpURLConnection conn) - throws Exception { - super.onBeforeConnect(conn); - conn.setRequestMethod("GET"); - } - } - - /** - * RequstHelper for post form data, use POST method - */ - public static class PostFormHelper extends GetStringHelper { - private final String[][] mArgs; - - public PostFormHelper(String url, String[][] args) { - super(url); - mArgs = args; - } - - @Override - public void onBeforeConnect(HttpURLConnection conn) - throws Exception { - super.onBeforeConnect(conn); - conn.setDoOutput(true); - conn.setDoInput(true); - conn.setUseCaches(false); - conn.setRequestMethod("POST"); - conn.setRequestProperty("Content-Type", - "application/x-www-form-urlencoded"); - - DataOutputStream out = new DataOutputStream(conn.getOutputStream()); - StringBuilder sb = new StringBuilder(); - int i = 0; - for (String[] arg : mArgs) { - if (i != 0) - sb.append("&"); - sb.append(URLEncoder.encode(arg[0], "UTF-8")); - sb.append("="); - sb.append(URLEncoder.encode(arg[1], "UTF-8")); - i++; - } - out.writeBytes(sb.toString()); - out.flush(); - out.close(); - } - } - - /** - * RequstHelper for post json, use POST method - */ - public static class PostJsonHelper extends GetStringHelper { - private final JSONObject mJo; - - public PostJsonHelper(String url, JSONObject jo) { - super(url); - mJo = jo; - } - - @Override - public void onBeforeConnect(HttpURLConnection conn) throws Exception { - super.onBeforeConnect(conn); - conn.setDoOutput(true); - conn.setDoInput(true); - conn.setUseCaches(false); - conn.setRequestMethod("POST"); - conn.setRequestProperty("Content-Type", "application/json"); - - DataOutputStream out = new DataOutputStream(conn.getOutputStream()); - String body = mJo.toString(); - Log.d(TAG, "Post json: " + body); - out.write(body.getBytes("utf-8")); - out.flush(); - out.close(); - } - } - - public abstract static class FormData { - private final Map mProperties; - - public FormData() { - mProperties = new LinkedHashMap<>(); - } - - public void setProperty(String key, String value) { - mProperties.put(key, value); - } - - public void clearProperty(String key) { - mProperties.remove(key); - } - - public void clearAllProperties() { - mProperties.clear(); - } - - /** - * Put information to target OutputStream. - * - * @param os target outputStream - * @throws java.io.IOException - */ - public abstract void output(OutputStream os) throws IOException; - - public void doOutPut(OutputStream os) throws IOException { - StringBuilder sb = new StringBuilder(); - for (String key : mProperties.keySet()) - sb.append(key).append(": ").append(mProperties.get(key)).append("\r\n"); - sb.append("\r\n"); - os.write(sb.toString().getBytes()); - output(os); - } - } - - public static class StringData extends FormData { - private final String mStr; - - public StringData(String str) { - mStr = str; - } - - @Override - public void output(OutputStream os) throws IOException { - os.write(mStr.getBytes()); - os.write("\r\n".getBytes()); - } - } - - public static class BitmapData extends FormData { - private final Bitmap mBitmap; - - public BitmapData(Bitmap bmp) { - mBitmap = bmp; - setProperty("Content-Type", "image/jpeg"); - } - - @Override - public void output(OutputStream os) throws IOException { - mBitmap.compress(Bitmap.CompressFormat.JPEG, 98, os); - os.write("\r\n".getBytes()); - } - } - - public static class FileData extends FormData { - private final File mFile; - - public FileData(File file) { - mFile = file; - setProperty("Content-Type", - URLConnection.guessContentTypeFromName(file.getName())); - } - - @Override - public void output(OutputStream os) throws IOException { - InputStream is = new FileInputStream(mFile); - byte[] buffer = new byte[1024]; - int bytesRead; - while((bytesRead = is.read(buffer)) !=-1) - os.write(buffer, 0, bytesRead); - is.close(); - - os.write("\r\n".getBytes()); - } - } - - public static class PostFormDataHelper extends GetStringHelper { - private static final String BOUNDARY = "----WebKitFormBoundary7eDB0hDQ91s22Tkf"; - - private final List mDataList; - - - public PostFormDataHelper(String url, List dataList) { - super(url); - mDataList = dataList; - } - - @Override - public void onBeforeConnect(HttpURLConnection conn) throws Exception { - super.onBeforeConnect(conn); - conn.setDoOutput(true); - conn.setDoInput(true); - conn.setUseCaches(false); - conn.setRequestMethod("POST"); - conn.setRequestProperty("Content-Type", - "multipart/form-data; boundary=" + BOUNDARY); - - DataOutputStream out = new DataOutputStream(conn.getOutputStream()); - - for (FormData data : mDataList) { - out.write("--".getBytes()); - out.write(BOUNDARY.getBytes()); - out.write("\r\n".getBytes()); - data.doOutPut(out); - } - out.write("--".getBytes()); - out.write(BOUNDARY.getBytes()); - out.write("--".getBytes()); - - out.flush(); - out.close(); - } - } - - public static class GetImageHelper implements RequestHelper { - private final String mUrl; - - public GetImageHelper(String url) { - mUrl = url; - } - - @Override - public URL getUrl() throws MalformedURLException { - return new URL(mUrl); - } - - @Override - public void onBeforeConnect(HttpURLConnection conn) - throws Exception { - conn.setRequestMethod("GET"); - } - - @Override - public void onRedirect(@NonNull URL newURL) { - // Empty - } - - @Override - public Object onAfterConnect(HttpURLConnection conn) - throws Exception { - // If just - // Bitmap bmp = BitmapFactory.decodeStream(conn.getInputStream(), null, Ui.getBitmapOpt()); - // bitmap might be incomplete. - int size = conn.getContentLength(); - FastByteArrayOutputStream fbaos = new FastByteArrayOutputStream(size == -1 ? 24 * 1024 : (size + 100)); - Utils.copy(conn.getInputStream(), fbaos); - Bitmap bmp = BitmapFactory.decodeByteArray(fbaos.getBuffer(), 0, fbaos.size(), null); - - if (bmp == null) { - throw new IllegalStateException("Can not decode to bitmap."); - } - return bmp; - } - - @Override - public boolean onRetry(Exception previousException) { - // Do not care about exception, just retry - return true; - } - - @Override - public void onRequestFailed(Exception exception) { - // Empty - } - } - - public interface OnDownloadListener { - - /** - * Called before connecting - */ - void onStartConnecting(); - - /** - * Called after connecting and before downloading - * - * @param totalSize content length, -1 for unknown - */ - void onStartDownloading(int totalSize); - - /** - * File name is fixed - * - * @param newName new file name - */ - void onNameFix(String newName); - - /** - * Called repeatedly during downloading - * - * @param downloadSize downloaded size - * @param totalSize content length, -1 for unknown - */ - void onDownload(int downloadSize, int totalSize); - - /** - * Called when download ok - */ - void onSuccess(); - - /** - * Called when download stop - */ - void onStop(); - - /** - * Called when download failed - * - * @param e the exception why fail - */ - void onFailure(Exception e); - } - - public static class DownloadControlor { - private boolean mStop = false; - - public void stop() { - mStop = true; - } - - public void reset() { - mStop = false; - } - - public boolean isStop() { - return mStop; - } - } - - public static class DownloadHelper implements RequestHelper { - - private static final String DOWNLOAD_EXTENSION = ".download"; - - private final String mUrl; - private final File mDir; - private String mFileName; - private File mFile; - private File mTempFile; - private final DownloadControlor mControlor; - private final OnDownloadListener mListener; - private int mContentLength; - private int mReceivedSize; - - public DownloadHelper(String url, File dir, String fileName, - DownloadControlor controlor, OnDownloadListener listener) { - mUrl = url; - mDir = dir; - mFileName = fileName; - mControlor = controlor; - mListener = listener; - } - - @Override - public URL getUrl() throws MalformedURLException { - return new URL(mUrl); - } - - private void checkStop() throws StopRequestException { - if (mControlor != null && mControlor.isStop()) { - throw new StopRequestException(); - } - } - - @Override - public void onBeforeConnect(HttpURLConnection conn) throws Exception { - checkStop(); - - conn.setRequestMethod("GET"); - // Sometimes for application/octet-stream, we need to add this line - // to get content length - conn.setRequestProperty("Range", "bytes=0-"); - - if (mListener != null) { - mListener.onStartConnecting(); - } - } - - private int getContentLength(HttpURLConnection conn) { - int contentLength = conn.getContentLength(); - String range; - if (contentLength == -1 && - (range = conn.getHeaderField("Content-Range")) != null) { - // Content-Range looks like bytes 500-999/1234 - int index = range.indexOf('/'); - if (index != -1) { - contentLength = Utils.parseIntSafely(range.substring(index + 1), -1); - } - } - return contentLength; - } - - @Override - public void onRedirect(@NonNull URL newURL) { - // TODO - } - - /** - * Get new extension - * - * @param ext new extension - * @return null for not changed - */ - protected String fixNewExtension(String ext) { - return null; - } - - @Override - public Object onAfterConnect(HttpURLConnection conn) throws Exception { - // Check stop - if (mControlor != null && mControlor.isStop()) - throw new StopRequestException(); - - String contentType = conn.getContentType(); - int index = contentType.indexOf(';'); - if (index != -1) - contentType = contentType.substring(0, index); - - mContentLength = getContentLength(conn); - if (mListener != null) { - mListener.onStartDownloading(mContentLength); - } - - // Fix extension - MimeTypeMap mime = MimeTypeMap.getSingleton(); - String newExtension = mime.getExtensionFromMimeType(contentType); - if (newExtension == null) { - index = contentType.lastIndexOf('/'); - if (index != -1) { - newExtension = contentType.substring(index + 1); - } - } - newExtension = fixNewExtension(newExtension); - if (newExtension != null) { - index = mFileName.lastIndexOf('.'); - if (index == -1) { - mFileName = mFileName + '.' + newExtension; - } else { - mFileName = mFileName.substring(0, index) + '.' + newExtension; - } - } - - // Make sure parent exist - if (!mDir.mkdirs() && !mDir.isDirectory()) { - throw new FileNotFoundException("Can not create dir " + - mDir.getPath()); - } - - mFile = new File(mDir, mFileName); - mTempFile = new File(mDir, mFileName + DOWNLOAD_EXTENSION); - - // Transfer - transferData(conn.getInputStream(), new FileOutputStream(mTempFile)); - - // Get ok, rename - Utils.deleteFile(mFile); - if (!mTempFile.renameTo(mFile)) { - throw new FileNotFoundException("Rename " + mTempFile.getPath() + - " to " + mFile.getPath() + " error"); - } - - // Callback - if (mListener != null) { - mListener.onSuccess(); - } - - // We do not need result - return null; - } - - private void transferData(InputStream in, OutputStream out) - throws Exception { - final byte data[] = new byte[512 * 1024]; - mReceivedSize = 0; - - while (true) { - // Check stop first - checkStop(); - - int bytesRead = in.read(data); - if (bytesRead == -1) - break; - out.write(data, 0, bytesRead); - mReceivedSize += bytesRead; - - if (mListener != null) { - mListener.onDownload(mReceivedSize, mContentLength); - } - } - - if (mContentLength != -1 && mReceivedSize != mContentLength) { - throw new UncompletedException("Received size is " + mReceivedSize - + ", but ContentLength is " + mContentLength); - } - } - - @Override - public boolean onRetry(Exception previousException) { - // Delete unfinished file - Utils.deleteFile(mTempFile); - Utils.deleteFile(mFile); - - if (previousException instanceof StopRequestException) { - return false; - } else { - return true; - } - } - - @Override - public void onRequestFailed(Exception exception) { - if (mListener != null) { - if (exception instanceof StopRequestException) { - mListener.onStop(); - } else { - mListener.onFailure(exception); - } - } - } - } - - /** - * Http GET method - * @param url the url to get - * @return body - */ - public String get(String url) throws Exception { - return (String) requst(new GetHelper(url)); - } - - /** - * Post form data - * @param url the url to post - * @param args the form to post - * @return body - */ - public String postForm(String url, String[][] args) throws Exception { - return (String) requst(new PostFormHelper(url, args)); - } - - /** - * Post json data - * @param url the url to post - * @param json the json to post - * @return body - */ - public String postJson(String url, JSONObject json) throws Exception { - return (String) requst(new PostJsonHelper(url, json)); - } - - /** - * Post data, multipart/form-data - * @param url the url to post - * @param dataList the data list to post - * @return body - */ - public String postFormData(String url, List dataList) throws Exception { - return (String)requst(new PostFormDataHelper(url, dataList)); - } - - /** - * Get image - * @param url the url to get image - * @return bitmap - */ - public Bitmap getImage(String url) throws Exception { - return (Bitmap) requst(new GetImageHelper(url)); - } - - /** - * Init DownloadHelper - * - * @param url the url to download - * @param dir the dir to download file - * @param file the file name - * @param controlor download control - * @param listener download listener - */ - public void download(String url, File dir, String file, - DownloadControlor controlor, OnDownloadListener listener) throws Exception { - requst(new DownloadHelper(url, dir, file, controlor, listener)); - } -} diff --git a/app/src/main/java/com/hippo/network/RedirectionException.java b/app/src/main/java/com/hippo/network/RedirectionException.java deleted file mode 100644 index 125028fb6..000000000 --- a/app/src/main/java/com/hippo/network/RedirectionException.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2014-2015 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 - * 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.network; - -public class RedirectionException extends Exception { - - public RedirectionException() { - super("To many redirection"); - } -} diff --git a/app/src/main/java/com/hippo/network/StopRequestException.java b/app/src/main/java/com/hippo/network/StopRequestException.java deleted file mode 100644 index 8077f8332..000000000 --- a/app/src/main/java/com/hippo/network/StopRequestException.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2014-2015 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 - * 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.network; - -public class StopRequestException extends Exception { - - public StopRequestException() { - super("Stoped by request"); - } -} diff --git a/app/src/main/java/com/hippo/network/UncompletedException.java b/app/src/main/java/com/hippo/network/UncompletedException.java deleted file mode 100644 index 334ef19d9..000000000 --- a/app/src/main/java/com/hippo/network/UncompletedException.java +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2014-2015 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 - * 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.network; - -public class UncompletedException extends Exception { - - public UncompletedException() { - super("Uncompleted error"); - } - - public UncompletedException(String detailMessage) { - super(detailMessage); - } -} diff --git a/app/src/main/java/com/hippo/util/ExceptionUtils.java b/app/src/main/java/com/hippo/util/ExceptionUtils.java index c3595112e..51d5ace2b 100644 --- a/app/src/main/java/com/hippo/util/ExceptionUtils.java +++ b/app/src/main/java/com/hippo/util/ExceptionUtils.java @@ -21,11 +21,12 @@ import android.support.annotation.NonNull; import android.support.annotation.Nullable; import com.hippo.ehviewer.R; -import com.hippo.network.RedirectionException; +import com.hippo.ehviewer.client.EhException; import com.hippo.network.ResponseCodeException; import org.apache.http.conn.ConnectTimeoutException; +import java.net.ProtocolException; import java.net.SocketException; import java.net.SocketTimeoutException; import java.net.UnknownHostException; @@ -46,10 +47,12 @@ public final class ExceptionUtils { error += '\n' + responseCodeException.getMessage(); } return error; - } else if (e instanceof RedirectionException) { + } else if (e instanceof ProtocolException && e.getMessage().startsWith("Too many follow-up requests:")) { return context.getString(R.string.em_redirection); } else if (e instanceof SocketException) { return context.getString(R.string.em_socket); + } else if (e instanceof EhException) { + return e.getMessage(); } else { Log.d("Can't recognize this Exception", e); return context.getString(R.string.em_unknown); diff --git a/app/src/main/java/com/hippo/util/Utils.java b/app/src/main/java/com/hippo/util/Utils.java index 9965b6356..112618c2d 100644 --- a/app/src/main/java/com/hippo/util/Utils.java +++ b/app/src/main/java/com/hippo/util/Utils.java @@ -15,6 +15,7 @@ package com.hippo.util; +import android.annotation.NonNull; import android.annotation.SuppressLint; import android.content.Context; import android.os.AsyncTask; @@ -804,4 +805,13 @@ public final class Utils { return EMPTY_STRING; } } + + public static boolean contain(@NonNull Object[] array, Object obj) { + for (Object o : array) { + if (o.equals(obj)) { + return true; + } + } + return false; + } }