From 8d5c8c423666b99e5deb249e764929377fdea827 Mon Sep 17 00:00:00 2001 From: seven332 Date: Sat, 11 Jul 2015 20:08:49 +0800 Subject: [PATCH] Make EhClient request cancellable --- .gitmodules | 3 + app/build.gradle | 4 +- .../com/hippo/ehviewer/EhApplication.java | 33 +- ...ancellable.java => CanceledException.java} | 6 +- .../com/hippo/ehviewer/client/EhClient.java | 644 +++++------------ .../com/hippo/ehviewer/client/EhConfig.java | 655 ++++++++++++++++++ .../com/hippo/ehviewer/client/EhEngine.java | 139 ++++ .../com/hippo/ehviewer/client/EhRequest.java | 58 ++ .../java/com/hippo/ehviewer/client/EhUrl.java | 70 ++ .../ehviewer/client/GalleryDetailParser.java | 236 +++---- .../ehviewer/client/GalleryListParser.java | 226 +++--- .../hippo/ehviewer/client/ParserUtils.java | 34 + .../hippo/ehviewer/client/PopularParser.java | 25 +- .../hippo/ehviewer/client/SignInParser.java | 6 +- .../ehviewer/client/data/ListUrlBuilder.java | 29 +- .../hippo/ehviewer/network/EhHttpClient.java | 146 ++++ .../hippo/ehviewer/network/EhHttpRequest.java | 67 ++ .../ehviewer/network/EhOkHttpClient.java | 193 ------ .../hippo/ehviewer/ui/ContentActivity.java | 6 +- .../ehviewer/ui/scene/GalleryDetailScene.java | 65 +- .../ehviewer/ui/scene/GalleryListScene.java | 52 +- .../hippo/ehviewer/ui/scene/SignInScene.java | 23 +- .../ui/scene/preference/EHSettingsScene.java | 6 +- .../java/com/hippo/ehviewer/util/EhUtils.java | 52 +- .../util/{Config.java => Settings.java} | 53 +- .../hippo/ehviewer/widget/CategoryTable.java | 42 +- .../ehviewer/widget/DrawerLeftPanel.java | 6 +- .../com/hippo/ehviewer/widget/SearchBar.java | 8 +- .../main/java/com/hippo/network/Cookie.java | 86 --- .../hippo/network/ResponseCodeException.java | 87 --- .../scene/preference/ListPreference.java | 6 +- .../scene/preference/SwitchPreference.java | 6 +- .../java/com/hippo/util/ExceptionUtils.java | 2 +- .../res/layout/item_gallery_list_detail.xml | 1 + .../main/res/layout/scene_gallery_list.xml | 1 + app/src/main/res/layout/search_category.xml | 1 + beerbelly | 2 +- build.gradle | 2 +- cardsalon | 2 +- conaco | 2 +- gradle/wrapper/gradle-wrapper.properties | 4 +- httpclient | 1 + settings.gradle | 2 +- 43 files changed, 1841 insertions(+), 1251 deletions(-) rename app/src/main/java/com/hippo/ehviewer/client/{Cancellable.java => CanceledException.java} (84%) create mode 100644 app/src/main/java/com/hippo/ehviewer/client/EhConfig.java create mode 100644 app/src/main/java/com/hippo/ehviewer/client/EhEngine.java create mode 100644 app/src/main/java/com/hippo/ehviewer/client/EhRequest.java create mode 100644 app/src/main/java/com/hippo/ehviewer/client/EhUrl.java create mode 100644 app/src/main/java/com/hippo/ehviewer/client/ParserUtils.java create mode 100644 app/src/main/java/com/hippo/ehviewer/network/EhHttpClient.java create mode 100644 app/src/main/java/com/hippo/ehviewer/network/EhHttpRequest.java delete mode 100644 app/src/main/java/com/hippo/ehviewer/network/EhOkHttpClient.java rename app/src/main/java/com/hippo/ehviewer/util/{Config.java => Settings.java} (76%) delete mode 100644 app/src/main/java/com/hippo/network/Cookie.java delete mode 100644 app/src/main/java/com/hippo/network/ResponseCodeException.java create mode 160000 httpclient diff --git a/.gitmodules b/.gitmodules index 62460061f..b0fd0288a 100644 --- a/.gitmodules +++ b/.gitmodules @@ -19,3 +19,6 @@ [submodule "cardsalon"] path = cardsalon url = https://github.com/seven332/CardSalon +[submodule "httpclient"] + path = httpclient + url = https://github.com/seven332/HttpClient diff --git a/app/build.gradle b/app/build.gradle index 5af16ceb6..b5b607074 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -2,7 +2,7 @@ apply plugin: 'com.android.application' android { compileSdkVersion 22 - buildToolsVersion "22.0.1" + buildToolsVersion "23.0.0 rc3" defaultConfig { applicationId "com.hippo.ehviewer.test" @@ -34,7 +34,6 @@ android { dependencies { compile 'com.android.support:support-v4:22.2.0' compile 'com.android.support:appcompat-v7:22.2.0' - compile 'com.squareup.okhttp:okhttp:2.4.0' debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3.1' releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1' compile fileTree(dir: 'libs', include: ['*.jar']) @@ -45,4 +44,5 @@ dependencies { compile project(':beerbelly') compile project(':conaco') compile project(':cardsalon') + compile project(':httpclient') } diff --git a/app/src/main/java/com/hippo/ehviewer/EhApplication.java b/app/src/main/java/com/hippo/ehviewer/EhApplication.java index 507d8a8dc..41d37d9e5 100644 --- a/app/src/main/java/com/hippo/ehviewer/EhApplication.java +++ b/app/src/main/java/com/hippo/ehviewer/EhApplication.java @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 Hippo Seven + * Copyright 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 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -18,13 +18,13 @@ package com.hippo.ehviewer; import android.app.ActivityManager; import android.content.Context; -import android.os.Build; -import android.webkit.CookieSyncManager; import com.hippo.beerbelly.SimpleDiskCache; import com.hippo.conaco.Conaco; -import com.hippo.ehviewer.network.EhOkHttpClient; -import com.hippo.ehviewer.util.Config; +import com.hippo.ehviewer.client.EhClient; +import com.hippo.ehviewer.network.EhHttpClient; +import com.hippo.ehviewer.util.Settings; +import com.hippo.httpclient.HttpClient; import com.hippo.scene.SceneApplication; import com.hippo.util.Log; import com.hippo.vectorold.content.VectorContext; @@ -34,6 +34,8 @@ import java.io.IOException; public class EhApplication extends SceneApplication { + private HttpClient mHttpClient; + private EhClient mEhClient; private Conaco mConaco; private SimpleDiskCache mReadcache; @@ -41,11 +43,10 @@ public class EhApplication extends SceneApplication { public void onCreate() { super.onCreate(); - Config.initialize(this); + Settings.initialize(this); - if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { - CookieSyncManager.createInstance(this); - } + mHttpClient = new EhHttpClient(this); + mEhClient = new EhClient(mHttpClient); Conaco.Builder conacoBuilder = new Conaco.Builder(); conacoBuilder.hasMemoryCache = true; @@ -53,7 +54,7 @@ public class EhApplication extends SceneApplication { conacoBuilder.hasDiskCache = true; conacoBuilder.diskCacheDir = new File(getCacheDir(), "conaco"); conacoBuilder.diskCacheMaxSize = 50 * 1024 * 1024; - conacoBuilder.httpClient = EhOkHttpClient.getInstance(); + conacoBuilder.httpClient = mHttpClient; mConaco = conacoBuilder.build(); try { @@ -84,6 +85,16 @@ public class EhApplication extends SceneApplication { } } + public static HttpClient getHttpClient(Context context) { + EhApplication application = (EhApplication) context.getApplicationContext(); + return application.mHttpClient; + } + + public static EhClient getEhClient(Context context) { + EhApplication application = (EhApplication) context.getApplicationContext(); + return application.mEhClient; + } + public static Conaco getConaco(Context context) { EhApplication application = (EhApplication) context.getApplicationContext(); return application.mConaco; diff --git a/app/src/main/java/com/hippo/ehviewer/client/Cancellable.java b/app/src/main/java/com/hippo/ehviewer/client/CanceledException.java similarity index 84% rename from app/src/main/java/com/hippo/ehviewer/client/Cancellable.java rename to app/src/main/java/com/hippo/ehviewer/client/CanceledException.java index 581aa02e4..48fba22fa 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/Cancellable.java +++ b/app/src/main/java/com/hippo/ehviewer/client/CanceledException.java @@ -16,7 +16,9 @@ package com.hippo.ehviewer.client; -public interface Cancellable { +public class CanceledException extends EhException { - void cancel(); + public CanceledException() { + super("CANCELED"); + } } 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 71246a860..d856f45e0 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/EhClient.java +++ b/app/src/main/java/com/hippo/ehviewer/client/EhClient.java @@ -19,510 +19,240 @@ package com.hippo.ehviewer.client; import android.os.AsyncTask; import android.os.Process; -import com.hippo.ehviewer.client.data.GalleryDetail; -import com.hippo.ehviewer.client.data.GalleryInfo; -import com.hippo.ehviewer.client.data.PreviewSet; -import com.hippo.ehviewer.network.EhOkHttpClient; -import com.hippo.network.ResponseCodeException; +import com.hippo.ehviewer.network.EhHttpRequest; +import com.hippo.httpclient.HttpClient; 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; - -import java.util.List; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; -// TODO Make request cancle public final class EhClient { - private static final String TAG = EhClient.class.getSimpleName(); + public static final String TAG = EhClient.class.getSimpleName(); - public static final MediaType JSON = MediaType.parse("application/json"); + /** + * Sign in + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
paraminfo
usernamethe username
passwordthe password
listenerthe listener for callback
+ */ + public static final int METHOD_SIGN_IN = 0; - public static final int SOURCE_G = 0x0; - public static final int SOURCE_EX = 0x1; - public static final int SOURCE_LOFI = 0x2; + /** + * Get gallery list + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
paraminfo
urlthe url to get gallery list
sourcethe source, one of {@link EhUrl#SOURCE_G}, + * {@link EhUrl#SOURCE_EX} and {@link EhUrl#SOURCE_LOFI}
listenerthe listener for callback
+ */ + public static final int METHOD_GET_GALLERY_LIST = 1; - public static final String API_G = "http://g.e-hentai.org/api.php"; - public static final String API_EX = "http://exhentai.org/api.php"; - public static final long APIUID = 1363542; - public static final String APIKEY = "f4b5407ab1727b9d08d7"; + /** + * Get popular + * + * + * + * + * + * + * + * + * + * + *
paraminfo
listenerthe listener for callback
+ */ + public static final int METHOD_GET_POPULAR = 2; - 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"; + /** + * Get gallery detail + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
paraminfo
urlthe url to get gallery detail
sourcethe source, one of {@link EhUrl#SOURCE_G}, + * {@link EhUrl#SOURCE_EX} and {@link EhUrl#SOURCE_LOFI}
listenerthe listener for callback
+ */ + public static final int METHOD_GET_GALLERY_DETAIL = 3; - public static final String HOST_G = "G.E-Hentai"; - public static final String HOST_EX = "ExHentai"; - public static final String HOST_LOFI = "Lofi.E-Hentai"; - - public static final String HEADER_G = "http://g.e-hentai.org/"; - public static final String HEADER_EX = "http://exhentai.org/"; - public static final String HEADER_LOFI = "http://lofi.e-hentai.org/"; - - 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"; + /** + * Get gallery preview set + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + * + *
paraminfo
urlthe url to get gallery preview set
sourcethe source, one of {@link EhUrl#SOURCE_G}, + * {@link EhUrl#SOURCE_EX} and {@link EhUrl#SOURCE_LOFI}
listenerthe listener for callback
+ */ + public static final int METHOD_GET_PREVIEW_SET = 4; private final ThreadPoolExecutor mRequestThreadPool; - private final EhOkHttpClient mHttpClient; + private final HttpClient mHttpClient; - private static final EhClient sInstance; - - static { - sInstance = new EhClient(); - } - - public static EhClient getInstance() { - return sInstance; - } - - private EhClient() { + public EhClient(HttpClient httpClient) { int poolSize = 3; BlockingQueue requestWorkQueue = new LinkedBlockingQueue<>(); ThreadFactory threadFactory = new PriorityThreadFactory(TAG, Process.THREAD_PRIORITY_BACKGROUND); mRequestThreadPool = new ThreadPoolExecutor(poolSize, poolSize, 1L, TimeUnit.SECONDS, requestWorkQueue, threadFactory); - - mHttpClient = EhOkHttpClient.getInstance(); + mHttpClient = httpClient; } - public static String getReadableHost(int source) { - switch (source) { - default: - case SOURCE_G: - return HOST_G; - case SOURCE_EX: - return HOST_EX; - case SOURCE_LOFI: - return HOST_LOFI; + public void execute(EhRequest request) { + if (!request.isCanceled()) { + Task task = new Task(request.method, request.ehListener, request.ehConfig); + task.executeOnExecutor(mRequestThreadPool, request.args); + request.task = task; + } else { + request.ehListener.onCanceled(); } } - public static String getUrlHeader(int source) { - switch (source) { - default: - case SOURCE_G: - return HEADER_G; - case SOURCE_EX: - return HEADER_EX; - case SOURCE_LOFI: - return HEADER_LOFI; - } + public static abstract class EhListener { + + public abstract void onSuccess(E result); + + public abstract void onFailure(Exception e); + + public abstract void onCanceled(); } - /** - * Get gellary detail url in target source - */ - public static String getDetailUrl(int source, int gid, String token, int pageIndex) { - StringBuilder sb = new StringBuilder(getUrlHeader(source)); - sb.append("g/").append(gid).append('/').append(token).append('/'); - if (pageIndex > 0) { - sb.append("?p=").append(pageIndex); - } + class Task extends AsyncTask { - return sb.toString(); - } + private int mMethod; + private EhListener mListener; + private EhHttpRequest mEhHttpRequest; - public interface SimpleListener { - void onFailure(Exception e); - } + private boolean mStop; - private void doBgJob(BgJobHelper bjh) { - new AsyncTask() { - @Override - protected BgJobHelper doInBackground(BgJobHelper... params) { - BgJobHelper bjh = params[0]; - bjh.doInBackground(); - return bjh; - } - - @Override - protected void onPostExecute(BgJobHelper bjh) { - bjh.onPostExecute(); - } - }.executeOnExecutor(mRequestThreadPool, bjh); - } - - private interface BgJobHelper { - void doInBackground(); - - void onPostExecute(); - } - - private abstract class SimpleBgJobHelper implements BgJobHelper { - - private SimpleListener mListener; - private Exception mException; - - public SimpleBgJobHelper(SimpleListener listener) { + public Task(int method, EhListener listener, EhConfig ehConfig) { + mMethod = method; mListener = listener; + mEhHttpRequest = new EhHttpRequest(); + mEhHttpRequest.setEhConfig(ehConfig); } - @Override - public void doInBackground() { - try { - doBgJob(); - } catch (Exception e) { - mException = e; - } - } + public void stop() { + if (!mStop) { + mStop = true; - @Override - public void onPostExecute() { - if (mListener != null) { - if (mException == null) { - doSuccessCallback(); - } else { - mListener.onFailure(mException); + Status status = getStatus(); + if (status == Status.PENDING) { + cancel(false); + + // If it is pending, onPostExecute will not be called, + // need to call mListener.onCanceled here + mListener.onCanceled(); + + // Clear + mEhHttpRequest = null; + mListener = null; + } else if (status == Status.FINISHED) { + mEhHttpRequest.cancel(); } } } - public abstract void doBgJob() throws Exception; - - public abstract void doSuccessCallback(); - } - - 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 { - Request request = new Request.Builder() - .url(url) - .build(); - Response response = mHttpClient.newCall(request).execute(); - - checkResponse(response); - - GalleryListParser parser = new GalleryListParser(); - parser.parse(response.body().string(), source); - return new Object[]{parser.giList, parser.pageNum}; - } - - public abstract static class OnGetGalleryListListener implements SimpleListener { - public abstract void onSuccess(List glList, int pageNum); - } - - private final class GetGalleryListHelper extends SimpleBgJobHelper { - - private int mSource; - private String mUrl; - private OnGetGalleryListListener mListener; - - private List mGlList; - private int mPageNum; - - public GetGalleryListHelper(int source, String url, OnGetGalleryListListener listener) { - super(listener); - mSource = source; - mUrl = url; - mListener = listener; - } - @Override - public void doBgJob() throws Exception { - Object[] objs = doGetGalleryList(mSource, mUrl); - mGlList = (List) objs[0]; - mPageNum = (int) objs[1]; + protected Object doInBackground(Object... params) { + try { + switch (mMethod) { + case METHOD_SIGN_IN: + return EhEngine.signIn(mHttpClient, mEhHttpRequest, (String) params[0], (String) params[1]); + case METHOD_GET_GALLERY_LIST: + return EhEngine.getGalleryList(mHttpClient, mEhHttpRequest, (String) params[0], (Integer) params[1]); + case METHOD_GET_POPULAR: + return EhEngine.getPopular(mHttpClient, mEhHttpRequest); + case METHOD_GET_GALLERY_DETAIL: + return EhEngine.getGalleryDetail(mHttpClient, mEhHttpRequest, (String) params[0], (Integer) params[1]); + case METHOD_GET_PREVIEW_SET: + return EhEngine.getPreviewSet(mHttpClient, mEhHttpRequest, (String) params[0], (Integer) params[1]); + default: + return new IllegalStateException("Can't detect method"); + } + } catch (Exception e) { + return e; + } } + @SuppressWarnings("unchecked") @Override - public void doSuccessCallback() { - mListener.onSuccess(mGlList, mPageNum); + protected void onPostExecute(Object result) { + if (result instanceof CanceledException) { + mListener.onCanceled(); + } else if (result instanceof Exception) { + mListener.onFailure((Exception) result); + } else { + mListener.onSuccess(result); + } + + // Clear + mEhHttpRequest = null; + mListener = null; } } - - /** - * Get gallery list - * - * @param source the source, one of {@link #SOURCE_G}, {@link #SOURCE_EX} and - * {@link #SOURCE_LOFI} - * @param url the url to get gallery list - * @param listener the listener for callback - */ - public void getGalleryList(int source, String url, OnGetGalleryListListener listener) { - 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()); - - Request request = new Request.Builder() - .url(API_EHVIEWER) - .post(body) - .build(); - Response response = mHttpClient.newCall(request).execute(); - - checkResponse(response); - - PopularParser parser = new PopularParser(); - parser.parse(response.body().string()); - return new Object[]{parser.galleryInfoList, parser.timeStamp}; - } - - public abstract static class OnGetPopularListener implements SimpleListener { - public abstract void onSuccess(List giList, long timeStamp); - } - - private final class GetPopularHelper extends SimpleBgJobHelper { - - private OnGetPopularListener mListener; - - private List mGiList; - private long mTimeStamp; - - public GetPopularHelper(OnGetPopularListener listener) { - super(listener); - mListener = listener; - } - - @Override - public void doBgJob() throws Exception { - Object[] objs = doGetPopular(); - mGiList = (List) objs[0]; - mTimeStamp = (Long) objs[1]; - } - - @Override - public void doSuccessCallback() { - mListener.onSuccess(mGiList, mTimeStamp); - } - } - - /** - * Get popular gallery list - * - * @param listener the listener for callback - */ - 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)); - } - - private GalleryDetail doGetGalleryDetail(int source, String url) throws Exception { - Request request = new Request.Builder() - .url(url) - .build(); - Response response = mHttpClient.newCall(request).execute(); - - checkResponse(response); - - GalleryDetailParser parser = new GalleryDetailParser(); - parser.parse(response.body().string(), GalleryDetailParser.REQUEST_DETAIL | - GalleryDetailParser.REQUEST_TAG | - GalleryDetailParser.REQUEST_PREVIEW_INFO | - GalleryDetailParser.REQUEST_PREVIEW | - GalleryDetailParser.REQUEST_COMMENT, - source); - - GalleryDetail gd = new GalleryDetail(); - gd.gid = parser.gid; - gd.token = parser.token; - gd.thumb = parser.thumb; - gd.title = parser.title; - gd.titleJpn = parser.titleJpn; - gd.category = parser.category; - gd.uploader = parser.uploader; - gd.torrentCount = parser.torrentCount; - gd.torrentUrl = parser.torrentUrl; - gd.posted = parser.posted; - gd.parent = parser.parent; - gd.visible = parser.visible; - gd.language = parser.language; - gd.size = parser.size; - gd.resize = parser.resize; - gd.pageCount = parser.pageCount; - gd.favoredTimes = parser.favoredTimes; - gd.isFavored = parser.isFavored; - gd.rating = parser.rating; - gd.ratedTimes = parser.ratedTimes; - gd.tags = parser.tags; - gd.comments = parser.comments; - gd.previewPageCount = parser.previewPageCount; - gd.previewSetArray = new PreviewSet[gd.previewPageCount]; - gd.previewSetArray[0] = parser.previewSet; - gd.previewSetArray[0].setStartIndex(0); - gd.previewSetArray[0].setGid(gd.gid); - - return gd; - } - - public abstract static class OnGetGalleryDetailListener implements SimpleListener { - public abstract void onSuccess(GalleryDetail galleryDetail); - } - - private final class GetGalleryDetailHelper extends SimpleBgJobHelper { - - private int mSource; - private String mUrl; - private OnGetGalleryDetailListener mListener; - - private GalleryDetail mGalleryDetail; - - public GetGalleryDetailHelper(int source, String url, OnGetGalleryDetailListener listener) { - super(listener); - mSource = source; - mUrl = url; - mListener = listener; - } - - @Override - public void doBgJob() throws Exception { - mGalleryDetail = doGetGalleryDetail(mSource, mUrl); - } - - @Override - public void doSuccessCallback() { - mListener.onSuccess(mGalleryDetail); - } - } - - /** - * Get gallery detail - */ - public void getGalleryDetail(int source, String url, OnGetGalleryDetailListener listener) { - doBgJob(new GetGalleryDetailHelper(source, url, listener)); - } - - - public abstract static class OnGetPreviewSetListener implements SimpleListener { - public abstract void onSuccess(PreviewSet previewSet); - } - - private PreviewSet doGetPreviewSet(int source, String url) throws Exception { - Request request = new Request.Builder() - .url(url) - .build(); - Response response = mHttpClient.newCall(request).execute(); - - checkResponse(response); - - GalleryDetailParser parser = new GalleryDetailParser(); - parser.parse(response.body().string(), GalleryDetailParser.REQUEST_PREVIEW, - source); - - return parser.previewSet; - } - - private final class GetPreviewSetHelper extends SimpleBgJobHelper { - - private int mSource; - private String mUrl; - private OnGetPreviewSetListener mListener; - - private PreviewSet mPreviewSet; - - public GetPreviewSetHelper(int source, String url, OnGetPreviewSetListener listener) { - super(listener); - mSource = source; - mUrl = url; - mListener = listener; - } - - @Override - public void doBgJob() throws Exception { - mPreviewSet = doGetPreviewSet(mSource, mUrl); - } - - @Override - public void doSuccessCallback() { - mListener.onSuccess(mPreviewSet); - } - } - - /** - * Get gallery preview set - */ - public void getPreviewSet(int source, String url, OnGetPreviewSetListener listener) { - doBgJob(new GetPreviewSetHelper(source, url, listener)); - } } diff --git a/app/src/main/java/com/hippo/ehviewer/client/EhConfig.java b/app/src/main/java/com/hippo/ehviewer/client/EhConfig.java new file mode 100644 index 000000000..20fa275dc --- /dev/null +++ b/app/src/main/java/com/hippo/ehviewer/client/EhConfig.java @@ -0,0 +1,655 @@ +/* + * Copyright 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 + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hippo.ehviewer.client; + +import android.text.TextUtils; + +import com.hippo.httpclient.Cookie; + +/** + * Some configurable stuff about EH. It ends up cookie. + */ +public class EhConfig implements Cloneable { + + /** + * The Cookie key of uconfig + */ + public static final String KEY_UCONFIG = "uconfig"; + + /** + * The key of load images through the Hentai@Home Network + */ + private static final String KEY_LOAD_FROM_HAH = "uh"; + /** + * The key of scale images width + */ + private static final String KEY_SCALE_WIDTH = "rx"; + /** + * The key of scale images height + */ + private static final String KEY_SCALE_HEIGHT = "ry"; + /** + * The key of the behavior for downloading archiver + */ + private static final String KEY_ARCHIVER_DOWNLOAD = "ar"; + /** + * The key of display mode would you like to use on the front and search pages + */ + private static final String KEY_LAYOUT_MODE = "dm"; + /** + * The key of categories would you like to view as default on the front page + */ + private static final String KEY_DEFAULT_CATEGORIES = "cats"; + /** + * The key of exclude certain namespaces from a default tag search + */ + private static final String KEY_EXCLUDED_NAMESPACES = "xns"; + /** + * The key of hide galleries in certain languages from the gallery list and searches + */ + private static final String KEY_EXCLUDED_LANGUAGES = "xl"; + /** + * The key of how many results would you like per page for the index/search page and torrent search pages + */ + private static final String KEY_RESULT_COUNT = "rc"; + /** + * The key of mouse-over thumb + */ + private static final String KEY_MOUSE_OVER = "tl"; + /** + * The key of preview size + */ + private static final String KEY_PREVIEW_SIZE = "ts"; + /** + * The key of preview row per page + */ + private static final String KEY_PREVIEW_ROW = "tr"; + /** + * The key of sort order for gallery comments + */ + private static final String KEY_COMMENTS_SORT = "cs"; + /** + * The key of show gallery comment votes + */ + private static final String KEY_COMMENTS_VOTES = "sc"; + /** + * The key of sort order for gallery tags + */ + private static final String KEY_TAGS_SORT = "to"; + /** + * The key of show gallery page numbers + */ + private static final String KEY_SHOW_GALLERY_INDEX = "pn"; + /** + * The key of the IP:Port of a proxy-enabled Hentai@Home Client + * to load all images + */ + private static final String KEY_HAH_CLIENT_IP_PORT = "hp"; + /** + * The key of the passkey of a proxy-enabled Hentai@Home Client + * to load all images + */ + private static final String KEY_HAH_CLIENT_PASSKEY = "hk"; + /** + * The key of enable Tag Flagging + */ + private static final String KEY_ENABLE_TAG_FLAGGING = "tf"; + /** + * The key of always display the original images instead of the resampled versions + */ + private static final String KEY_ALWAYS_ORIGINAL = "oi"; + /** + * The key of enable the multi-Page Viewer + */ + private static final String KEY_MULTI_PAGE = "qb"; + /** + * The key of multi-Page Viewer Display Style + */ + private static final String KEY_MULTI_PAGE_STYLE = "ms"; + /** + * The key of multi-Page Viewer Thumbnail Pane + */ + private static final String KEY_MULTI_PAGE_THUMB = "mt"; + + /** + * The Cookie key of lofi resolution + */ + public static final String KEY_LOFI_RESOLUTION = "xres"; + + /** + * The Cookie key of show warning + */ + public static final String KEY_CONTENT_WARNING = "nw"; + + /** + * load images through the Hentai@Home Network + */ + public static final String LOAD_FROM_HAH_YES = "y"; + /** + * do not load images through the Hentai@Home Network + */ + public static final String LOAD_FROM_HAH_NO = "n"; + + /** + * Manual Accept, Manual Start + */ + public static final String ARCHIVER_DOWNLOAD_MAMS = "0"; + /** + * >Manual Accept, Auto Start + */ + public static final String ARCHIVER_DOWNLOAD_AAMS = "1"; + /** + * Auto Accept, Manual Start + */ + public static final String ARCHIVER_DOWNLOAD_MAAS = "2"; + /** + * Auto Accept, Auto Start + */ + public static final String ARCHIVER_DOWNLOAD_AAAS = "3"; + + /** + * List View on the front and search pages + */ + public static final String LAYOUT_MODE_LIST = "l"; + /** + * Thumbnail View on the front and search pages + */ + public static final String LAYOUT_MODE_THUMB = "t"; + + public static final int MISC = 0x1; + public static final int DOUJINSHI = 0x2; + public static final int MANGA = 0x4; + public static final int ARTIST_CG = 0x8; + public static final int GAME_CG = 0x10; + public static final int IMAGE_SET = 0x20; + public static final int COSPLAY = 0x40; + public static final int ASIAN_PORN = 0x80; + public static final int NON_H = 0x100; + public static final int WESTERN = 0x200; + + public static final int NAMESPACES_RECLASS = 0x1; + public static final int NAMESPACES_LANGUAGE = 0x2; + public static final int NAMESPACES_PARODY = 0x4; + public static final int NAMESPACES_CHARACTER = 0x8; + public static final int NAMESPACES_GROUP = 0x10; + public static final int NAMESPACES_ARTIST = 0x20; + public static final int NAMESPACES_MALE = 0x40; + public static final int NAMESPACES_FEMALE = 0x80; + public static final int JAPANESE_TRANSLATED = 1024; + public static final int JAPANESE_REWRITE = 2048; + public static final int ENGLISH_ORIGINAL = 1; + public static final int ENGLISH_TRANSLATED = 1025; + public static final int ENGLISH_REWRITE = 2049; + public static final int CHINESE_ORIGINAL = 10; + public static final int CHINESE_TRANSLATED = 1034; + public static final int CHINESE_REWRITE = 2058; + public static final int DUTCH_ORIGINAL = 20; + public static final int DUTCH_TRANSLATED = 1044; + public static final int DUTCH_REWRITE = 2068; + public static final int FRENCH_ORIGINAL = 30; + public static final int FRENCH_TRANSLATED = 1054; + public static final int FRENCH_REWRITE = 2078; + public static final int GERMAN_ORIGINAL = 40; + public static final int GERMAN_TRANSLATED = 1064; + public static final int GERMAN_REWRITE = 2088; + public static final int HUNGARIAN_ORIGINAL = 50; + public static final int HUNGARIAN_TRANSLATED = 1074; + public static final int HUNGARIAN_REWRITE = 2098; + public static final int ITALIAN_ORIGINAL = 60; + public static final int ITALIAN_TRANSLATED = 1084; + public static final int ITALIAN_REWRITE = 2108; + public static final int KOREAN_ORIGINAL = 70; + public static final int KOREAN_TRANSLATED = 1094; + public static final int KOREAN_REWRITE = 2118; + public static final int POLISH_ORIGINAL = 80; + public static final int POLISH_TRANSLATED = 1104; + public static final int POLISH_REWRITE = 2128; + public static final int PORTUGUESE_ORIGINAL = 90; + public static final int PORTUGUESE_TRANSLATED = 1114; + public static final int PORTUGUESE_REWRITE = 2138; + public static final int RUSSIAN_ORIGINAL = 100; + public static final int RUSSIAN_TRANSLATED = 1124; + public static final int RUSSIAN_REWRITE = 2148; + public static final int SPANISH_ORIGINAL = 110; + public static final int SPANISH_TRANSLATED = 1134; + public static final int SPANISH_REWRITE = 2158; + public static final int THAI_ORIGINAL = 120; + public static final int THAI_TRANSLATED = 1144; + public static final int THAI_REWRITE = 2168; + public static final int VIETNAMESE_ORIGINAL = 130; + public static final int VIETNAMESE_TRANSLATED = 1154; + public static final int VIETNAMESE_REWRITE = 2178; + public static final int NA_ORIGINAL = 254; + public static final int NA_TRANSLATED = 1278; + public static final int NA_REWRITE = 2302; + public static final int OTHER_ORIGINAL = 255; + public static final int OTHER_TRANSLATED = 1279; + public static final int OTHER_REWRITE = 2303; + + /** + * 25 results per page for the index/search page and torrent search pages + */ + public static final String RESULT_COUNT_25 = "0"; + /** + * 50 results per page for the index/search page and torrent search pages + */ + public static final String RESULT_COUNT_50 = "1"; + /** + * 100 results per page for the index/search page and torrent search pages + */ + public static final String RESULT_COUNT_100 = "2"; + /** + * 200 results per page for the index/search page and torrent search pages + */ + public static final String RESULT_COUNT_200 = "3"; + + /** + * On mouse-over + */ + public static final String MOUSE_OVER_YES = "m"; + /** + * On page load + */ + public static final String MOUSE_OVER_NO = "p"; + + /** + * Preview normal size + */ + public static final String PREVIEW_SIZE_NORMAL = "m"; + /** + * Preview large size + */ + public static final String PREVIEW_SIZE_LARGE = "l"; + + /** + * 4 row preview per page + */ + public static final String PREVIEW_ROW_4 = "2"; + /** + * 10 row preview per page + */ + public static final String PREVIEW_ROW_10 = "5"; + /** + * 20 row preview per page + */ + public static final String PREVIEW_ROW_20 = "10"; + /** + * 40 row preview per page + */ + public static final String PREVIEW_ROW_40 = "20"; + + /** + * Oldest comments first + */ + public static final String COMMENTS_SORT_OLDEST_FIRST = "a"; + /** + * Recent comments first + */ + public static final String COMMENTS_SORT_RECENT_FIRST = "d"; + /** + * By highest score + */ + public static final String COMMENTS_SORT_HIGHEST_SCORE_FIRST = "s"; + + /** + * Show gallery comment votes On score hover or click + */ + public static final String COMMENTS_VOTES_POP = "0"; + /** + * Always show gallery comment votes + */ + public static final String COMMENTS_VOTES_ALWAYS = "1"; + + /** + * Sort order for gallery tags alphabetically + */ + public static final String TAGS_SORT_ALPHABETICAL = "a"; + /** + * Sort order for gallery tags by tag power + */ + public static final String TAGS_SORT_POWER = "p"; + + /** + * Show gallery page numbers + */ + public static final String SHOW_GALLERY_INDEX_YES = "1"; + /** + * Do not show gallery page numbers + */ + public static final String SHOW_GALLERY_INDEX_NO = "0"; + + /** + * Enable Tag Flagging + */ + public static final String ENABLE_TAG_FLAGGING_YES = "y"; + /** + * Do not enable Tag Flagging + */ + public static final String ENABLE_TAG_FLAGGING_NO = "n"; + + /** + * Always display the original images + */ + public static final String ALWAYS_ORIGINAL_YES = "y"; + /** + * Do not Always display the original images + */ + public static final String ALWAYS_ORIGINAL_NO = "n"; + + /** + * Enable the Multi-Page Viewe + */ + public static final String MULTI_PAGE_YES = "y"; + /** + * Do not enable the Multi-Page Viewe + */ + public static final String MULTI_PAGE_NO = "n"; + + /** + * Align left, only scale if image is larger than browser width + */ + public static final String MULTI_PAGE_STYLE_N = "n"; + /** + * Align center, only scale if image is larger than browser width + */ + public static final String MULTI_PAGE_STYLE_C = "c"; + /** + * Align center, Always scale images to fit browser width + */ + public static final String MULTI_PAGE_STYLE_Y = "y"; + + /** + * Show Multi-Page Viewer Thumbnail Pane + */ + public static final String MULTI_PAGE_THUMB_SHOW = "n"; + /** + * Hide Multi-Page Viewer Thumbnail Pane + */ + public static final String MULTI_PAGE_THUMB_HIDE = "y"; + + /** + * 460x for lofi resolution + */ + public static final String LOFI_RESOLUTION_460X = "1"; + + /** + * 780X for lofi resolution + */ + public static final String LOFI_RESOLUTION_780X = "2"; + + /** + * 980X for lofi resolution + */ + public static final String LOFI_RESOLUTION_980X = "3"; + + /** + * show warning + */ + private static final String CONTENT_WARNING_SHOW = "0"; + + /** + * not show warning + */ + private static final String CONTENT_WARNING_NOT_SHOW = "1"; + + /** + * Load images through the Hentai@Home Network
+ * key: {@link #KEY_LOAD_FROM_HAH}
+ * value: {@link #LOAD_FROM_HAH_YES}, {@link #LOAD_FROM_HAH_NO} + */ + public String loadFromHAH = LOAD_FROM_HAH_YES; + + /** + * Scale width
+ * key: {@link #KEY_SCALE_WIDTH}
+ * value: 0 for no limit + */ + public int scaleWidth = 0; + + /** + * Scale height
+ * key: {@link #KEY_SCALE_HEIGHT}
+ * value: 0 for no limit + */ + public int scaleHeight = 0; + + /** + * The default behavior for downloading an archiver
+ * key: {@link #KEY_ARCHIVER_DOWNLOAD}
+ * value: {@link #ARCHIVER_DOWNLOAD_MAMS}, {@link #ARCHIVER_DOWNLOAD_AAMS}, + * {@link #ARCHIVER_DOWNLOAD_MAAS}, {@link #ARCHIVER_DOWNLOAD_AAAS} + */ + public String archiverDownload = ARCHIVER_DOWNLOAD_MAMS; + + /** + * Display mode used on the front and search pages
+ * false for list, true for thumb
+ * key: {@link #KEY_LAYOUT_MODE}
+ * value: {@link #LAYOUT_MODE_LIST}, {@link #LAYOUT_MODE_THUMB} + */ + public String layoutMode = LAYOUT_MODE_LIST; + + /** + * Default categories on the front page
+ * key: {@link #KEY_DEFAULT_CATEGORIES}
+ * value: the value of categories, for multiple use & operation, + * 0 for none + */ + public int defaultCategories = 0; + + /** + * Certain namespaces excluded from a default tag search
+ * key: {@link #KEY_EXCLUDED_NAMESPACES}
+ * value: the value of namespaces, for multiple use & operation, + * 0 for none + */ + public int excludedNamespaces = 0; + + /** + * Certain languages excluded from list and searches
+ * key: {@link #KEY_EXCLUDED_LANGUAGES}
+ * value: {@link #JAPANESE_TRANSLATED}, {@link #JAPANESE_REWRITE} ... + * For multiple languages, use x to combine them, like 1x1024x2048 + */ + public String excludedLanguages = ""; + + /** + * How many results would you like per page for the index/search page + * and torrent search pages
+ * key: {@link #KEY_RESULT_COUNT}
+ * value: {@link #RESULT_COUNT_25}, {@link #RESULT_COUNT_50}, + * {@link #RESULT_COUNT_100}, {@link #RESULT_COUNT_200}
+ * Require Hath Perk:Paging Enlargement + */ + public String resultCount = RESULT_COUNT_25; + + /** + * mouse-over thumb
+ * key: {@link #KEY_MOUSE_OVER}
+ * value: {@link #MOUSE_OVER_YES}, {@link #MOUSE_OVER_NO} + */ + public String mouseOver = MOUSE_OVER_YES; + + /** + * Default preview mode
+ * key: {@link #KEY_PREVIEW_SIZE}
+ * value: {@link #PREVIEW_SIZE_NORMAL}, {@link #PREVIEW_SIZE_LARGE} + */ + public String previewSize = PREVIEW_SIZE_NORMAL; + + /** + * Preview row
+ * key: {@link #KEY_PREVIEW_ROW}
+ * value: {@link #PREVIEW_ROW_4}, {@link #PREVIEW_ROW_10}, + * {@link #PREVIEW_ROW_20}, {@link #PREVIEW_ROW_40} + */ + public String previewRow = PREVIEW_ROW_4; + + /** + * Sort order for gallery comments
+ * key: {@link #KEY_COMMENTS_SORT}
+ * value: {@link #COMMENTS_SORT_OLDEST_FIRST}, {@link #COMMENTS_SORT_RECENT_FIRST}, + * {@link #COMMENTS_SORT_HIGHEST_SCORE_FIRST} + */ + public String commentSort = COMMENTS_SORT_OLDEST_FIRST; + + /** + * Show gallery comment votes mode
+ * key: {@link #KEY_COMMENTS_VOTES}
+ * value: {@link #COMMENTS_VOTES_POP}, {@link #COMMENTS_VOTES_ALWAYS} + */ + public String commentVotes = COMMENTS_VOTES_POP; + + + /** + * Sort order for gallery tags
+ * key: {@link #KEY_TAGS_SORT}
+ * value: {@link #TAGS_SORT_ALPHABETICAL}, {@link #TAGS_SORT_POWER} + */ + public String tagSort = TAGS_SORT_ALPHABETICAL; + + /** + * Show gallery page numbers
+ * key: {@link #KEY_SHOW_GALLERY_INDEX}
+ * value: {@link #SHOW_GALLERY_INDEX_YES}, {@link #SHOW_GALLERY_INDEX_NO} + */ + public String showGalleryIndex = SHOW_GALLERY_INDEX_YES; + + /** + * The IP of a proxy-enabled Hentai@Home Client + * to load all images
+ * key: {@link #KEY_HAH_CLIENT_IP_PORT}
+ */ + public String hahClientIp = ""; + + /** + * The PORT of a proxy-enabled Hentai@Home Client + * to load all images
+ * key: {@link #KEY_HAH_CLIENT_IP_PORT}
+ */ + public int hahClientPort = -1; + + /** + * The passkey of a proxy-enabled Hentai@Home Client + * to load all images
+ * key: {@link #KEY_HAH_CLIENT_PASSKEY}
+ */ + public String hahClientPasskey = ""; + + /** + * Enable tag flagging + * key: {@link #KEY_ENABLE_TAG_FLAGGING}
+ * value: {@link #ENABLE_TAG_FLAGGING_YES}, {@link #ENABLE_TAG_FLAGGING_NO}
+ * Bronze Star or Hath Perk: Tag Flagging Required + */ + public String enableTagFlagging = ENABLE_TAG_FLAGGING_NO; + + /** + * Always display the original images instead of the resampled versions
+ * key: {@link #KEY_ALWAYS_ORIGINAL}
+ * value: {@link #ALWAYS_ORIGINAL_YES}, {@link #ALWAYS_ORIGINAL_NO}
+ * Silver Star or Hath Perk: Source Nexus Required + */ + public String alwaysOriginal = ALWAYS_ORIGINAL_NO; + + /** + * Enable the multi-Page Viewer
+ * key: {@link #KEY_MULTI_PAGE}
+ * value: {@link #MULTI_PAGE_YES}, {@link #MULTI_PAGE_NO}
+ * Gold Star or Hath Perk: Multi-Page Viewer Required + */ + public String multiPage = MULTI_PAGE_NO; + + /** + * Multi-Page Viewer Display Style
+ * key: {@link #KEY_MULTI_PAGE_STYLE}
+ * value: {@link #MULTI_PAGE_STYLE_N}, {@link #MULTI_PAGE_STYLE_C}, + * {@link #MULTI_PAGE_STYLE_Y}
+ * Gold Star or Hath Perk: Multi-Page Viewer Required + */ + public String multiPageStyle = MULTI_PAGE_STYLE_N; + + /** + * Multi-Page Viewer Thumbnail Pane
+ * key: {@link #KEY_MULTI_PAGE_THUMB}
+ * value: {@link #MULTI_PAGE_THUMB_SHOW}, {@link #MULTI_PAGE_THUMB_HIDE}
+ * Gold Star or Hath Perk: Multi-Page Viewer Required + */ + public String multiPageThumb = MULTI_PAGE_THUMB_SHOW; + + /** + * Lofi resolution + * key: {@link #KEY_LOFI_RESOLUTION}
+ * value: {@link #LOFI_RESOLUTION_460X}, {@link #LOFI_RESOLUTION_780X}, + * {@link #LOFI_RESOLUTION_980X} + */ + public String lofiResolution = LOFI_RESOLUTION_980X; + + /** + * Show content warning + * key: {@link #KEY_CONTENT_WARNING}
+ * value: {@link #CONTENT_WARNING_SHOW}, {@link #CONTENT_WARNING_NOT_SHOW} + */ + public String contentWarning = CONTENT_WARNING_NOT_SHOW; + + private String mUconfig; + + private boolean mDirty = true; + + public void setDirty() { + mDirty = true; + } + + private void updateUconfig() { + String hahClientIpPort = (TextUtils.isEmpty(hahClientIp) || hahClientPort == -1) ? + "" : hahClientIp + "%3A" + hahClientPort; + mUconfig = KEY_LOAD_FROM_HAH + "_" + loadFromHAH + "-" + + KEY_SCALE_WIDTH + "_" + scaleWidth + "-" + + KEY_SCALE_HEIGHT + "_" + scaleHeight + "-" + + KEY_ARCHIVER_DOWNLOAD + "_" + archiverDownload + "-" + + KEY_LAYOUT_MODE + "_" + layoutMode + "-" + + KEY_DEFAULT_CATEGORIES + "_" + defaultCategories + "-" + + KEY_EXCLUDED_NAMESPACES + "_" + excludedNamespaces + "-" + + KEY_EXCLUDED_LANGUAGES + "_" + excludedLanguages + "-" + + KEY_RESULT_COUNT + "_" + resultCount + "-" + + KEY_MOUSE_OVER + "_" + mouseOver + "-" + + KEY_PREVIEW_SIZE + "_" + previewSize + "-" + + KEY_PREVIEW_ROW + "_" + previewRow + "-" + + KEY_COMMENTS_SORT + "_" + commentSort + "-" + + KEY_COMMENTS_VOTES + "_" + commentVotes + "-" + + KEY_TAGS_SORT + "_" + tagSort + "-" + + KEY_SHOW_GALLERY_INDEX + "_" + showGalleryIndex + "-" + + KEY_HAH_CLIENT_IP_PORT + "_" + hahClientIpPort + "-" + + KEY_HAH_CLIENT_PASSKEY + "_" + hahClientPasskey + "-" + + KEY_ENABLE_TAG_FLAGGING + "_" + enableTagFlagging + "-" + + KEY_ALWAYS_ORIGINAL + "_" + alwaysOriginal + "-" + + KEY_MULTI_PAGE + "_" + multiPage + "-" + + KEY_MULTI_PAGE_STYLE + "_" + multiPageStyle + "-" + + KEY_MULTI_PAGE_THUMB + "_" + multiPageThumb; + } + + public void fillCookie(Cookie cookie) { + if (mDirty) { + mDirty = false; + updateUconfig(); + } + + cookie.put(KEY_UCONFIG, mUconfig); + cookie.put(KEY_LOFI_RESOLUTION, lofiResolution); + cookie.put(KEY_CONTENT_WARNING, contentWarning); + } +} diff --git a/app/src/main/java/com/hippo/ehviewer/client/EhEngine.java b/app/src/main/java/com/hippo/ehviewer/client/EhEngine.java new file mode 100644 index 000000000..884ee3e15 --- /dev/null +++ b/app/src/main/java/com/hippo/ehviewer/client/EhEngine.java @@ -0,0 +1,139 @@ +/* + * Copyright 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 + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hippo.ehviewer.client; + +import com.hippo.ehviewer.client.data.GalleryDetail; +import com.hippo.ehviewer.client.data.PreviewSet; +import com.hippo.httpclient.FormPoster; +import com.hippo.httpclient.HttpClient; +import com.hippo.httpclient.HttpRequest; +import com.hippo.httpclient.HttpResponse; +import com.hippo.httpclient.JsonPoster; + +import org.json.JSONObject; + +class EhEngine { + + private static final String SIGN_IN_URL = "http://forums.e-hentai.org/index.php?act=Login&CODE=01"; + public static final String API_EHVIEWER = "http://www.ehviewer.com/API"; + + public static String signIn(HttpClient httpClient, HttpRequest httpRequest, + String username, String password) throws Exception { + try { + FormPoster formPoster = new FormPoster(); + formPoster.addData("UserName", username) + .addData("PassWord", password) + .addData("submit", "Log me in") + .addData("CookieDate", "1") + .addData("temporary_https", "off"); + httpRequest.setUrl(SIGN_IN_URL); + httpRequest.setHttpImpl(formPoster); + HttpResponse response = httpClient.execute(httpRequest); + String body = response.getString(); + return SignInParser.parse(body); + } catch (Exception e) { + if (httpRequest.isCanceled()) { + throw new CanceledException(); + } else { + throw e; + } + } finally { + httpRequest.disconnect(); + } + } + + public static GalleryListParser.Result getGalleryList(HttpClient httpClient, + HttpRequest httpRequest, String url, int source) throws Exception { + try { + httpRequest.setUrl(url); + HttpResponse response = httpClient.execute(httpRequest); + String body = response.getString(); + return GalleryListParser.parse(body, source); + } catch (Exception e) { + if (httpRequest.isCanceled()) { + throw new CanceledException(); + } else { + throw e; + } + } finally { + httpRequest.disconnect(); + } + } + + public static PopularParser.Result getPopular(HttpClient httpClient, + HttpRequest httpRequest) throws Exception { + try { + final JSONObject json = new JSONObject(); + json.put("method", "popular"); + JsonPoster jsonPoster = new JsonPoster(json); + httpRequest.setUrl(API_EHVIEWER); + httpRequest.setHttpImpl(jsonPoster); + HttpResponse response = httpClient.execute(httpRequest); + String body = response.getString(); + return PopularParser.parse(body); + } catch (Exception e) { + if (httpRequest.isCanceled()) { + throw new CanceledException(); + } else { + throw e; + } + } finally { + httpRequest.disconnect(); + } + } + + public static GalleryDetail getGalleryDetail(HttpClient httpClient, + HttpRequest httpRequest, String url, int source) throws Exception { + try { + httpRequest.setUrl(url); + HttpResponse response = httpClient.execute(httpRequest); + String body = response.getString(); + return GalleryDetailParser.parse(body, source, + GalleryDetailParser.REQUEST_DETAIL | + GalleryDetailParser.REQUEST_TAG | + GalleryDetailParser.REQUEST_PREVIEW_INFO | + GalleryDetailParser.REQUEST_PREVIEW | + GalleryDetailParser.REQUEST_COMMENT); + } catch (Exception e) { + if (httpRequest.isCanceled()) { + throw new CanceledException(); + } else { + throw e; + } + } finally { + httpRequest.disconnect(); + } + } + + public static PreviewSet getPreviewSet(HttpClient httpClient, + HttpRequest httpRequest, String url, int source) throws Exception { + try { + httpRequest.setUrl(url); + HttpResponse response = httpClient.execute(httpRequest); + String body = response.getString(); + return GalleryDetailParser.parsePreview(body, source); + } catch (Exception e) { + if (httpRequest.isCanceled()) { + throw new CanceledException(); + } else { + throw e; + } + } finally { + httpRequest.disconnect(); + } + } +} diff --git a/app/src/main/java/com/hippo/ehviewer/client/EhRequest.java b/app/src/main/java/com/hippo/ehviewer/client/EhRequest.java new file mode 100644 index 000000000..56bced9d1 --- /dev/null +++ b/app/src/main/java/com/hippo/ehviewer/client/EhRequest.java @@ -0,0 +1,58 @@ +/* + * Copyright 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 + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hippo.ehviewer.client; + +public class EhRequest { + + int method; + Object[] args; + EhClient.EhListener ehListener; + EhConfig ehConfig; + + EhClient.Task task; + + private boolean mCancel = false; + + public void setMethod(int method) { + this.method = method; + } + + public void setArgs(Object... args) { + this.args = args; + } + + public void setEhConfig(EhConfig ehConfig) { + this.ehConfig = ehConfig; + } + + public void setEhListener(EhClient.EhListener ehListener) { + this.ehListener = ehListener; + } + + public void cancel() { + if (!mCancel) { + mCancel = true; + if (task != null) { + task.stop(); + } + } + } + + public boolean isCanceled() { + return mCancel; + } +} diff --git a/app/src/main/java/com/hippo/ehviewer/client/EhUrl.java b/app/src/main/java/com/hippo/ehviewer/client/EhUrl.java new file mode 100644 index 000000000..80fd5b2d4 --- /dev/null +++ b/app/src/main/java/com/hippo/ehviewer/client/EhUrl.java @@ -0,0 +1,70 @@ +/* + * Copyright 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 + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hippo.ehviewer.client; + +public class EhUrl { + + public static final int SOURCE_G = 0x0; + public static final int SOURCE_EX = 0x1; + public static final int SOURCE_LOFI = 0x2; + + public static final String HOST_G = "G.E-Hentai"; + public static final String HOST_EX = "ExHentai"; + public static final String HOST_LOFI = "Lofi.E-Hentai"; + + public static final String HEADER_G = "http://g.e-hentai.org/"; + public static final String HEADER_EX = "http://exhentai.org/"; + public static final String HEADER_LOFI = "http://lofi.e-hentai.org/"; + + public static String getReadableHost(int source) { + switch (source) { + default: + case SOURCE_G: + return HOST_G; + case SOURCE_EX: + return HOST_EX; + case SOURCE_LOFI: + return HOST_LOFI; + } + } + + public static String getUrlHeader(int source) { + switch (source) { + default: + case SOURCE_G: + return HEADER_G; + case SOURCE_EX: + return HEADER_EX; + case SOURCE_LOFI: + return HEADER_LOFI; + } + } + + /** + * Get gellary detail url in target source + */ + public static String getDetailUrl(int source, int gid, String token, int pageIndex) { + StringBuilder sb = new StringBuilder(getUrlHeader(source)); + sb.append("g/").append(gid).append('/').append(token).append('/'); + if (pageIndex > 0) { + sb.append("?p=").append(pageIndex); + } + + return sb.toString(); + } + +} diff --git a/app/src/main/java/com/hippo/ehviewer/client/GalleryDetailParser.java b/app/src/main/java/com/hippo/ehviewer/client/GalleryDetailParser.java index ce83e7a21..104869bf5 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/GalleryDetailParser.java +++ b/app/src/main/java/com/hippo/ehviewer/client/GalleryDetailParser.java @@ -17,12 +17,12 @@ package com.hippo.ehviewer.client; import com.hippo.ehviewer.client.data.Comment; +import com.hippo.ehviewer.client.data.GalleryDetail; import com.hippo.ehviewer.client.data.LargePreviewSet; import com.hippo.ehviewer.client.data.NormalPreviewSet; import com.hippo.ehviewer.client.data.PreviewSet; import com.hippo.ehviewer.client.data.TagGroup; import com.hippo.ehviewer.util.EhUtils; -import com.hippo.util.AssertUtils; import com.hippo.util.Utils; import java.text.DateFormat; @@ -31,7 +31,6 @@ import java.util.Collections; import java.util.Comparator; import java.util.Date; import java.util.LinkedList; -import java.util.List; import java.util.Locale; import java.util.TimeZone; import java.util.regex.Matcher; @@ -60,90 +59,22 @@ public class GalleryDetailParser { private static final CommentSort COMMENT_SORTER = new CommentSort(); - public int gid; - public String token; - public String thumb; - public String title; - public String titleJpn; - public int category; - public String uploader; - - public int torrentCount; - public String torrentUrl; - - public String posted; - public String parent; - public String visible; - public String language; - public String size; - public String resize; - public int pageCount; - public int favoredTimes; - public boolean isFavored; - public float rating; - public int ratedTimes; - - public List tags; - public List comments; - - public int previewPageCount; - - public PreviewSet previewSet; - - private String sortOut(String str) { - // Avoid null - if (str == null) { - str = ""; - } - return Utils.unescapeXml(str).trim(); - } - - private int sortOutInteger(String str, int defaultValue) { - return Utils.parseIntSafely(sortOut(str).replace(",", ""), defaultValue); - } - - private void parseTagGroup(TagGroup tagGroup, String body) { - Pattern p = Pattern.compile("]+>]+>([\\w\\s]+)"); - Matcher m = p.matcher(body); - while (m.find()) { - tagGroup.addTag(sortOut(m.group(1))); + public static GalleryDetail parse(String body, int source, int request) throws Exception { + switch (source) { + default: + case EhUrl.SOURCE_G: + case EhUrl.SOURCE_EX: { + return parse(body, request); + } + case EhUrl.SOURCE_LOFI: { + //parseLofi(body, request); + //break; + throw new EhException("Not support lofi now"); + } } } - private void parseNormalPreview(String body) { - Pattern p = Pattern.compile("]*class=\"gdtm\"[^<>]*>]*width:(\\d+)[^<>]*height:(\\d+)[^<>]*\\((.+?)\\)[^<>]*-(\\d+)px[^<>]*>]*href=\"(.+?)\"[^<>]*>"); - Matcher m = p.matcher(body); - NormalPreviewSet normalPreviewSet = new NormalPreviewSet(); - while (m.find()) { - normalPreviewSet.addItem(m.group(3), Integer.parseInt(m.group(4)), 0, - Integer.parseInt(m.group(1)), Integer.parseInt(m.group(2)), - m.group(5)); - } - previewSet = normalPreviewSet; - } - - private void parseLargePreview(String body) { - Pattern p = Pattern.compile("
\n

([^<]+)

"); m = p.matcher(body); @@ -163,6 +97,8 @@ public class GalleryDetailParser { throw new EhException(m.group(1)); } + GalleryDetail galleryDetail = new GalleryDetail(); + if ((request & REQUEST_DETAIL) != 0) { p = Pattern.compile("var gid = (\\d+)" // 1 gid + ".+?" @@ -195,70 +131,70 @@ public class GalleryDetailParser { + "]*>(.+?)", Pattern.DOTALL); // 20 isFavored "Favorite Gallery" for favorite m = p.matcher(body); if (m.find()) { - gid = sortOutInteger(m.group(1), 0); - token = sortOut(m.group(2)); - thumb = sortOut(m.group(3)); - title = sortOut(m.group(4)); - titleJpn = sortOut(m.group(5)); - torrentUrl = sortOut(m.group(6)); - torrentCount = sortOutInteger(m.group(7), 0); - category = EhUtils.getCategory(sortOut(m.group(8))); - uploader = sortOut(m.group(9)); - posted = sortOut(m.group(10)); - parent = sortOut(m.group(11)); - visible = sortOut(m.group(12)); - language = sortOut(m.group(13)); - size = sortOut(m.group(14)); - resize = sortOut(m.group(15)); - pageCount = sortOutInteger(m.group(16), 0); + galleryDetail.gid = ParserUtils.parseInt(m.group(1)); + galleryDetail.token = ParserUtils.trim(m.group(2)); + galleryDetail.thumb = ParserUtils.trim(m.group(3)); + galleryDetail.title = ParserUtils.trim(m.group(4)); + galleryDetail.titleJpn = ParserUtils.trim(m.group(5)); + galleryDetail.torrentUrl = ParserUtils.trim(m.group(6)); + galleryDetail.torrentCount = ParserUtils.parseInt(m.group(7)); + galleryDetail.category = EhUtils.getCategory(ParserUtils.trim(m.group(8))); + galleryDetail.uploader = ParserUtils.trim(m.group(9)); + galleryDetail.posted = ParserUtils.trim(m.group(10)); + galleryDetail.parent = ParserUtils.trim(m.group(11)); + galleryDetail.visible = ParserUtils.trim(m.group(12)); + galleryDetail.language = ParserUtils.trim(m.group(13)); + galleryDetail.size = ParserUtils.trim(m.group(14)); + galleryDetail.resize = ParserUtils.trim(m.group(15)); + galleryDetail.pageCount = ParserUtils.parseInt(m.group(16)); - String favTimeStr = sortOut(m.group(17)); + String favTimeStr = ParserUtils.trim(m.group(17)); switch (favTimeStr) { case "Never": - favoredTimes = 0; + galleryDetail.favoredTimes = 0; break; case "Once": - favoredTimes = 1; + galleryDetail.favoredTimes = 1; break; default: int index = favTimeStr.indexOf(' '); if (index == -1) { - favoredTimes = 0; + galleryDetail.favoredTimes = 0; } else { - favoredTimes = Utils.parseIntSafely(favTimeStr.substring(0, index), 0); + galleryDetail.favoredTimes = ParserUtils.parseInt(favTimeStr.substring(0, index)); } break; } - ratedTimes = sortOutInteger(m.group(18), 0); + galleryDetail.ratedTimes = ParserUtils.parseInt(m.group(18)); - String ratingStr = sortOut(m.group(19)); + String ratingStr = ParserUtils.trim(m.group(19)); if ("Not Yet Rated".equals(ratingStr)) { - rating = Float.NaN; + galleryDetail.rating = Float.NaN; } else { int index = ratingStr.indexOf(' '); if (index == -1 || index >= ratingStr.length()) { - rating = 0f; + galleryDetail.rating = 0f; } else { - rating = Utils.parseFloatSafely(ratingStr.substring(index + 1), 0f); + galleryDetail.rating = Utils.parseFloatSafely(ratingStr.substring(index + 1), 0f); } } - isFavored = "Favorite Gallery".equals(sortOut(m.group(20))); + galleryDetail.isFavored = "Favorite Gallery".equals(ParserUtils.trim(m.group(20))); } else { - throw new ParseException("Parse gallery body error", body); + throw new ParseException("Parse gallery detail error", body); } } if ((request & REQUEST_TAG) != 0) { - tags = new LinkedList<>(); + galleryDetail.tags = new LinkedList<>(); p = Pattern.compile("]+>([\\w\\s]+):(?:]+>]+>[\\w\\s]+
)+"); m = p.matcher(body); while (m.find()) { TagGroup tagGroup = new TagGroup(); - tagGroup.groupName = sortOut(m.group(1)); + tagGroup.groupName = ParserUtils.trim(m.group(1)); parseTagGroup(tagGroup, m.group(0)); - tags.add(tagGroup); + galleryDetail.tags.add(tagGroup); } } @@ -267,27 +203,30 @@ public class GalleryDetailParser { p = Pattern.compile("]+>]+>([\\d,]+)]+>(?:]+>)?>(?:)?"); m = p.matcher(body); if (m.find()) { - previewPageCount = sortOutInteger(m.group(1), 0); + galleryDetail.previewPageCount = ParserUtils.parseInt(m.group(1)); } else { - previewPageCount = 0; + galleryDetail.previewPageCount = 0; } - if (previewPageCount <= 0) { + if (galleryDetail.previewPageCount <= 0) { throw new ParseException("Parse preview page count error", body); } } // Get preview if ((request & REQUEST_PREVIEW) != 0) { - parsePreview(body); + PreviewSet previewSet = parsePreview(body); + previewSet.setGid(galleryDetail.gid); // TODO What if not set REQUEST_DETAIL + galleryDetail.previewSetArray = new PreviewSet[galleryDetail.previewPageCount]; + galleryDetail.previewSetArray[0] = previewSet; } // Get comment if ((request & REQUEST_COMMENT) != 0) { p = Pattern.compile("
Posted on ([^<>]+) by:   ]+>([^<>]+).+?
]*>(.+?)
(); + galleryDetail.comments = new LinkedList<>(); while (m.find()) { - String webDateString = sortOut(m.group(1)); + String webDateString = ParserUtils.trim(m.group(1)); Date date; try { date = WEB_COMMENT_DATA_FORMAT.parse(webDateString); @@ -295,34 +234,67 @@ public class GalleryDetailParser { date = new Date(0l); } String outDateString = OUT_COMMENT_DATA_FORMAT.format(date); - comments.add(new Comment(outDateString, date, sortOut(m.group(2)), m.group(3))); + galleryDetail.comments.add(new Comment(outDateString, date, ParserUtils.trim(m.group(2)), m.group(3))); } - Collections.sort(comments, COMMENT_SORTER); + Collections.sort(galleryDetail.comments, COMMENT_SORTER); } - if ((request & REQUEST_COMMENT) != 0) { + return galleryDetail; + } + private static void parseTagGroup(TagGroup tagGroup, String body) { + Pattern p = Pattern.compile("]+>]+>([\\w\\s]+)
"); + Matcher m = p.matcher(body); + while (m.find()) { + tagGroup.addTag(ParserUtils.trim(m.group(1))); } } - public void parse(String body, int request, int source) throws Exception { - AssertUtils.assertNotNull("Body is null when parse gallery list", body); - + public static PreviewSet parsePreview(String body, int source) throws EhException { switch (source) { default: - case EhClient.SOURCE_G: - case EhClient.SOURCE_EX: { - parse(body, request); - break; + case EhUrl.SOURCE_G: + case EhUrl.SOURCE_EX: { + return parsePreview(body); } - case EhClient.SOURCE_LOFI: { - //parseLofi(body, request); + case EhUrl.SOURCE_LOFI: { + //parsePreviewLofi(body); //break; throw new EhException("Not support lofi now"); } } } + public static PreviewSet parsePreview(String body) { + if (body.contains("
]*class=\"gdtm\"[^<>]*>]*width:(\\d+)[^<>]*height:(\\d+)[^<>]*\\((.+?)\\)[^<>]*-(\\d+)px[^<>]*>]*href=\"(.+?)\"[^<>]*>"); + Matcher m = p.matcher(body); + NormalPreviewSet normalPreviewSet = new NormalPreviewSet(); + while (m.find()) { + normalPreviewSet.addItem(m.group(3), Integer.parseInt(m.group(4)), 0, + Integer.parseInt(m.group(1)), Integer.parseInt(m.group(2)), + m.group(5)); + } + return normalPreviewSet; + } + + private static LargePreviewSet parseLargePreview(String body) { + Pattern p = Pattern.compile("
{ @Override diff --git a/app/src/main/java/com/hippo/ehviewer/client/GalleryListParser.java b/app/src/main/java/com/hippo/ehviewer/client/GalleryListParser.java index 4bad193ea..1100a90d1 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/GalleryListParser.java +++ b/app/src/main/java/com/hippo/ehviewer/client/GalleryListParser.java @@ -16,6 +16,8 @@ package com.hippo.ehviewer.client; +import android.support.annotation.NonNull; + import com.hippo.ehviewer.client.data.GalleryInfo; import com.hippo.ehviewer.client.data.LofiGalleryInfo; import com.hippo.ehviewer.util.EhUtils; @@ -29,99 +31,120 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; public class GalleryListParser { - private static final String PARSE_MESSAGE = "Gallery list parser error"; - private static final int DEFAULT_LIST_SIZE = 25; + public static class Result { - public static final int CURRENT_PAGE_IS_LAST = -1; + public static final int NOT_FOUND = 0; - /** - * If NOT FOUND, pageNum is 0.
- * For lofi, we can not get pages number, - * so pageNum is {@link java.lang.Integer#MAX_VALUE} when it is not the last page, - * pageNum is {@link #CURRENT_PAGE_IS_LAST} when it is the last page - */ - public int pageNum; + public static final int CURRENT_PAGE_IS_LAST = -1; - public List giList; + public static final int KEEP_LOADING = Integer.MAX_VALUE; - private void parse(String body) throws EhException { - Pattern p; - Matcher m; + /** + * If NOT FOUND, pageNum is 0.
+ * For lofi, we can not get pages number, + * so pageNum is {@link java.lang.Integer#MAX_VALUE} when it is not the last page, + * pageNum is {@link #CURRENT_PAGE_IS_LAST} when it is the last page + */ + public int pages; + public List galleryInfos; + } - // Get page number - p = Pattern.compile("]+>([\\d]+)]+>(?:]+>)?&"); - m = p.matcher(body); - if (m.find()) { - pageNum = Integer.parseInt(m.group(1)); - } else if (body.contains("No hits found

")) { - pageNum = 0; - } else { - // Can not get page number - throw new EhException(PARSE_MESSAGE); - } - - // Get gallery - giList = new ArrayList<>(DEFAULT_LIST_SIZE); - - p = Pattern.compile("(?:)?(?:)?" // category - + "(.+?)" // posted - + "" - + "(?:" - + "|init~([^<>\"~]+~[^<>\"~]+)~([^<>]+))" // thumb and title - + "
" - + ".+?" - + "" // url and title - + ".+?" - + "
\"]+)\">" // rating - + ".+?" - + "
(.+?)"); // uploader - m = p.matcher(body); - while (m.find()) { - GalleryInfo gi = new GalleryInfo(); - - gi.category = EhUtils.getCategory(m.group(1)); - gi.posted = m.group(2); - gi.thumbHeight = Integer.parseInt(m.group(3)); - gi.thumbWidth = Integer.parseInt(m.group(4)); - - if (m.group(5) == null) { - gi.thumb = Utils.unescapeXml("http://" - + m.group(7).replace('~', '/')); - gi.title = Utils.unescapeXml(m.group(8)); - } else { - gi.thumb = Utils.unescapeXml(m.group(5)); - gi.title = Utils.unescapeXml(m.group(6)); + public static Result parse(@NonNull String body, int source) throws Exception { + switch (source) { + default: + case EhUrl.SOURCE_G: + case EhUrl.SOURCE_EX: { + return parse(body); } - - Pattern pattern = Pattern - .compile("/(\\d+)/(\\w+)"); - Matcher matcher = pattern.matcher(m.group(9)); - if (matcher.find()) { - gi.gid = Integer.parseInt(matcher.group(1)); - gi.token = matcher.group(2); - } else { - continue; + case EhUrl.SOURCE_LOFI: { + return parseLofi(body); } - - gi.rating = Utils.parseFloatSafely(getRate(m.group(11)), Float.NaN); - gi.uploader = m.group(12); - gi.generateSLang(); - - giList.add(gi); - } - - if (giList.size() == 0) { - throw new EhException(PARSE_MESSAGE); } } - private void parseLofi(String body) throws Exception { + private static Result parse(String body) throws EhException { + Result result = new Result(); Pattern p; Matcher m; - // Get gallery - giList = new ArrayList<>(DEFAULT_LIST_SIZE); + // pages + p = Pattern.compile("]+>([\\d]+)]+>(?:]+>)?&"); + m = p.matcher(body); + if (m.find()) { + result.pages = ParserUtils.parseInt(m.group(1)); + } else if (body.contains("No hits found

")) { + result.pages = Result.NOT_FOUND; + } else { + // Can not get page number + throw new ParseException("Can't parse gallery list", body); + } + + if (result.pages > 0) { + List list = new ArrayList<>(25); + result.galleryInfos = list; + + p = Pattern.compile("(?:)?(?:)?" // category + + "(.+?)" // posted + + "" + + "(?:" + + "|init~([^<>\"~]+~[^<>\"~]+)~([^<>]+))" // thumb and title + + "
" + + ".+?" + + "" // url and title + + ".+?" + + "
\"]+)\">" // rating + + ".+?" + + "
(.+?)"); // uploader + m = p.matcher(body); + while (m.find()) { + GalleryInfo gi = new GalleryInfo(); + + gi.category = EhUtils.getCategory(ParserUtils.trim(m.group(1))); + gi.posted = ParserUtils.trim(m.group(2)); + gi.thumbHeight = ParserUtils.parseInt(m.group(3)); + gi.thumbWidth = ParserUtils.parseInt(m.group(4)); + + if (m.group(5) == null) { + gi.thumb = ParserUtils.trim("http://" + m.group(7).replace('~', '/')); + gi.title = ParserUtils.trim(m.group(8)); + } else { + gi.thumb = ParserUtils.trim(m.group(5)); + gi.title = ParserUtils.trim(m.group(6)); + } + + Pattern pattern = Pattern + .compile("/(\\d+)/(\\w+)"); + Matcher matcher = pattern.matcher(m.group(9)); + if (matcher.find()) { + gi.gid = ParserUtils.parseInt(matcher.group(1)); + gi.token = ParserUtils.trim(matcher.group(2)); + } else { + continue; + } + + gi.rating = Utils.parseFloatSafely(getRate(m.group(11)), Float.NaN); + gi.uploader = ParserUtils.trim(m.group(12)); + gi.generateSLang(); + + list.add(gi); + } + + if (list.size() == 0) { + throw new ParseException("Can't parse gallery list", body); + } + } + + return result; + } + + private static Result parseLofi(String body) throws Exception { + Result result = new Result(); + Pattern p; + Matcher m; + + List list = new ArrayList<>(25); + result.galleryInfos = list; p = Pattern.compile("" // detail url + "" // thumb url + ".+?(.+?)" // title @@ -139,8 +162,8 @@ public class GalleryListParser { lgi.gid = dup.gid; lgi.token = dup.token; - lgi.thumb = Utils.unescapeXml(m.group(2)); - lgi.title = Utils.unescapeXml(m.group(3)); + lgi.thumb = ParserUtils.trim(m.group(2)); + lgi.title = ParserUtils.trim(m.group(3)); getPostedAndUploader(m.group(4), pau); lgi.posted = pau[0]; @@ -159,44 +182,29 @@ public class GalleryListParser { lgi.rating = getStartNum(rating); lgi.generateSLang(); - giList.add(lgi); + list.add(lgi); } - if (giList.size() == 0) { + if (list.size() == 0) { if (body.contains("No hits found
")) { - pageNum = 0; + result.pages = Result.NOT_FOUND; } else if (body.contains("No more hits found
")) { throw new EhException("Index is out of range"); } else { - throw new EhException(PARSE_MESSAGE); + throw new ParseException("Can't parse gallery list", body); } } else { if (!body.contains("Next Page >")) { - pageNum = CURRENT_PAGE_IS_LAST; + result.pages = Result.CURRENT_PAGE_IS_LAST; } else { - pageNum = Integer.MAX_VALUE; + result.pages = Result.KEEP_LOADING; } } + + return result; } - public void parse(String body, int source) throws Exception { - AssertUtils.assertNotNull("Body is null when parse gallery list", body); - - switch (source) { - default: - case EhClient.SOURCE_G: - case EhClient.SOURCE_EX: { - parse(body); - break; - } - case EhClient.SOURCE_LOFI: { - parseLofi(body); - break; - } - } - } - - private String getRate(String rawRate) { + private static String getRate(String rawRate) { Pattern p = Pattern.compile("\\d+px"); Matcher m = p.matcher(rawRate); int num1; @@ -204,11 +212,11 @@ public class GalleryListParser { int rate = 5; String re; if (m.find()) - num1 = Integer.parseInt(m.group().replace("px", "")); + num1 = ParserUtils.parseInt(m.group().replace("px", "")); else return null; if (m.find()) - num2 = Integer.parseInt(m.group().replace("px", "")); + num2 = ParserUtils.parseInt(m.group().replace("px", "")); else return null; rate = rate - num1 / 16; @@ -223,14 +231,14 @@ public class GalleryListParser { private static final String PAU_SPACER = " by "; - private void getPostedAndUploader(String raw, String[] pau) throws AssertException { + private static void getPostedAndUploader(String raw, String[] pau) throws AssertException { int index = raw.indexOf(PAU_SPACER); AssertUtils.assertNotEqualsEx("Can not parse posted and uploader", index, -1); pau[0] = raw.substring(0, index); pau[1] = raw.substring(index + PAU_SPACER.length()); } - private int getStartNum(String str) { + private static int getStartNum(String str) { int startNum = 0; for (int i = 0; i < str.length(); i++) { if (str.charAt(i) == '*') diff --git a/app/src/main/java/com/hippo/ehviewer/client/ParserUtils.java b/app/src/main/java/com/hippo/ehviewer/client/ParserUtils.java new file mode 100644 index 000000000..816f96e9a --- /dev/null +++ b/app/src/main/java/com/hippo/ehviewer/client/ParserUtils.java @@ -0,0 +1,34 @@ +/* + * Copyright 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 + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hippo.ehviewer.client; + +import com.hippo.util.Utils; + +public class ParserUtils { + + public static String trim(String str) { + // Avoid null + if (str == null) { + str = ""; + } + return Utils.unescapeXml(str).trim(); + } + + public static int parseInt(String str) { + return Integer.parseInt(trim(str).replace(",", "")); + } +} diff --git a/app/src/main/java/com/hippo/ehviewer/client/PopularParser.java b/app/src/main/java/com/hippo/ehviewer/client/PopularParser.java index 10f277df4..485b9fe2c 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/PopularParser.java +++ b/app/src/main/java/com/hippo/ehviewer/client/PopularParser.java @@ -28,22 +28,27 @@ import java.util.List; public class PopularParser { - public List galleryInfoList; - public long timeStamp; + public static class Result { - public void parse(String body) throws Exception { - galleryInfoList = new ArrayList<>(); + public long timeStamp; + public List galleryInfos; + } + + public static Result parse(String body) throws Exception { + Result result = new Result(); JSONObject js = new JSONObject(body); - js = js.getJSONObject("popular"); + js = js.getJSONObject("popular"); if (!js.has("galleries")) { if (js.has("error")) { throw new EhException(js.getString("error")); } else { - throw new EhException("Parser error"); // TODO + throw new ParseException("Can't parse popular", body); } } + List list = new ArrayList<>(); + result.galleryInfos = list; JSONArray ja = js.getJSONArray("galleries"); for (int i = 0; i < ja.length(); i++) { JSONObject j = ja.getJSONObject(i); @@ -57,13 +62,15 @@ public class PopularParser { gi.uploader = j.getString("uploader"); gi.rating = Float.parseFloat(j.getString("rating")); gi.generateSLang(); - galleryInfoList.add(gi); + list.add(gi); } if (js.has("time")) { - timeStamp = js.getLong("time"); + result.timeStamp = js.getLong("time"); } else { - timeStamp = -1; + result.timeStamp = -1; } + + return result; } } diff --git a/app/src/main/java/com/hippo/ehviewer/client/SignInParser.java b/app/src/main/java/com/hippo/ehviewer/client/SignInParser.java index ad21d2600..8bf8b625b 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/SignInParser.java +++ b/app/src/main/java/com/hippo/ehviewer/client/SignInParser.java @@ -20,17 +20,15 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; public class SignInParser { - public String displayname; - public boolean parse(String body) throws Exception { + public static String 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; + return m.group(1); } else { p = Pattern.compile("(?:

The error returned was:

\\s*

(.+?)

)" + "|(?:(.+?))"); diff --git a/app/src/main/java/com/hippo/ehviewer/client/data/ListUrlBuilder.java b/app/src/main/java/com/hippo/ehviewer/client/data/ListUrlBuilder.java index 8c2b60b05..1220cff90 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/data/ListUrlBuilder.java +++ b/app/src/main/java/com/hippo/ehviewer/client/data/ListUrlBuilder.java @@ -16,7 +16,8 @@ package com.hippo.ehviewer.client.data; -import com.hippo.ehviewer.client.EhClient; +import com.hippo.ehviewer.client.EhConfig; +import com.hippo.ehviewer.client.EhUrl; import com.hippo.ehviewer.util.EhUtils; import com.hippo.ehviewer.widget.AdvanceSearchTable; import com.hippo.network.UrlBuilder; @@ -128,18 +129,18 @@ public class ListUrlBuilder { case MODE_NORMAL: case MODE_UPLOADER: { boolean filter = false; - UrlBuilder ub = new UrlBuilder(EhClient.getUrlHeader(source)); + UrlBuilder ub = new UrlBuilder(EhUrl.getUrlHeader(source)); if (mCategory != EhUtils.NONE) { - ub.addQuery("f_doujinshi", ((mCategory & EhUtils.DOUJINSHI) == 0) ? "0" : "1"); - ub.addQuery("f_manga", ((mCategory & EhUtils.MANGA) == 0) ? "0" : "1"); - ub.addQuery("f_artistcg", ((mCategory & EhUtils.ARTIST_CG) == 0) ? "0" : "1"); - ub.addQuery("f_gamecg", ((mCategory & EhUtils.GAME_CG) == 0) ? "0" : "1"); - ub.addQuery("f_western", ((mCategory & EhUtils.WESTERN) == 0) ? "0" : "1"); - ub.addQuery("f_non-h", ((mCategory & EhUtils.NON_H) == 0) ? "0" : "1"); - ub.addQuery("f_imageset", ((mCategory & EhUtils.IMAGE_SET) == 0) ? "0" : "1"); - ub.addQuery("f_cosplay", ((mCategory & EhUtils.COSPLAY) == 0) ? "0" : "1"); - ub.addQuery("f_asianporn", ((mCategory & EhUtils.ASIAN_PORN) == 0) ? "0" : "1"); - ub.addQuery("f_misc", ((mCategory & EhUtils.MISC) == 0) ? "0" : "1"); + ub.addQuery("f_doujinshi", ((mCategory & EhConfig.DOUJINSHI) == 0) ? "0" : "1"); + ub.addQuery("f_manga", ((mCategory & EhConfig.MANGA) == 0) ? "0" : "1"); + ub.addQuery("f_artistcg", ((mCategory & EhConfig.ARTIST_CG) == 0) ? "0" : "1"); + ub.addQuery("f_gamecg", ((mCategory & EhConfig.GAME_CG) == 0) ? "0" : "1"); + ub.addQuery("f_western", ((mCategory & EhConfig.WESTERN) == 0) ? "0" : "1"); + ub.addQuery("f_non-h", ((mCategory & EhConfig.NON_H) == 0) ? "0" : "1"); + ub.addQuery("f_imageset", ((mCategory & EhConfig.IMAGE_SET) == 0) ? "0" : "1"); + ub.addQuery("f_cosplay", ((mCategory & EhConfig.COSPLAY) == 0) ? "0" : "1"); + ub.addQuery("f_asianporn", ((mCategory & EhConfig.ASIAN_PORN) == 0) ? "0" : "1"); + ub.addQuery("f_misc", ((mCategory & EhConfig.MISC) == 0) ? "0" : "1"); filter = true; } // Search key @@ -180,10 +181,10 @@ public class ListUrlBuilder { return ub.build(); } case MODE_TAG: { - if (source == EhClient.SOURCE_LOFI) { + if (source == EhUrl.SOURCE_LOFI) { throw new UnsupportedSearchException("Lofi do not support tag search"); } - StringBuilder sb = new StringBuilder(EhClient.getUrlHeader(source)); + StringBuilder sb = new StringBuilder(EhUrl.getUrlHeader(source)); sb.append("tag/"); try { sb.append(URLEncoder.encode(mKeyword, "UTF-8")); diff --git a/app/src/main/java/com/hippo/ehviewer/network/EhHttpClient.java b/app/src/main/java/com/hippo/ehviewer/network/EhHttpClient.java new file mode 100644 index 000000000..b5d592683 --- /dev/null +++ b/app/src/main/java/com/hippo/ehviewer/network/EhHttpClient.java @@ -0,0 +1,146 @@ +/* + * Copyright 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 + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hippo.ehviewer.network; + +import android.content.Context; +import android.os.Build; +import android.webkit.CookieManager; +import android.webkit.CookieSyncManager; + +import com.hippo.ehviewer.client.EhConfig; +import com.hippo.ehviewer.util.Settings; +import com.hippo.httpclient.Cookie; +import com.hippo.httpclient.HttpClient; +import com.hippo.util.MathUtils; +import com.hippo.util.Utils; + +import java.net.URL; + +public class EhHttpClient extends HttpClient { + + private static String[] EHENTAI_DOMAIN = { + "exhentai.org", + "e-hentai.org" + }; + + private static final String HOST_EX = "exhentai.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_YAY = "yay"; + + private final CookieManager mCookieManager; + + private EhConfig mEhConfig; + + @SuppressWarnings("deprecation") + public EhHttpClient(Context context) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + CookieSyncManager.createInstance(context); + } + + mCookieManager = CookieManager.getInstance(); + mEhConfig = Settings.getEhConfig(); + } + + private String getDomain(URL 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 + protected void fillCookie(URL url, Cookie cookie) { + boolean isSignIn = Settings.getSignIn(); + String host = url.getHost(); + + cookie.putRaw(mCookieManager.getCookie(url.toString())); + + if (Utils.contain(EHENTAI_DOMAIN, getDomain(url))) + + + if (!isSignIn && HOST_EX.equals(host)) { + cookie.put("yay", "louder"); + } else { + cookie.putRaw(mCookieManager.getCookie(url.toString())); + + if (Utils.contain(EHENTAI_DOMAIN, getDomain(url))) { + if (Settings.getSignIn()) { + // Put login info + String ipdMemberId = Settings.getIpdNumberId(); + String ipdPassHash = Settings.getIpdPassHash(); + String igneous = Settings.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); + } + } else if (HOST_EX.equals(url.getHost())) { + cookie.put("yay", "louder"); + } + + mEhConfig.fillCookie(cookie); + } + } + } + + @Override + protected void storeCookie(URL url, String cookieStr) { + Cookie cookie = new Cookie(); + cookie.putRaw(cookieStr); + + 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) { + Settings.putIpdMemberId(ipdMemberId); + } + if (ipdPassHash != null) { + Settings.putIpdPassHash(ipdPassHash); + } + if (igneous != null) { + Settings.putIgneous(igneous); + } + + cookie.remove(KEY_IPD_MEMBER_ID); + cookie.remove(KEY_IPD_MEMBER_ID); + cookie.remove(KEY_IGNEOUS); + cookie.remove(KEY_YAY); + cookie.remove(EhConfig.KEY_UCONFIG); + cookie.remove(EhConfig.KEY_LOFI_RESOLUTION); + cookie.remove(EhConfig.KEY_CONTENT_WARNING); + + mCookieManager.setCookie(url.toString(), cookie.toString()); + } +} diff --git a/app/src/main/java/com/hippo/ehviewer/network/EhHttpRequest.java b/app/src/main/java/com/hippo/ehviewer/network/EhHttpRequest.java new file mode 100644 index 000000000..9675219eb --- /dev/null +++ b/app/src/main/java/com/hippo/ehviewer/network/EhHttpRequest.java @@ -0,0 +1,67 @@ +/* + * Copyright 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 + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hippo.ehviewer.network; + +import com.hippo.ehviewer.client.EhConfig; +import com.hippo.ehviewer.client.EhException; +import com.hippo.httpclient.Cookie; +import com.hippo.httpclient.HttpRequest; +import com.hippo.httpclient.ResponseCodeException; + +import java.net.HttpURLConnection; +import java.net.URL; + +public class EhHttpRequest extends HttpRequest { + + 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 EhConfig mEhConfig; + + public void setEhConfig(EhConfig ehConfig) { + mEhConfig = ehConfig; + } + + @Override + protected void fillCookie(URL url, Cookie cookie) { + super.fillCookie(url, cookie); + + if (mEhConfig != null) { + mEhConfig.fillCookie(cookie); + } + } + + @Override + protected void onAfterConnect(HttpURLConnection conn) throws Exception { + super.onAfterConnect(conn); + + final int responseCode = conn.getResponseCode(); + if (responseCode >= 400) { + throw new ResponseCodeException(responseCode); + } + + String disposition = conn.getHeaderField("Content-Disposition"); + String type = conn.getHeaderField("Content-Type"); + String length = conn.getHeaderField("Content-Length"); + + if (SAD_PANDA_DISPOSITION.equals(disposition) && SAD_PANDA_TYPE.equals(type) && + SAD_PANDA_LENGTH.equals(length)) { + throw new EhException("Sad Panda"); + } + } +} diff --git a/app/src/main/java/com/hippo/ehviewer/network/EhOkHttpClient.java b/app/src/main/java/com/hippo/ehviewer/network/EhOkHttpClient.java deleted file mode 100644 index baeefa0dc..000000000 --- a/app/src/main/java/com/hippo/ehviewer/network/EhOkHttpClient.java +++ /dev/null @@ -1,193 +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 - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hippo.ehviewer.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 f2627f0ec..399213a03 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/ContentActivity.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/ContentActivity.java @@ -31,7 +31,7 @@ import com.hippo.ehviewer.R; import com.hippo.ehviewer.ui.scene.GalleryListScene; import com.hippo.ehviewer.ui.scene.MainSettingsScene; import com.hippo.ehviewer.ui.scene.SignInScene; -import com.hippo.ehviewer.util.Config; +import com.hippo.ehviewer.util.Settings; import com.hippo.ehviewer.widget.DrawerLeftPanel; import com.hippo.ehviewer.widget.FitStageLayout; import com.hippo.scene.Announcer; @@ -130,7 +130,7 @@ public final class ContentActivity extends StageActivity @Override protected boolean isShowStats() { - return Config.getShowApplicationStats(); + return Settings.getShowApplicationStats(); } @SuppressLint("RtlHardcoded") @@ -242,7 +242,7 @@ public final class ContentActivity extends StageActivity @Override public void onClickSignOut() { - Config.putSignIn(false); + Settings.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/GalleryDetailScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryDetailScene.java index ace86be9a..2acb4f754 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryDetailScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryDetailScene.java @@ -38,14 +38,16 @@ import com.hippo.ehviewer.EhImageKeyFactory; import com.hippo.ehviewer.R; import com.hippo.ehviewer.client.EhClient; import com.hippo.ehviewer.client.EhException; +import com.hippo.ehviewer.client.EhRequest; +import com.hippo.ehviewer.client.EhUrl; import com.hippo.ehviewer.client.OffensiveException; import com.hippo.ehviewer.client.data.Comment; import com.hippo.ehviewer.client.data.GalleryDetail; import com.hippo.ehviewer.client.data.GalleryInfo; import com.hippo.ehviewer.client.data.PreviewSet; import com.hippo.ehviewer.client.data.TagGroup; -import com.hippo.ehviewer.util.Config; import com.hippo.ehviewer.util.EhUtils; +import com.hippo.ehviewer.util.Settings; import com.hippo.ehviewer.widget.LoadImageView; import com.hippo.ehviewer.widget.PreviewLayout; import com.hippo.ehviewer.widget.RatingView; @@ -118,9 +120,16 @@ public class GalleryDetailScene extends Scene implements View.OnClickListener, private GalleryDetail mGalleryDetail; private void requestGalleryDetail(GalleryInfo gi) { - EhClient.getInstance().getGalleryDetail(Config.getEhSource(), - EhClient.getDetailUrl(Config.getEhSource(), gi.gid, gi.token, 0), - new EhDetailListener()); + EhClient client = EhApplication.getEhClient(getStageActivity()); + int source = Settings.getEhSource(); + String url = EhUrl.getDetailUrl(source, gi.gid, gi.token, 0); + + EhRequest request = new EhRequest(); + request.setMethod(EhClient.METHOD_GET_GALLERY_DETAIL); + request.setEhListener(new EhDetailListener()); + request.setArgs(url, source); + // TODO request.setEhConfig(); + client.execute(request); } private void handleAnnouncer(Announcer announcer) { @@ -270,7 +279,7 @@ public class GalleryDetailScene extends Scene implements View.OnClickListener, } else if (v == mShare) { StartActivityHelper.share(getStageActivity(), - EhClient.getDetailUrl(Config.getEhSource(), gd.gid, gd.token, 0)); + EhUrl.getDetailUrl(Settings.getEhSource(), gd.gid, gd.token, 0)); } } @@ -421,7 +430,7 @@ public class GalleryDetailScene extends Scene implements View.OnClickListener, } } - private class EhDetailListener extends EhClient.OnGetGalleryDetailListener { + private class EhDetailListener extends EhClient.EhListener { @Override public void onSuccess(GalleryDetail galleryDetail) { @@ -483,28 +492,44 @@ public class GalleryDetailScene extends Scene implements View.OnClickListener, }).show(GalleryDetailScene.this); } } + + @Override + public void onCanceled() { + + } } class SimplePreviewHelper implements PreviewLayout.PreviewHelper { @Override public void onRequstPreview(PreviewLayout previewLayout, final int index) { - int source = Config.getEhSource(); - EhClient.getInstance().getPreviewSet(source, - EhClient.getDetailUrl(source, mGalleryDetail.gid, mGalleryDetail.token, index), - new EhClient.OnGetPreviewSetListener() { + EhClient client = EhApplication.getEhClient(getStageActivity()); + int source = Settings.getEhSource(); + String url = EhUrl.getDetailUrl(source, mGalleryDetail.gid, mGalleryDetail.token, index); - @Override - public void onSuccess(PreviewSet previewSet) { - mPreviewLayout.onGetPreview(previewSet, index); - } + EhRequest request = new EhRequest(); + request.setMethod(EhClient.METHOD_GET_PREVIEW_SET); + // TODO request.setEhConfig(); + request.setArgs(url, source); + request.setEhListener(new EhClient.EhListener() { - @Override - public void onFailure(Exception e) { - // TODO - e.printStackTrace(); - } - }); + @Override + public void onSuccess(PreviewSet result) { + mPreviewLayout.onGetPreview(result, index); + } + + @Override + public void onFailure(Exception e) { + e.printStackTrace(); + } + + @Override + public void onCanceled() { + + } + }); + + client.execute(request); } @Override diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.java index 0c7a3e853..466f8ed33 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/GalleryListScene.java @@ -44,13 +44,16 @@ import com.hippo.ehviewer.EhApplication; import com.hippo.ehviewer.EhImageKeyFactory; import com.hippo.ehviewer.R; import com.hippo.ehviewer.client.EhClient; +import com.hippo.ehviewer.client.EhRequest; +import com.hippo.ehviewer.client.EhUrl; import com.hippo.ehviewer.client.GalleryListParser; +import com.hippo.ehviewer.client.PopularParser; import com.hippo.ehviewer.client.data.GalleryInfo; import com.hippo.ehviewer.client.data.ListUrlBuilder; import com.hippo.ehviewer.client.data.UnsupportedSearchException; import com.hippo.ehviewer.ui.ContentActivity; -import com.hippo.ehviewer.util.Config; import com.hippo.ehviewer.util.EhUtils; +import com.hippo.ehviewer.util.Settings; import com.hippo.ehviewer.widget.ContentLayout; import com.hippo.ehviewer.widget.LoadImageView; import com.hippo.ehviewer.widget.OffsetLayout; @@ -72,8 +75,6 @@ import com.hippo.widget.FabLayout; import com.hippo.widget.FloatingActionButton; import com.hippo.widget.recyclerview.EasyRecyclerView; -import java.util.List; - // TODO remeber the data in ContentHelper after screen dirction change // TODO Must refresh when change source // TODO disable click action when animating @@ -891,22 +892,33 @@ public final class GalleryListScene extends Scene implements SearchBar.Helper, @Override protected void getPageData(int taskId, int type, int page) { + EhClient client = EhApplication.getEhClient(getStageActivity()); + int mode = mListUrlBuilder.getMode(); if (mode == ListUrlBuilder.MODE_POPULAR) { PopularListener listener = new PopularListener(taskId); listener.setGalleryListHelper(this); mListener = listener; - EhClient.getInstance().getPopular(listener); + EhRequest request = new EhRequest(); + request.setMethod(EhClient.METHOD_GET_POPULAR); + request.setEhListener(listener); + client.execute(request); } else { try { - int source = Config.getEhSource(); + int source = Settings.getEhSource(); mListUrlBuilder.setPageIndex(page); String url = mListUrlBuilder.build(source); GalleryListListener listener = new GalleryListListener(taskId, type, page, source); listener.setGalleryListHelper(this); mListener = listener; - EhClient.getInstance().getGalleryList(source, url, listener); + + EhRequest request = new EhRequest(); + request.setMethod(EhClient.METHOD_GET_GALLERY_LIST); + request.setEhListener(listener); + request.setArgs(url, source); + + client.execute(request); } catch (UnsupportedSearchException e) { onGetPageData(taskId, e); } @@ -940,7 +952,7 @@ public final class GalleryListScene extends Scene implements SearchBar.Helper, } } - private static class GalleryListListener extends EhClient.OnGetGalleryListListener + private static class GalleryListListener extends EhClient.EhListener implements GalleryListHelperSettable { private int mTaskId; @@ -963,18 +975,18 @@ public final class GalleryListScene extends Scene implements SearchBar.Helper, } @Override - public void onSuccess(List glList, int pageNum) { + public void onSuccess(GalleryListParser.Result result) { if (mHelper != null) { - if (mSource == EhClient.SOURCE_LOFI) { - if (pageNum == GalleryListParser.CURRENT_PAGE_IS_LAST) { + if (mSource == EhUrl.SOURCE_LOFI) { + if (result.pages == GalleryListParser.Result.CURRENT_PAGE_IS_LAST) { mHelper.setPageCount(mTargetPage); } else if (mTaskType == ContentLayout.ContentHelper.TYPE_REFRESH) { mHelper.setPageCount(Integer.MAX_VALUE); } } else { - mHelper.setPageCount(pageNum); + mHelper.setPageCount(result.pages); } - mHelper.onGetPageData(mTaskId, glList); + mHelper.onGetPageData(mTaskId, result.galleryInfos); mHelper.clearLastGalleryListHelperSettable(this); } @@ -988,9 +1000,14 @@ public final class GalleryListScene extends Scene implements SearchBar.Helper, mHelper.clearLastGalleryListHelperSettable(this); } } + + @Override + public void onCanceled() { + + } } - private static class PopularListener extends EhClient.OnGetPopularListener + private static class PopularListener extends EhClient.EhListener implements GalleryListHelperSettable { private int mTaskId; @@ -1006,10 +1023,10 @@ public final class GalleryListScene extends Scene implements SearchBar.Helper, } @Override - public void onSuccess(List glList, long timeStamp) { + public void onSuccess(PopularParser.Result result) { if (mHelper != null) { mHelper.setPageCount(1); - mHelper.onGetPageData(mTaskId, glList); + mHelper.onGetPageData(mTaskId, result.galleryInfos); mHelper.clearLastGalleryListHelperSettable(this); } @@ -1023,6 +1040,11 @@ public final class GalleryListScene extends Scene implements SearchBar.Helper, mHelper.clearLastGalleryListHelperSettable(this); } } + + @Override + public void onCanceled() { + + } } private interface GalleryListHelperSettable { 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 d158a43b5..4550b9c8b 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 @@ -23,9 +23,11 @@ import android.widget.EditText; import android.widget.TextView; import com.hippo.ehviewer.Constants; +import com.hippo.ehviewer.EhApplication; import com.hippo.ehviewer.R; import com.hippo.ehviewer.client.EhClient; -import com.hippo.ehviewer.util.Config; +import com.hippo.ehviewer.client.EhRequest; +import com.hippo.ehviewer.util.Settings; import com.hippo.rippleold.RippleSalon; import com.hippo.scene.Scene; import com.hippo.util.Messenger; @@ -39,11 +41,11 @@ public final class SignInScene extends Scene implements View.OnClickListener, private TextView mSignUp; private TextView mSignIn; - private EhClient.OnSignInListener mSignInListener = new EhClient.OnSignInListener() { + private EhClient.EhListener mSignInListener = new EhClient.EhListener() { @Override public void onSuccess(String displayname) { - Config.putSignIn(true); - Config.putDisplayName(displayname); + Settings.putSignIn(true); + Settings.putDisplayName(displayname); Messenger.getInstance().notify(Constants.MESSENGER_ID_SIGN_IN_OR_OUT, displayname); } @@ -51,6 +53,11 @@ public final class SignInScene extends Scene implements View.OnClickListener, public void onFailure(Exception e) { e.printStackTrace(); } + + @Override + public void onCanceled() { + + } }; @Override @@ -88,7 +95,13 @@ public final class SignInScene extends Scene implements View.OnClickListener, if (v == mSignIn) { String username = mUsername.getText().toString(); String password = mPassword.getText().toString(); - EhClient.getInstance().signIn(username, password, mSignInListener); + EhClient client = EhApplication.getEhClient(getStageActivity()); + + EhRequest request = new EhRequest(); + request.setMethod(EhClient.METHOD_SIGN_IN); + request.setEhListener(mSignInListener); + request.setArgs(username, password); + client.execute(request); } } diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/preference/EHSettingsScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/preference/EHSettingsScene.java index 773427bb4..d83671b1b 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/scene/preference/EHSettingsScene.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/preference/EHSettingsScene.java @@ -18,10 +18,9 @@ package com.hippo.ehviewer.ui.scene.preference; import android.content.res.Resources; -import com.hippo.ehviewer.BuildConfig; import com.hippo.ehviewer.Constants; import com.hippo.ehviewer.R; -import com.hippo.ehviewer.client.EhClient; +import com.hippo.ehviewer.client.EhUrl; import com.hippo.scene.preference.ListPreference; import com.hippo.scene.preference.Preference; import com.hippo.scene.preference.PreferenceCategory; @@ -32,8 +31,7 @@ import com.hippo.util.Messenger; public final class EHSettingsScene extends PreferenceScene { private static final String KEY_EH_SOURCE = "eh_source"; - private static final int DEFAULT_EH_SOURCE = BuildConfig.DEBUG ? - EhClient.SOURCE_EX : EhClient.SOURCE_G; + private static final int DEFAULT_EH_SOURCE = EhUrl.SOURCE_G; @Override protected void onCreate(boolean rebirth) { diff --git a/app/src/main/java/com/hippo/ehviewer/util/EhUtils.java b/app/src/main/java/com/hippo/ehviewer/util/EhUtils.java index e66160b27..a31f30512 100644 --- a/app/src/main/java/com/hippo/ehviewer/util/EhUtils.java +++ b/app/src/main/java/com/hippo/ehviewer/util/EhUtils.java @@ -18,6 +18,8 @@ package com.hippo.ehviewer.util; import android.graphics.Color; +import com.hippo.ehviewer.client.EhConfig; + import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Locale; @@ -29,16 +31,6 @@ public final class EhUtils { public static final String EH_DOWNLOAD_FILENAME = ".ehviewer"; public static final int NONE = -1; // Use it for homepage - public static final int MISC = 0x1; - public static final int DOUJINSHI = 0x2; - public static final int MANGA = 0x4; - public static final int ARTIST_CG = 0x8; - public static final int GAME_CG = 0x10; - public static final int IMAGE_SET = 0x20; - public static final int COSPLAY = 0x40; - public static final int ASIAN_PORN = 0x80; - public static final int NON_H = 0x100; - public static final int WESTERN = 0x200; public static final int UNKNOWN = 0x400; public static final int BG_COLOR_DOUJINSHI = 0xfff44336; @@ -54,16 +46,16 @@ public final class EhUtils { public static final int BG_COLOR_UNKNOWN = Color.BLACK; private static final int[] CATEGORY_VALUES = { - MISC, - DOUJINSHI, - MANGA, - ARTIST_CG, - GAME_CG, - IMAGE_SET, - COSPLAY, - ASIAN_PORN, - NON_H, - WESTERN, + EhConfig.MISC, + EhConfig.DOUJINSHI, + EhConfig.MANGA, + EhConfig.ARTIST_CG, + EhConfig.GAME_CG, + EhConfig.IMAGE_SET, + EhConfig.COSPLAY, + EhConfig.ASIAN_PORN, + EhConfig.NON_H, + EhConfig.WESTERN, UNKNOWN }; private static final String[][] CATEGORY_STRINGS = { @@ -102,25 +94,25 @@ public final class EhUtils { public static int getCategoryColor(int category) { switch (category) { - case DOUJINSHI: + case EhConfig.DOUJINSHI: return BG_COLOR_DOUJINSHI; - case MANGA: + case EhConfig.MANGA: return BG_COLOR_MANGA; - case ARTIST_CG: + case EhConfig.ARTIST_CG: return BG_COLOR_ARTIST_CG; - case GAME_CG: + case EhConfig.GAME_CG: return BG_COLOR_GAME_CG; - case WESTERN: + case EhConfig.WESTERN: return BG_COLOR_WESTERN; - case NON_H: + case EhConfig.NON_H: return BG_COLOR_NON_H; - case IMAGE_SET: + case EhConfig.IMAGE_SET: return BG_COLOR_IMAGE_SET; - case COSPLAY: + case EhConfig.COSPLAY: return BG_COLOR_COSPLAY; - case ASIAN_PORN: + case EhConfig.ASIAN_PORN: return BG_COLOR_ASIAN_PORN; - case MISC: + case EhConfig.MISC: return BG_COLOR_MISC; default: return BG_COLOR_UNKNOWN; diff --git a/app/src/main/java/com/hippo/ehviewer/util/Config.java b/app/src/main/java/com/hippo/ehviewer/util/Settings.java similarity index 76% rename from app/src/main/java/com/hippo/ehviewer/util/Config.java rename to app/src/main/java/com/hippo/ehviewer/util/Settings.java index 0785eb821..795bb8e05 100644 --- a/app/src/main/java/com/hippo/ehviewer/util/Config.java +++ b/app/src/main/java/com/hippo/ehviewer/util/Settings.java @@ -1,11 +1,11 @@ /* - * Copyright (C) 2015 Hippo Seven + * Copyright 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 + * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, @@ -21,64 +21,60 @@ import android.content.SharedPreferences; import android.preference.PreferenceManager; import com.hippo.ehviewer.BuildConfig; -import com.hippo.ehviewer.client.EhClient; +import com.hippo.ehviewer.client.EhConfig; +import com.hippo.ehviewer.client.EhUrl; -public final class Config { +public final class Settings { - private static SharedPreferences sConfigPre; - - private Config() { - } + private static SharedPreferences sSettingsPre; public static void initialize(Context context) { - sConfigPre = PreferenceManager.getDefaultSharedPreferences(context); + sSettingsPre = PreferenceManager.getDefaultSharedPreferences(context); } public static boolean getBoolean(String key, boolean defValue) { - return sConfigPre.getBoolean(key, defValue); + return sSettingsPre.getBoolean(key, defValue); } public static void putBoolean(String key, boolean value) { - sConfigPre.edit().putBoolean(key, value).apply(); + sSettingsPre.edit().putBoolean(key, value).apply(); } public static int getInt(String key, int defValue) { - return sConfigPre.getInt(key, defValue); + return sSettingsPre.getInt(key, defValue); } public static void putInt(String key, int value) { - sConfigPre.edit().putInt(key, value).apply(); + sSettingsPre.edit().putInt(key, value).apply(); } public static long getLong(String key, long defValue) { - return sConfigPre.getLong(key, defValue); + return sSettingsPre.getLong(key, defValue); } public static void putLong(String key, long value) { - sConfigPre.edit().putLong(key, value).apply(); + sSettingsPre.edit().putLong(key, value).apply(); } public static float getFloat(String key, float defValue) { - return sConfigPre.getFloat(key, defValue); + return sSettingsPre.getFloat(key, defValue); } public static void putFloat(String key, float value) { - sConfigPre.edit().putFloat(key, value).apply(); + sSettingsPre.edit().putFloat(key, value).apply(); } public static String getString(String key, String defValue) { - return sConfigPre.getString(key, defValue); + return sSettingsPre.getString(key, defValue); } public static void putString(String key, String value) { - sConfigPre.edit().putString(key, value).apply(); + sSettingsPre.edit().putString(key, value).apply(); } - /****** ******/ - + /****** EH ******/ private static final String KEY_EH_SOURCE = "eh_source"; - private static final int DEFAULT_EH_SOURCE = BuildConfig.DEBUG ? - EhClient.SOURCE_EX : EhClient.SOURCE_G; + private static final int DEFAULT_EH_SOURCE = EhUrl.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"; @@ -92,14 +88,14 @@ public final class Config { public static int getEhSource() { int value = getInt(KEY_EH_SOURCE, DEFAULT_EH_SOURCE); - if (value < EhClient.SOURCE_G || value > EhClient.SOURCE_LOFI) { + if (value < EhUrl.SOURCE_G || value > EhUrl.SOURCE_LOFI) { value = DEFAULT_EH_SOURCE; } return value; } public static void putEhSource(int value) { - if (value < EhClient.SOURCE_G || value > EhClient.SOURCE_LOFI) { + if (value < EhUrl.SOURCE_G || value > EhUrl.SOURCE_LOFI) { value = DEFAULT_EH_SOURCE; } putInt(KEY_EH_SOURCE, value); @@ -152,9 +148,14 @@ public final class Config { } } + /****** EhConfig ******/ + private static EhConfig sEhConfig = new EhConfig(); + + public static EhConfig getEhConfig() { + return sEhConfig; + } /****** Advance ******/ - private static final String KEY_SHOW_APPLICATION_STATS = "show_application_stats"; private static final boolean DEFAULT_SHOW_APPLICATION_STATS = BuildConfig.DEBUG; diff --git a/app/src/main/java/com/hippo/ehviewer/widget/CategoryTable.java b/app/src/main/java/com/hippo/ehviewer/widget/CategoryTable.java index 13a92b7a3..6522ed564 100644 --- a/app/src/main/java/com/hippo/ehviewer/widget/CategoryTable.java +++ b/app/src/main/java/com/hippo/ehviewer/widget/CategoryTable.java @@ -25,7 +25,7 @@ import android.view.ViewGroup; import android.widget.TableLayout; import com.hippo.ehviewer.R; -import com.hippo.ehviewer.util.EhUtils; +import com.hippo.ehviewer.client.EhConfig; import com.hippo.util.Utils; import com.hippo.widget.CheckTextView; @@ -86,16 +86,16 @@ public class CategoryTable extends TableLayout { * @param category target category */ public void setCategory(int category) { - mDoujinshi.setChecked(!Utils.int2boolean(category & EhUtils.DOUJINSHI), false); - mManga.setChecked(!Utils.int2boolean(category & EhUtils.MANGA), false); - mArtistCG.setChecked(!Utils.int2boolean(category & EhUtils.ARTIST_CG), false); - mGameCG.setChecked(!Utils.int2boolean(category & EhUtils.GAME_CG), false); - mWestern.setChecked(!Utils.int2boolean(category & EhUtils.WESTERN), false); - mNonH.setChecked(!Utils.int2boolean(category & EhUtils.NON_H), false); - mImageSets.setChecked(!Utils.int2boolean(category & EhUtils.IMAGE_SET), false); - mCosplay.setChecked(!Utils.int2boolean(category & EhUtils.COSPLAY), false); - mAsianPorn.setChecked(!Utils.int2boolean(category & EhUtils.ASIAN_PORN), false); - mMisc.setChecked(!Utils.int2boolean(category & EhUtils.MISC), false); + mDoujinshi.setChecked(!Utils.int2boolean(category & EhConfig.DOUJINSHI), false); + mManga.setChecked(!Utils.int2boolean(category & EhConfig.MANGA), false); + mArtistCG.setChecked(!Utils.int2boolean(category & EhConfig.ARTIST_CG), false); + mGameCG.setChecked(!Utils.int2boolean(category & EhConfig.GAME_CG), false); + mWestern.setChecked(!Utils.int2boolean(category & EhConfig.WESTERN), false); + mNonH.setChecked(!Utils.int2boolean(category & EhConfig.NON_H), false); + mImageSets.setChecked(!Utils.int2boolean(category & EhConfig.IMAGE_SET), false); + mCosplay.setChecked(!Utils.int2boolean(category & EhConfig.COSPLAY), false); + mAsianPorn.setChecked(!Utils.int2boolean(category & EhConfig.ASIAN_PORN), false); + mMisc.setChecked(!Utils.int2boolean(category & EhConfig.MISC), false); } /** @@ -104,16 +104,16 @@ public class CategoryTable extends TableLayout { */ public int getCategory() { int category = 0; - if (!mDoujinshi.isChecked()) category |= EhUtils.DOUJINSHI; - if (!mManga.isChecked()) category |= EhUtils.MANGA; - if (!mArtistCG.isChecked()) category |= EhUtils.ARTIST_CG; - if (!mGameCG.isChecked()) category |= EhUtils.GAME_CG; - if (!mWestern.isChecked()) category |= EhUtils.WESTERN; - if (!mNonH.isChecked()) category |= EhUtils.NON_H; - if (!mImageSets.isChecked()) category |= EhUtils.IMAGE_SET; - if (!mCosplay.isChecked()) category |= EhUtils.COSPLAY; - if (!mAsianPorn.isChecked()) category |= EhUtils.ASIAN_PORN; - if (!mMisc.isChecked()) category |= EhUtils.MISC; + if (!mDoujinshi.isChecked()) category |= EhConfig.DOUJINSHI; + if (!mManga.isChecked()) category |= EhConfig.MANGA; + if (!mArtistCG.isChecked()) category |= EhConfig.ARTIST_CG; + if (!mGameCG.isChecked()) category |= EhConfig.GAME_CG; + if (!mWestern.isChecked()) category |= EhConfig.WESTERN; + if (!mNonH.isChecked()) category |= EhConfig.NON_H; + if (!mImageSets.isChecked()) category |= EhConfig.IMAGE_SET; + if (!mCosplay.isChecked()) category |= EhConfig.COSPLAY; + if (!mAsianPorn.isChecked()) category |= EhConfig.ASIAN_PORN; + if (!mMisc.isChecked()) category |= EhConfig.MISC; return category; } 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 eaddca445..a1063fa92 100644 --- a/app/src/main/java/com/hippo/ehviewer/widget/DrawerLeftPanel.java +++ b/app/src/main/java/com/hippo/ehviewer/widget/DrawerLeftPanel.java @@ -30,7 +30,7 @@ import android.widget.TextView; import com.hippo.ehviewer.Constants; import com.hippo.ehviewer.R; -import com.hippo.ehviewer.util.Config; +import com.hippo.ehviewer.util.Settings; import com.hippo.rippleold.RippleSalon; import com.hippo.util.Messenger; import com.hippo.widget.DrawerListView; @@ -135,11 +135,11 @@ public class DrawerLeftPanel extends LinearLayout implements FitPaddingImpl { mUserPanelOriginalPaddingTop = mUserPanel.getPaddingTop(); mDrawerListViewOriginalPaddingBottom = mDrawerListView.getPaddingBottom(); - mSignIn = Config.getSignIn(); + mSignIn = Settings.getSignIn(); if (mSignIn) { // TODO mAvatar.setImageResource(DEFAULT_AVATAR_ID); - mUsename.setText(Config.getDisplayName()); + mUsename.setText(Settings.getDisplayName()); mAction.setText(getContext().getString(R.string.signout)); } else { mAvatar.setImageResource(DEFAULT_AVATAR_ID); diff --git a/app/src/main/java/com/hippo/ehviewer/widget/SearchBar.java b/app/src/main/java/com/hippo/ehviewer/widget/SearchBar.java index 9c0f4c445..7f5a2ad7a 100644 --- a/app/src/main/java/com/hippo/ehviewer/widget/SearchBar.java +++ b/app/src/main/java/com/hippo/ehviewer/widget/SearchBar.java @@ -51,8 +51,8 @@ import com.hippo.drawable.DrawerArrowDrawable; import com.hippo.effect.ViewTransition; 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.ehviewer.client.EhUrl; +import com.hippo.ehviewer.util.Settings; import com.hippo.util.MathUtils; import com.hippo.util.Messenger; import com.hippo.util.ViewUtils; @@ -162,7 +162,7 @@ public class SearchBar extends CardView implements View.OnClickListener, } }); - setSource(Config.getEhSource()); + setSource(Settings.getEhSource()); } @Override @@ -192,7 +192,7 @@ public class SearchBar extends CardView implements View.OnClickListener, Drawable searchImage = resources.getDrawable(R.drawable.ic_search); SpannableStringBuilder ssb = new SpannableStringBuilder(" "); ssb.append(String.format(resources.getString(R.string.search_bar_hint), - EhClient.getReadableHost(source))); + EhUrl.getReadableHost(source))); int textSize = (int) (mEditText.getTextSize() * 1.25); searchImage.setBounds(0, 0, textSize, textSize); ssb.setSpan(new ImageSpan(searchImage), 1, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE); diff --git a/app/src/main/java/com/hippo/network/Cookie.java b/app/src/main/java/com/hippo/network/Cookie.java deleted file mode 100644 index bd7824b95..000000000 --- a/app/src/main/java/com/hippo/network/Cookie.java +++ /dev/null @@ -1,86 +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 - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hippo.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/ResponseCodeException.java b/app/src/main/java/com/hippo/network/ResponseCodeException.java deleted file mode 100644 index 5eabfc9ea..000000000 --- a/app/src/main/java/com/hippo/network/ResponseCodeException.java +++ /dev/null @@ -1,87 +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 - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package com.hippo.network; - -import android.util.SparseArray; - -public class ResponseCodeException extends Exception { - - private static final SparseArray ERROR_MESSAGE_ARRAY; - private static final String DEFAULT_ERROR_MESSAGE = "Error response code"; - - private final int mResponseCode; - private final String mMessage; - - static { - ERROR_MESSAGE_ARRAY = new SparseArray<>(24); - - ERROR_MESSAGE_ARRAY.append(400, "Bad Request"); - ERROR_MESSAGE_ARRAY.append(401, "Unauthorized"); - ERROR_MESSAGE_ARRAY.append(402, "Payment Required"); - ERROR_MESSAGE_ARRAY.append(403, "Forbidden"); - ERROR_MESSAGE_ARRAY.append(404, "Not Found"); - ERROR_MESSAGE_ARRAY.append(405, "Method Not Allowed"); - ERROR_MESSAGE_ARRAY.append(406, "Not Acceptable"); - ERROR_MESSAGE_ARRAY.append(407, "Proxy Authentication Required"); - ERROR_MESSAGE_ARRAY.append(408, "Request Timeout"); - ERROR_MESSAGE_ARRAY.append(409, "Conflict"); - ERROR_MESSAGE_ARRAY.append(410, "Gone"); - ERROR_MESSAGE_ARRAY.append(411, "Length Required"); - ERROR_MESSAGE_ARRAY.append(412, "Precondition Failed"); - ERROR_MESSAGE_ARRAY.append(413, "Request Entity Too Large"); - ERROR_MESSAGE_ARRAY.append(414, "Request-URI Too Long"); - ERROR_MESSAGE_ARRAY.append(415, "Unsupported Media Type"); - ERROR_MESSAGE_ARRAY.append(416, "Requested Range Not Satisfiable"); - ERROR_MESSAGE_ARRAY.append(417, "Expectation Failed"); - - ERROR_MESSAGE_ARRAY.append(500, "Internal Server Error"); - ERROR_MESSAGE_ARRAY.append(501, "Not Implemented"); - ERROR_MESSAGE_ARRAY.append(502, "Bad Gateway"); - ERROR_MESSAGE_ARRAY.append(503, "Service Unavailable"); - ERROR_MESSAGE_ARRAY.append(504, "Gateway Timeout"); - ERROR_MESSAGE_ARRAY.append(505, "HTTP Version Not Supported"); - } - - public ResponseCodeException(int responseCode) { - mResponseCode = responseCode; - mMessage = ERROR_MESSAGE_ARRAY.get(responseCode, DEFAULT_ERROR_MESSAGE); - } - - public ResponseCodeException(int responseCode, String message) { - mResponseCode = responseCode; - mMessage = message; - } - - public int getResponseCode() { - return mResponseCode; - } - - public boolean isIdentifiedResponseCode() { - return !DEFAULT_ERROR_MESSAGE.equals(mMessage); - } - - @Override - public String getMessage() { - return mMessage; - } - - @Override - public String getLocalizedMessage() { - return getMessage(); - } - -} diff --git a/app/src/main/java/com/hippo/scene/preference/ListPreference.java b/app/src/main/java/com/hippo/scene/preference/ListPreference.java index ce7fa8afc..df3a34181 100644 --- a/app/src/main/java/com/hippo/scene/preference/ListPreference.java +++ b/app/src/main/java/com/hippo/scene/preference/ListPreference.java @@ -19,7 +19,7 @@ package com.hippo.scene.preference; import android.support.annotation.NonNull; import android.support.v7.widget.RecyclerView; -import com.hippo.ehviewer.util.Config; +import com.hippo.ehviewer.util.Settings; import com.hippo.scene.Scene; import com.hippo.scene.SimpleDialog; @@ -62,7 +62,7 @@ public class ListPreference extends Preference { } private int getValuePosition() { - return getValuePosition(Config.getInt(getKey(), mDefaultValue)); + return getValuePosition(Settings.getInt(getKey(), mDefaultValue)); } private int getValuePosition(int value) { @@ -77,7 +77,7 @@ public class ListPreference extends Preference { @Override protected void storeValue(Object newValue) { - Config.putInt(getKey(), (Integer) newValue); + Settings.putInt(getKey(), (Integer) newValue); } @Override diff --git a/app/src/main/java/com/hippo/scene/preference/SwitchPreference.java b/app/src/main/java/com/hippo/scene/preference/SwitchPreference.java index 75b48b025..127939699 100644 --- a/app/src/main/java/com/hippo/scene/preference/SwitchPreference.java +++ b/app/src/main/java/com/hippo/scene/preference/SwitchPreference.java @@ -24,7 +24,7 @@ import android.view.LayoutInflater; import android.widget.FrameLayout; import com.hippo.ehviewer.R; -import com.hippo.ehviewer.util.Config; +import com.hippo.ehviewer.util.Settings; public class SwitchPreference extends Preference { @@ -59,7 +59,7 @@ public class SwitchPreference extends Preference { } private boolean getValue() { - return Config.getBoolean(getKey(), mDefaultValue); + return Settings.getBoolean(getKey(), mDefaultValue); } private SwitchCompat getSwitch(RecyclerView.ViewHolder viewHolder) { @@ -68,7 +68,7 @@ public class SwitchPreference extends Preference { @Override protected void storeValue(Object newValue) { - Config.putBoolean(getKey(), (Boolean) newValue); + Settings.putBoolean(getKey(), (Boolean) newValue); } @Override diff --git a/app/src/main/java/com/hippo/util/ExceptionUtils.java b/app/src/main/java/com/hippo/util/ExceptionUtils.java index 1ee98cc0b..74d853464 100644 --- a/app/src/main/java/com/hippo/util/ExceptionUtils.java +++ b/app/src/main/java/com/hippo/util/ExceptionUtils.java @@ -23,7 +23,7 @@ import android.support.annotation.Nullable; import com.hippo.ehviewer.R; import com.hippo.ehviewer.client.EhException; -import com.hippo.network.ResponseCodeException; +import com.hippo.httpclient.ResponseCodeException; import org.apache.http.conn.ConnectTimeoutException; diff --git a/app/src/main/res/layout/item_gallery_list_detail.xml b/app/src/main/res/layout/item_gallery_list_detail.xml index 917cb53e9..83a712401 100644 --- a/app/src/main/res/layout/item_gallery_list_detail.xml +++ b/app/src/main/res/layout/item_gallery_list_detail.xml @@ -19,6 +19,7 @@ xmlns:tools="http://schemas.android.com/tools" android:layout_width="wrap_content" android:layout_height="wrap_content" + auto:cardElevation="4dp" auto:forceNoElevation="true">