From fdcf1a0be53ec868c327b232a7b3e7a3f6da6990 Mon Sep 17 00:00:00 2001 From: seven332 Date: Wed, 9 Mar 2016 22:39:42 +0800 Subject: [PATCH] Add WebViewLoginScene --- .../hippo/ehviewer/client/EhCookieStore.java | 19 +-- .../java/com/hippo/ehviewer/client/EhUrl.java | 1 + .../com/hippo/ehviewer/ui/MainActivity.java | 2 + .../hippo/ehviewer/ui/scene/SignInScene.java | 50 +++++- .../ehviewer/ui/scene/WebViewLoginScene.java | 159 ++++++++++++++++++ app/src/main/res/values-zh-rCN/strings.xml | 3 + app/src/main/res/values/strings.xml | 3 + 7 files changed, 223 insertions(+), 14 deletions(-) create mode 100644 app/src/main/java/com/hippo/ehviewer/ui/scene/WebViewLoginScene.java diff --git a/app/src/main/java/com/hippo/ehviewer/client/EhCookieStore.java b/app/src/main/java/com/hippo/ehviewer/client/EhCookieStore.java index 64d0f4c45..05e23df1f 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/EhCookieStore.java +++ b/app/src/main/java/com/hippo/ehviewer/client/EhCookieStore.java @@ -28,8 +28,8 @@ import okhttp3.Request; public class EhCookieStore extends CookieDBStore { - private static final String KEY_IPD_MEMBER_ID = "ipb_member_id"; - private static final String KEY_IPD_PASS_HASH = "ipb_pass_hash"; + public static final String KEY_IPD_MEMBER_ID = "ipb_member_id"; + public static final String KEY_IPD_PASS_HASH = "ipb_pass_hash"; public void cleanUpForSignIn() { removeAll(); @@ -40,14 +40,16 @@ public class EhCookieStore extends CookieDBStore { contain(EhUrl.DOMAIN_EX, KEY_IPD_PASS_HASH); } - private Cookie newCookie(Cookie cookie, String newDomain) { + public static Cookie newCookie(Cookie cookie, String newDomain, boolean forcePersistent, boolean forceNotHostOnly) { Cookie.Builder builder = new Cookie.Builder(); builder.name(cookie.name()); builder.value(cookie.value()); if (cookie.persistent()) { builder.expiresAt(cookie.expiresAt()); + } else if (forcePersistent) { + builder.expiresAt(Long.MAX_VALUE); } - if (cookie.hostOnly()) { + if (cookie.hostOnly() && !forceNotHostOnly) { builder.hostOnlyDomain(newDomain); } else { builder.domain(newDomain); @@ -99,17 +101,10 @@ public class EhCookieStore extends CookieDBStore { for (Cookie cookie: cookies) { if (EhUrl.DOMAIN_E.equals(cookie.domain())) { - // Don't save igneous: mystery. It is for sad panda - if (EhUrl.DOMAIN_E.equals(cookie.domain()) && - "igneous".equals(cookie.name()) && - "mystery".equals(cookie.value())) { - continue; - } - // Save id and hash for exhentai if (KEY_IPD_MEMBER_ID.equals(cookie.name()) || KEY_IPD_PASS_HASH.equals(cookie.name())) { - result.add(newCookie(cookie, EhUrl.DOMAIN_EX)); + result.add(newCookie(cookie, EhUrl.DOMAIN_EX, false, false)); } } diff --git a/app/src/main/java/com/hippo/ehviewer/client/EhUrl.java b/app/src/main/java/com/hippo/ehviewer/client/EhUrl.java index 398c86313..ef02c7180 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/EhUrl.java +++ b/app/src/main/java/com/hippo/ehviewer/client/EhUrl.java @@ -33,6 +33,7 @@ public class EhUrl { public static final String API_EX = HOST_EX + "api.php"; + public static final String URL_SIGN_IN = "http://forums.e-hentai.org/index.php?act=Login"; public static final String URL_FAVORITES = HOST_EX + "favorites.php"; public static String getGalleryDetailUrl(long gid, String token) { diff --git a/app/src/main/java/com/hippo/ehviewer/ui/MainActivity.java b/app/src/main/java/com/hippo/ehviewer/ui/MainActivity.java index b803cd484..0fe4554f8 100644 --- a/app/src/main/java/com/hippo/ehviewer/ui/MainActivity.java +++ b/app/src/main/java/com/hippo/ehviewer/ui/MainActivity.java @@ -53,6 +53,7 @@ import com.hippo.ehviewer.ui.scene.SignInScene; import com.hippo.ehviewer.ui.scene.ProgressScene; import com.hippo.ehviewer.ui.scene.QuickSearchScene; import com.hippo.ehviewer.ui.scene.WarningScene; +import com.hippo.ehviewer.ui.scene.WebViewLoginScene; import com.hippo.scene.Announcer; import com.hippo.scene.SceneFragment; import com.hippo.scene.StageActivity; @@ -91,6 +92,7 @@ public final class MainActivity extends StageActivity registerLaunchMode(WarningScene.class, SceneFragment.LAUNCH_MODE_SINGLE_TASK); registerLaunchMode(AnalyticsScene.class, SceneFragment.LAUNCH_MODE_SINGLE_TASK); registerLaunchMode(SignInScene.class, SceneFragment.LAUNCH_MODE_SINGLE_TASK); + registerLaunchMode(WebViewLoginScene.class, SceneFragment.LAUNCH_MODE_SINGLE_TASK); registerLaunchMode(GalleryListScene.class, SceneFragment.LAUNCH_MODE_SINGLE_TOP); registerLaunchMode(QuickSearchScene.class, SceneFragment.LAUNCH_MODE_SINGLE_TASK); registerLaunchMode(GalleryDetailScene.class, SceneFragment.LAUNCH_MODE_STANDARD); 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 d0d3b3378..81604ec6b 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 @@ -17,11 +17,13 @@ package com.hippo.ehviewer.ui.scene; import android.content.Context; +import android.content.DialogInterface; import android.graphics.Paint; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.design.widget.TextInputLayout; import android.support.v7.app.AlertDialog; +import android.text.TextUtils; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.View; @@ -31,6 +33,7 @@ import android.widget.EditText; import android.widget.TextView; import android.widget.Toast; +import com.hippo.app.EditTextDialogBuilder; import com.hippo.ehviewer.EhApplication; import com.hippo.ehviewer.R; import com.hippo.ehviewer.Settings; @@ -40,6 +43,7 @@ import com.hippo.ehviewer.client.EhRequest; import com.hippo.ehviewer.client.EhUrl; import com.hippo.ehviewer.ui.MainActivity; import com.hippo.rippleold.RippleSalon; +import com.hippo.scene.Announcer; import com.hippo.scene.SceneFragment; import com.hippo.scene.StageActivity; import com.hippo.util.ActivityHelper; @@ -52,6 +56,8 @@ public final class SignInScene extends BaseScene implements EditText.OnEditorAct private static final String KEY_REQUEST_ID = "request_id"; + private static final int REQUEST_CODE_WEBVIEW = 0; + /*--------------- View life cycle ---------------*/ @@ -107,7 +113,6 @@ public final class SignInScene extends BaseScene implements EditText.OnEditorAct outState.putInt(KEY_REQUEST_ID, mRequestId); } - @Nullable @Override public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @@ -161,6 +166,47 @@ public final class SignInScene extends BaseScene implements EditText.OnEditorAct ActivityHelper.showSoftInput(getActivity(), mUsername); } + private void showNoDisplayDialog() { + final EditTextDialogBuilder builder = new EditTextDialogBuilder(getContext(), + "", getString(R.string.display_name)); + builder.setTitle(R.string.display_name_dialog_title); + builder.setPositiveButton(android.R.string.ok, null); + builder.setCancelable(false); + final AlertDialog dialog = builder.show(); + dialog.getButton(DialogInterface.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + String text = builder.getText().trim(); + if (TextUtils.isEmpty(text)) { + builder.setError(getString(R.string.display_name_is_empty)); + } else { + builder.setError(null); + dialog.dismiss(); + // TODO get display name from web + Settings.putDisplayName(text); + redirectTo(); + } + } + }); + } + + @Override + protected void onSceneResult(int requestCode, int resultCode, Bundle data) { + if (REQUEST_CODE_WEBVIEW == requestCode) { + if (RESULT_OK == resultCode) { + String displayName; + if (null == data || null == (displayName = data.getString(WebViewLoginScene.KEY_DISPLAY_NAME))) { + showNoDisplayDialog(); + } else { + Settings.putDisplayName(displayName); + redirectTo(); + } + } + } else { + super.onSceneResult(requestCode, resultCode, data); + } + } + @Override public void onClick(View v) { if (mRegister == v) { @@ -168,7 +214,7 @@ public final class SignInScene extends BaseScene implements EditText.OnEditorAct } else if (mSignIn == v) { signIn(); } else if (mSignInViaWebView == v) { - + startScene(new Announcer(WebViewLoginScene.class).setRequestCode(this, REQUEST_CODE_WEBVIEW)); } else if (mSignInViaCookies == v) { } else if (mSkipSigningIn == v) { diff --git a/app/src/main/java/com/hippo/ehviewer/ui/scene/WebViewLoginScene.java b/app/src/main/java/com/hippo/ehviewer/ui/scene/WebViewLoginScene.java new file mode 100644 index 000000000..c9cd50eee --- /dev/null +++ b/app/src/main/java/com/hippo/ehviewer/ui/scene/WebViewLoginScene.java @@ -0,0 +1,159 @@ +/* + * Copyright 2016 Hippo Seven + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.hippo.ehviewer.ui.scene; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.os.Bundle; +import android.support.annotation.Nullable; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.webkit.CookieManager; +import android.webkit.JavascriptInterface; +import android.webkit.WebView; +import android.webkit.WebViewClient; + +import com.hippo.ehviewer.EhApplication; +import com.hippo.ehviewer.client.EhCookieStore; +import com.hippo.ehviewer.client.EhUrl; +import com.hippo.ehviewer.client.parser.SignInParser; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import okhttp3.Cookie; +import okhttp3.HttpUrl; + +public class WebViewLoginScene extends BaseScene { + + public static final String KEY_DISPLAY_NAME = "display_name"; + + /*--------------- + View life cycle + ---------------*/ + @Nullable + private WebView mWebView; + + @Override + public boolean needShowLeftDrawer() { + return false; + } + + @Nullable + @Override + @SuppressLint({"SetJavaScriptEnabled", "AddJavascriptInterface"}) + public View onCreateView(LayoutInflater inflater, + @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { + EhApplication.getEhCookieStore(getContext()).removeAll(); + CookieManager.getInstance().removeAllCookie(); + mWebView = new WebView(getContext()); + mWebView.getSettings().setJavaScriptEnabled(true); + mWebView.addJavascriptInterface(new MyJavaScriptInterface(), "HTMLOUT"); + mWebView.setWebViewClient(new LoginWebViewClient()); + mWebView.loadUrl(EhUrl.URL_SIGN_IN); + return mWebView; + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + + if (null != mWebView) { + mWebView.destroy(); + mWebView = null; + } + } + + private class LoginWebViewClient extends WebViewClient { + + public List parseCookies(HttpUrl url, String cookieStrings) { + if (cookieStrings == null) { + return Collections.emptyList(); + } + + List cookies = null; + String[] pieces = cookieStrings.split(";"); + for (String piece: pieces) { + Cookie cookie = Cookie.parse(url, piece); + if (cookie == null) { + continue; + } + if (cookies == null) { + cookies = new ArrayList<>(); + } + cookies.add(cookie); + } + + return cookies != null ? cookies : Collections.emptyList(); + } + + private void addCookie(Context context, String domain, Cookie cookie) { + EhApplication.getEhCookieStore(context).add(EhCookieStore.newCookie(cookie, domain, true, true)); + } + + @Override + public void onPageFinished(WebView view, String url) { + Context context = getContext(); + if (context == null) { + return; + } + HttpUrl httpUrl = HttpUrl.parse(url); + if (httpUrl == null) { + return; + } + + String cookieString = CookieManager.getInstance().getCookie(url); + List cookies = parseCookies(httpUrl, cookieString); + boolean getId = false; + boolean getHash = false; + for (Cookie cookie: cookies) { + if (EhCookieStore.KEY_IPD_MEMBER_ID.equals(cookie.name())) { + getId = true; + addCookie(context, EhUrl.DOMAIN_EX, cookie); + addCookie(context, EhUrl.DOMAIN_E, cookie); + } else if (EhCookieStore.KEY_IPD_PASS_HASH.equals(cookie.name())) { + getHash = true; + addCookie(context, EhUrl.DOMAIN_EX, cookie); + addCookie(context, EhUrl.DOMAIN_E, cookie); + } + } + + if (getId && getHash) { + // Get content + view.loadUrl("javascript:window.HTMLOUT.processHTML(''+document.getElementsByTagName('html')[0].innerHTML+'');"); + } + } + } + + private class MyJavaScriptInterface { + + @JavascriptInterface + public void processHTML(String html) { + try { + String displayName = SignInParser.parse(html); + Bundle bundle = new Bundle(); + bundle.putString(KEY_DISPLAY_NAME, displayName); + setResult(RESULT_OK, bundle); + finish(); + } catch (Exception e) { + // TODO NO ask username + } + } + } +} diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index bbf1af6ec..948e909d8 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -33,6 +33,9 @@ 注册 通过网页登陆 通过 Cookie 登陆 + 输入昵称 + 昵称 + 昵称为空 错误的状态码:%d 超时 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c51ac4c18..ad44f547d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -46,6 +46,9 @@ Register Sign in via WebView Sign in via cookies + Enter Display Name + Display name + Display name is empty Bad Request Unauthorized