Use OkHttpClient

This commit is contained in:
seven332 committed 2015-05-18 19:53:59 +08:00
1 parent 08d0794fe8
commit b7f8cda304
18 files changed
+551 -1121

No files matched your search

+7 -3
View File
@@ -74,6 +74,7 @@
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.facebook.fresco/drawee/0.5.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.facebook.fresco/fbcore/0.5.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.facebook.fresco/fresco/0.5.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.facebook.fresco/imagepipeline-okhttp/0.5.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.facebook.fresco/imagepipeline/0.5.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
@@ -92,15 +93,18 @@
</content>
<orderEntry type="jdk" jdkName="Android API 22 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" exported="" name="appcompat-v7-22.1.1" level="project" />
<orderEntry type="library" exported="" name="svg-android-2.0.6" level="project" />
<orderEntry type="library" exported="" name="imagepipeline-0.5.0" level="project" />
<orderEntry type="library" exported="" name="support-annotations-22.1.1" level="project" />
<orderEntry type="library" exported="" name="appcompat-v7-22.1.1" level="project" />
<orderEntry type="library" exported="" name="fresco-0.5.0" level="project" />
<orderEntry type="library" exported="" name="fbcore-0.5.0" level="project" />
<orderEntry type="library" exported="" name="drawee-0.5.0" level="project" />
<orderEntry type="library" exported="" name="bolts-android-1.1.4" level="project" />
<orderEntry type="library" exported="" name="imagepipeline-0.5.0" level="project" />
<orderEntry type="library" exported="" name="imagepipeline-okhttp-0.5.0" level="project" />
<orderEntry type="library" exported="" name="library-2.4.0" level="project" />
<orderEntry type="library" exported="" name="support-v4-22.1.1" level="project" />
<orderEntry type="library" exported="" name="support-annotations-22.1.1" level="project" />
<orderEntry type="library" exported="" name="okhttp-2.4.0-RC1" level="project" />
<orderEntry type="library" exported="" name="okio-1.4.0" level="project" />
</component>
</module>
+2
View File
@@ -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'])
}
@@ -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);
}
@@ -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<GalleryInfo> 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<GalleryInfo> 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));
}
}
@@ -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("<p>You are now logged in as: (.+?)<br />");
m = p.matcher(body);
if (m.find()) {
displayname = m.group(1);
return true;
} else {
p = Pattern.compile("(?:<h4>The error returned was:</h4>\\s*<p>(.+?)</p>)"
+ "|(?:<span class=\"postcolor\">(.+?)</span>)");
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
}
}
}
}
@@ -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<EhHttpHelper> 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);
}
}
@@ -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<String, List<String>> get(URI uri, Map<String, List<String>> 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<String> cookieList = new ArrayList<>();
cookieList.add(cookie.toString());
// Map to return
Map<String, List<String>> cookieMap = new HashMap<>(requestHeaders);
cookieMap.put("Cookie" , cookieList);
return Collections.unmodifiableMap(cookieMap);
}
@Override
public void put(URI uri, Map<String, List<String>> responseHeaders) throws IOException {
Cookie cookie = new Cookie();
List<String> 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));
}
}
@@ -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);
}
}
@@ -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);
}
}
}
@@ -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 ******/
@@ -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() {
@@ -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<String, String> 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();
}
}
@@ -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 <code>haha=hehe; fere=bfdgds</code>
*
* @param raw the raw string
* @return the key is toLowerCase
*/
public static @NonNull Map<String, String> parseMap(@Nullable String raw) {
Map<String, String> 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<String> 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<String, String> 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<FormData> mDataList;
public PostFormDataHelper(String url, List<FormData> 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<FormData> 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));
}
}
@@ -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");
}
}
@@ -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");
}
}
@@ -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);
}
}
@@ -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);
@@ -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;
}
}