Add recaptcha

This commit is contained in:
seven332 committed 2017-09-06 16:49:48 +08:00
1 parent 550d3735c7
commit 2c3fa31e91
29 files changed
+1591 -519

No files matched your search

+3
View File
@@ -55,6 +55,7 @@ dependencies {
compile "com.android.support:appcompat-v7:$supportLibrary"
compile "com.android.support:design:$supportLibrary"
compile 'com.github.amlcurran.showcaseview:library:5.4.3'
compile 'com.github.seven332:android-recaptcha:2bbb3459a8'
compile 'com.github.seven332:animator:0.1.0'
compile 'com.github.seven332:beerbelly:0.1.4'
compile 'com.github.seven332:conaco:0.1.5-eh'
@@ -79,4 +80,6 @@ dependencies {
compile 'org.greenrobot:greendao:2.2.0'
compile 'org.jsoup:jsoup:1.9.2'
testCompile 'junit:junit:4.12'
testCompile 'org.robolectric:robolectric:3.4'
testCompile 'org.jooq:joor:0.9.6'
}
@@ -0,0 +1,130 @@
/*
* Copyright 2017 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.database;
/*
* Created by Hippo on 2017/9/3.
*/
import android.content.Context;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.SparseArray;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MSQLiteBuilder {
public static final String COLUMN_ID = "_id";
private static final Map<Class, String> JAVA_TYPE_TO_SQLITE_TYPE = new HashMap<>();
static {
JAVA_TYPE_TO_SQLITE_TYPE.put(boolean.class, "INTEGER NOT NULL DEFAULT 0");
JAVA_TYPE_TO_SQLITE_TYPE.put(byte.class, "INTEGER NOT NULL DEFAULT 0");
JAVA_TYPE_TO_SQLITE_TYPE.put(short.class, "INTEGER NOT NULL DEFAULT 0");
JAVA_TYPE_TO_SQLITE_TYPE.put(int.class, "INTEGER NOT NULL DEFAULT 0");
JAVA_TYPE_TO_SQLITE_TYPE.put(long.class, "INTEGER NOT NULL DEFAULT 0");
JAVA_TYPE_TO_SQLITE_TYPE.put(float.class, "REAL NOT NULL DEFAULT 0");
JAVA_TYPE_TO_SQLITE_TYPE.put(double.class, "REAL NOT NULL DEFAULT 0");
JAVA_TYPE_TO_SQLITE_TYPE.put(String.class, "TEXT");
}
private static String javaTypeToSQLiteType(Class clazz) {
String type = JAVA_TYPE_TO_SQLITE_TYPE.get(clazz);
if (type == null) {
throw new IllegalStateException("Unknown type: " + clazz);
}
return type;
}
private int version = 0;
private List<String> statements;
private SparseArray<List<String>> statementsMap = new SparseArray<>();
/**
* Bump database version.
*/
public MSQLiteBuilder version(int version) {
if (version <= this.version) {
throw new IllegalStateException("New version must be bigger than current version. "
+ "current version: " + this.version + ", new version: " + version + ".");
}
this.version = version;
this.statements = new ArrayList<>();
this.statementsMap.put(version, this.statements);
return this;
}
/**
* Creates a table with int {@link #COLUMN_ID} primary key.
*/
public MSQLiteBuilder createTable(String table) {
return createTable(table, COLUMN_ID, int.class);
}
/**
* Creates a table.
*/
public MSQLiteBuilder createTable(String table, String column, Class clazz) {
return statement("CREATE TABLE " + table + " (" + column + " " + javaTypeToSQLiteType(clazz) + " PRIMARY KEY);");
}
/**
* Drops a table.
*/
public MSQLiteBuilder dropTable(String table) {
return statement("DROP TABLE " + table + ";");
}
/**
* Inserts a column to the table.
*/
public MSQLiteBuilder insertColumn(String table, String column, Class clazz) {
return statement("ALTER TABLE " + table + " ADD COLUMN " + column + " " + javaTypeToSQLiteType(clazz) + ";");
}
/**
* Add a statement.
*/
public MSQLiteBuilder statement(String statement) {
if (version == 0 || statements == null) {
throw new IllegalStateException("Call version() first!");
}
statements.add(statement);
return this;
}
/**
* Build a SQLiteOpenHelper from it.
*/
public SQLiteOpenHelper build(Context context, String name, int version) {
return new MSQLiteOpenHelper(context, name, version, this);
}
List<String> getStatements(int oldVersion, int newVersion) {
List<String> result = new ArrayList<>();
for (int i = oldVersion + 1; i <= newVersion; ++i) {
List<String> list = statementsMap.get(i);
if (list != null) {
result.addAll(list);
}
}
return result;
}
}
@@ -0,0 +1,56 @@
/*
* Copyright 2017 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.database;
/*
* Created by Hippo on 2017/9/4.
*/
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import com.hippo.util.SqlUtils;
class MSQLiteOpenHelper extends SQLiteOpenHelper {
private final int version;
private final MSQLiteBuilder builder;
public MSQLiteOpenHelper(Context context, String name, int version, MSQLiteBuilder builder) {
super(context, name, null, version);
this.version = version;
this.builder = builder;
}
@Override
public void onCreate(SQLiteDatabase db) {
onUpgrade(db, 0, version);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
for (String command : builder.getStatements(oldVersion, newVersion)) {
db.execSQL(command);
}
}
@Override
public void onDowngrade(SQLiteDatabase db, int oldVersion, int newVersion) {
SqlUtils.dropAllTable(db);
onCreate(db);
}
}
@@ -0,0 +1,140 @@
/*
* Copyright 2017 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.drawable;
/*
* Created by Hippo on 2017/9/6.
*/
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ColorFilter;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.support.annotation.IntRange;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.text.TextUtils;
public class TextDrawable extends Drawable {
private static final float STANDARD_TEXT_SIZE = 1000.0f;
private static final Paint STANDARD_PAINT = new Paint();
static {
STANDARD_PAINT.setTextSize(STANDARD_TEXT_SIZE);
}
private String text;
private float contentPercent;
private Paint backgroundPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Paint textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private int textColor = Color.BLACK;
private int backgroundColor = Color.BLACK;
private float x = 0.0f;
private float y = 0.0f;
private boolean textSizeDirty = false;
private Rect textBounds = new Rect();
public TextDrawable(String text, float contentPercent) {
this.text = text;
this.contentPercent = contentPercent;
STANDARD_PAINT.getTextBounds(text, 0, text.length(), textBounds);
}
public int getTextColor() {
return textColor;
}
public void setTextColor(int textColor) {
if (this.textColor != textColor) {
this.textColor = textColor;
invalidateSelf();
}
}
public int getBackgroundColor() {
return backgroundColor;
}
public void setBackgroundColor(int backgroundColor) {
if (this.backgroundColor != backgroundColor) {
this.backgroundColor = backgroundColor;
invalidateSelf();
}
}
@Override
protected void onBoundsChange(Rect bounds) {
super.onBoundsChange(bounds);
textSizeDirty = true;
}
private void updateTextSizeIfDirty(Rect bounds) {
if (!textSizeDirty) {
return;
}
textSizeDirty = false;
int contentWidth = (int) (bounds.width() * contentPercent);
int contentHeight = (int) (bounds.height() * contentPercent);
float widthRatio = (float) contentWidth / (float) textBounds.width();
float heightRatio = (float) contentHeight / (float) textBounds.height();
float ratio = Math.min(widthRatio, heightRatio);
float textSize = STANDARD_TEXT_SIZE * ratio;
textPaint.setTextSize(textSize);
x = (bounds.width() - textBounds.width() * ratio) / 2 - textBounds.left * ratio;
y = (bounds.height() - textBounds.height() * ratio) / 2 - textBounds.top * ratio;
}
@Override
public void draw(@NonNull Canvas canvas) {
Rect bounds = getBounds();
if (!bounds.isEmpty()) {
// Draw background
backgroundPaint.setColor(backgroundColor);
canvas.drawRect(bounds, backgroundPaint);
if (!TextUtils.isEmpty(text)) {
// Draw text
updateTextSizeIfDirty(bounds);
textPaint.setColor(textColor);
canvas.drawText(text, x, y, textPaint);
}
}
}
@Override
public void setAlpha(@IntRange(from = 0, to = 255) int alpha) {}
@Override
public void setColorFilter(@Nullable ColorFilter colorFilter) {
backgroundPaint.setColorFilter(colorFilter);
textPaint.setColorFilter(colorFilter);
invalidateSelf();
}
@Override
public int getOpacity() {
return PixelFormat.TRANSLUCENT;
}
}
@@ -32,7 +32,6 @@ import com.hippo.conaco.Conaco;
import com.hippo.ehviewer.client.EhClient;
import com.hippo.ehviewer.client.EhCookieStore;
import com.hippo.ehviewer.client.EhEngine;
import com.hippo.ehviewer.client.EhUrl;
import com.hippo.ehviewer.client.data.GalleryDetail;
import com.hippo.ehviewer.download.DownloadManager;
import com.hippo.ehviewer.spider.SpiderDen;
@@ -40,7 +39,6 @@ import com.hippo.ehviewer.ui.CommonOperations;
import com.hippo.image.Image;
import com.hippo.image.ImageBitmap;
import com.hippo.network.StatusCodeException;
import com.hippo.okhttp.CookieDB;
import com.hippo.scene.SceneApplication;
import com.hippo.text.Html;
import com.hippo.unifile.UniFile;
@@ -58,8 +56,6 @@ import java.util.HashMap;
import java.util.List;
import java.util.concurrent.TimeUnit;
import okhttp3.Cookie;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
public class EhApplication extends SceneApplication implements Thread.UncaughtExceptionHandler {
@@ -97,7 +93,6 @@ public class EhApplication extends SceneApplication implements Thread.UncaughtEx
super.onCreate();
GetText.initialize(this);
CookieDB.initialize(this);
StatusCodeException.initialize(this);
Settings.initialize(this);
ReadableTime.initialize(this);
@@ -159,29 +154,6 @@ public class EhApplication extends SceneApplication implements Thread.UncaughtEx
if (version < 52) {
Settings.putGuideGallery(true);
}
if (version < 56) { // Make cookie long live
HttpUrl eUrl = HttpUrl.parse(EhUrl.HOST_E);
HttpUrl exUrl = HttpUrl.parse(EhUrl.HOST_EX);
EhCookieStore cookieStore = getEhCookieStore(this);
Cookie c;
c = cookieStore.get(eUrl, EhCookieStore.KEY_IPD_MEMBER_ID);
if (null != c) {
cookieStore.add(EhCookieStore.newCookie(c, c.domain(), true, true, true));
}
c = cookieStore.get(eUrl, EhCookieStore.KEY_IPD_PASS_HASH);
if (null != c) {
cookieStore.add(EhCookieStore.newCookie(c, c.domain(), true, true, true));
}
c = cookieStore.get(exUrl, EhCookieStore.KEY_IPD_MEMBER_ID);
if (null != c) {
cookieStore.add(EhCookieStore.newCookie(c, c.domain(), true, true, true));
}
c = cookieStore.get(exUrl, EhCookieStore.KEY_IPD_PASS_HASH);
if (null != c) {
cookieStore.add(EhCookieStore.newCookie(c, c.domain(), true, true, true));
}
}
}
public void clearMemoryCache() {
@@ -243,7 +215,7 @@ public class EhApplication extends SceneApplication implements Thread.UncaughtEx
public static EhCookieStore getEhCookieStore(@NonNull Context context) {
EhApplication application = ((EhApplication) context.getApplicationContext());
if (application.mEhCookieStore == null) {
application.mEhCookieStore = new EhCookieStore();
application.mEhCookieStore = new EhCookieStore(context);
}
return application.mEhCookieStore;
}
@@ -153,7 +153,7 @@ public class EhClient {
try {
switch (mMethod) {
case METHOD_SIGN_IN:
return EhEngine.signIn(this, mOkHttpClient, (String) params[0], (String) params[1]);
return EhEngine.signIn(this, mOkHttpClient, (String) params[0], (String) params[1], (String) params[2], (String) params[3]);
case METHOD_GET_GALLERY_LIST:
return EhEngine.getGalleryList(this, mOkHttpClient, (String) params[0]);
case METHOD_FILL_GALLERY_LIST_BY_API:
@@ -16,7 +16,9 @@
package com.hippo.ehviewer.client;
import com.hippo.okhttp.CookieDBStore;
import android.content.Context;
import com.hippo.network.CookieRepository;
import java.util.ArrayList;
import java.util.Collections;
@@ -26,7 +28,7 @@ import okhttp3.Cookie;
import okhttp3.HttpUrl;
import okhttp3.Request;
public class EhCookieStore extends CookieDBStore {
public class EhCookieStore extends CookieRepository {
public static final String KEY_IPD_MEMBER_ID = "ipb_member_id";
public static final String KEY_IPD_PASS_HASH = "ipb_pass_hash";
@@ -41,13 +43,18 @@ public class EhCookieStore extends CookieDBStore {
.expiresAt(Long.MAX_VALUE)
.build();
public EhCookieStore(Context context) {
super(context, "okhttp3-cookie.db");
}
public void signOut() {
removeAll();
clear();
}
public boolean hasSignedIn() {
return contain(EhUrl.DOMAIN_EX, KEY_IPD_MEMBER_ID) &&
contain(EhUrl.DOMAIN_EX, KEY_IPD_PASS_HASH);
HttpUrl url = HttpUrl.parse(EhUrl.HOST_E);
return contains(url, KEY_IPD_MEMBER_ID) &&
contains(url, KEY_IPD_PASS_HASH);
}
public static Cookie newCookie(Cookie cookie, String newDomain, boolean forcePersistent,
@@ -82,10 +89,9 @@ public class EhCookieStore extends CookieDBStore {
public List<Cookie> loadForRequest(HttpUrl url, Request request) {
List<Cookie> cookies = super.loadForRequest(url, request);
Object tag = request.tag();
String host = url.host();
boolean checkTips = domainMatch(host, EhUrl.DOMAIN_E);
boolean checkUconfig = (domainMatch(host, EhUrl.DOMAIN_E) || domainMatch(host, EhUrl.DOMAIN_EX)) && tag instanceof EhConfig;
boolean checkTips = domainMatch(url, EhUrl.DOMAIN_E);
boolean checkUconfig = (domainMatch(url, EhUrl.DOMAIN_E) || domainMatch(url, EhUrl.DOMAIN_EX)) && tag instanceof EhConfig;
if (checkTips || checkUconfig) {
List<Cookie> result = new ArrayList<>(cookies.size() + 1);
@@ -109,7 +115,7 @@ public class EhCookieStore extends CookieDBStore {
Cookie uconfigCookie = new Cookie.Builder()
.name(EhConfig.KEY_UCONFIG)
.value(ehConfig.uconfig())
.domain(host)
.domain(url.host())
.path("/")
.expiresAt(Long.MAX_VALUE)
.build();
@@ -120,26 +126,4 @@ public class EhCookieStore extends CookieDBStore {
return cookies;
}
}
@Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
List<Cookie> result = new ArrayList<>(cookies.size() + 2);
for (Cookie cookie: cookies) {
if (EhUrl.DOMAIN_E.equals(cookie.domain())) {
// Save id and hash for exhentai
if (KEY_IPD_MEMBER_ID.equals(cookie.name()) ||
KEY_IPD_PASS_HASH.equals(cookie.name()) ||
KEY_IGNEOUS.equals(cookie.name())) {
result.add(newCookie(cookie, EhUrl.DOMAIN_E, true, true, true));
result.add(newCookie(cookie, EhUrl.DOMAIN_EX, true, true, true));
continue;
}
}
result.add(cookie);
}
super.saveFromResponse(url, Collections.unmodifiableList(result));
}
}
@@ -17,6 +17,7 @@
package com.hippo.ehviewer.client;
import android.support.annotation.Nullable;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
@@ -120,13 +121,17 @@ public class EhEngine {
}
public static String signIn(@Nullable EhClient.Task task, OkHttpClient okHttpClient,
String username, String password) throws Exception {
String username, String password, String recaptchaChallenge, String recaptchaResponse) throws Exception {
FormBody.Builder builder = new FormBody.Builder()
.add("UserName", username)
.add("PassWord", password)
.add("submit", "Log me in")
.add("CookieDate", "1")
.add("temporary_https", "off");
if (!TextUtils.isEmpty(recaptchaChallenge) && !TextUtils.isEmpty(recaptchaResponse)) {
builder.add("recaptcha_challenge_field", recaptchaChallenge);
builder.add("recaptcha_response_field", recaptchaResponse);
}
String url = EhUrl.API_SIGN_IN;
Log.d(TAG, url);
Request request = new EhRequestBuilder(url, null != task ? task.getEhConfig() : Settings.getEhConfig())
@@ -30,16 +30,13 @@ import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.TextView;
import com.hippo.ehviewer.EhApplication;
import com.hippo.ehviewer.R;
import com.hippo.ehviewer.client.EhCookieStore;
import com.hippo.ehviewer.client.EhUrl;
import com.hippo.ehviewer.client.EhUtils;
import com.hippo.yorozuya.ViewUtils;
import junit.framework.Assert;
import okhttp3.Cookie;
public class CookieSignInScene extends SolidScene implements EditText.OnEditorActionListener,
@@ -241,11 +238,11 @@ public class CookieSignInScene extends SolidScene implements EditText.OnEditorAc
EhUtils.signOut(context);
EhCookieStore store = EhApplication.getEhCookieStore(context);
store.add(newCookie(EhCookieStore.KEY_IPD_MEMBER_ID, id, EhUrl.DOMAIN_E));
store.add(newCookie(EhCookieStore.KEY_IPD_MEMBER_ID, id, EhUrl.DOMAIN_EX));
store.add(newCookie(EhCookieStore.KEY_IPD_PASS_HASH, hash, EhUrl.DOMAIN_E));
store.add(newCookie(EhCookieStore.KEY_IPD_PASS_HASH, hash, EhUrl.DOMAIN_EX));
store.add(newCookie(EhCookieStore.KEY_IGNEOUS, igneous, EhUrl.DOMAIN_E));
store.add(newCookie(EhCookieStore.KEY_IGNEOUS, igneous, EhUrl.DOMAIN_EX));
store.addCookie(newCookie(EhCookieStore.KEY_IPD_MEMBER_ID, id, EhUrl.DOMAIN_E));
store.addCookie(newCookie(EhCookieStore.KEY_IPD_MEMBER_ID, id, EhUrl.DOMAIN_EX));
store.addCookie(newCookie(EhCookieStore.KEY_IPD_PASS_HASH, hash, EhUrl.DOMAIN_E));
store.addCookie(newCookie(EhCookieStore.KEY_IPD_PASS_HASH, hash, EhUrl.DOMAIN_EX));
store.addCookie(newCookie(EhCookieStore.KEY_IGNEOUS, igneous, EhUrl.DOMAIN_E));
store.addCookie(newCookie(EhCookieStore.KEY_IGNEOUS, igneous, EhUrl.DOMAIN_EX));
}
}
@@ -40,6 +40,7 @@ import com.hippo.ehviewer.client.EhUrl;
import com.hippo.ehviewer.client.EhUtils;
import com.hippo.ehviewer.client.parser.ProfileParser;
import com.hippo.ehviewer.ui.MainActivity;
import com.hippo.ehviewer.widget.RecaptchaView;
import com.hippo.scene.Announcer;
import com.hippo.scene.SceneFragment;
import com.hippo.yorozuya.IntIdGenerator;
@@ -68,6 +69,8 @@ public final class SignInScene extends SolidScene implements EditText.OnEditorAc
private EditText mUsername;
@Nullable
private EditText mPassword;
private EditText mRecaptcha;
private RecaptchaView mRecaptchaView;
@Nullable
private View mRegister;
@Nullable
@@ -125,6 +128,8 @@ public final class SignInScene extends SolidScene implements EditText.OnEditorAc
mPasswordLayout = (TextInputLayout) ViewUtils.$$(loginForm, R.id.password_layout);
mPassword = mPasswordLayout.getEditText();
Assert.assertNotNull(mPassword);
mRecaptcha = (EditText) ViewUtils.$$(loginForm, R.id.recaptcha);
mRecaptchaView = (RecaptchaView) ViewUtils.$$(loginForm, R.id.recaptcha_image);
mRegister = ViewUtils.$$(loginForm, R.id.register);
mSignIn = ViewUtils.$$(loginForm, R.id.sign_in);
mSignInViaWebView = (TextView) ViewUtils.$$(loginForm, R.id.sign_in_via_webview);
@@ -280,12 +285,15 @@ public final class SignInScene extends SolidScene implements EditText.OnEditorAc
// Clean up for sign in
EhUtils.signOut(context);
String challenge = mRecaptchaView.getChallenge();
String response = mRecaptcha.getText().toString();
EhCallback callback = new SignInListener(context,
activity.getStageId(), getTag());
mRequestId = ((EhApplication) context.getApplicationContext()).putGlobalStuff(callback);
EhRequest request = new EhRequest()
.setMethod(EhClient.METHOD_SIGN_IN)
.setArgs(username, password)
.setArgs(username, password, challenge, response)
.setCallback(callback);
EhApplication.getEhClient(context).execute(request);
@@ -28,18 +28,14 @@ import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
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.EhUtils;
import junit.framework.Assert;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import junit.framework.Assert;
import okhttp3.Cookie;
import okhttp3.HttpUrl;
@@ -122,7 +118,7 @@ public class WebViewSignInScene extends SolidScene {
}
private void addCookie(Context context, String domain, Cookie cookie) {
EhApplication.getEhCookieStore(context).add(EhCookieStore.newCookie(cookie, domain, true, true, true));
EhApplication.getEhCookieStore(context).addCookie(EhCookieStore.newCookie(cookie, domain, true, true, true));
}
@Override
@@ -149,6 +145,9 @@ public class WebViewSignInScene extends SolidScene {
getHash = true;
addCookie(context, EhUrl.DOMAIN_EX, cookie);
addCookie(context, EhUrl.DOMAIN_E, cookie);
} else if (EhCookieStore.KEY_IGNEOUS.equals(cookie.name())) {
addCookie(context, EhUrl.DOMAIN_EX, cookie);
addCookie(context, EhUrl.DOMAIN_E, cookie);
}
}
@@ -0,0 +1,183 @@
/*
* Copyright 2017 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.widget;
/*
* Created by Hippo on 2017/8/20.
*/
import android.content.Context;
import android.graphics.Color;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;
import com.hippo.android.recaptcha.RecaptchaV1;
import com.hippo.drawable.TextDrawable;
import com.hippo.ehviewer.R;
import com.hippo.widget.LoadImageView;
import com.hippo.yorozuya.SimpleHandler;
public class RecaptchaView extends LoadImageView implements RecaptchaV1.RecaptchaCallback, View.OnClickListener {
private static final String CHALLENGE = "6LdtfgYAAAAAALjIPPiCgPJJah8MhAUpnHcKF8u_";
private boolean loading = false;
private String challenge;
private String image;
private TextDrawable waitingDrawable;
private TextDrawable loadingDrawable;
private TextDrawable failureDrawable;
public RecaptchaView(Context context) {
super(context);
init();
}
public RecaptchaView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
private void init() {
setOnClickListener(this);
if (waitingDrawable == null) {
waitingDrawable = new TextDrawable(getContext().getString(R.string.recaptcha_none), 0.6f);
waitingDrawable.setBackgroundColor(Color.GRAY);
waitingDrawable.setTextColor(Color.WHITE);
}
load(waitingDrawable);
}
public String getChallenge() {
return challenge;
}
public void load() {
if (loading) {
return;
}
loading = false;
challenge = null;
image = null;
if (loadingDrawable == null) {
loadingDrawable = new TextDrawable(getContext().getString(R.string.recaptcha_loading), 0.6f);
loadingDrawable.setBackgroundColor(Color.GRAY);
loadingDrawable.setTextColor(Color.WHITE);
}
load(loadingDrawable);
RecaptchaV1.recaptcha(getContext(), CHALLENGE, SimpleHandler.getInstance(), this);
}
@Override
public void onClick(@NonNull View v) {
load();
}
@Override
public void onSuccess(@NonNull String challenge, @NonNull String image) {
this.loading = false;
this.challenge = challenge;
this.image = image;
load(image, image);
}
@Override
public void onFailure() {
this.loading = false;
this.challenge = null;
this.image = null;
if (failureDrawable == null) {
failureDrawable = new TextDrawable(getContext().getString(R.string.recaptcha_failure), 0.6f);
failureDrawable.setBackgroundColor(Color.GRAY);
failureDrawable.setTextColor(Color.WHITE);
}
load(failureDrawable);
}
@Override
protected Parcelable onSaveInstanceState() {
SavedState ss = new SavedState(super.onSaveInstanceState());
ss.loading = loading;
ss.challenge = challenge;
ss.image = image;
return ss;
}
@Override
protected void onRestoreInstanceState(Parcelable state) {
if (!(state instanceof SavedState)) {
super.onRestoreInstanceState(state);
return;
}
SavedState ss = (SavedState) state;
super.onRestoreInstanceState(ss.getSuperState());
if (ss.loading) {
load();
} else if (!TextUtils.isEmpty(ss.challenge) && !TextUtils.isEmpty(ss.image)) {
onSuccess(ss.challenge, ss.image);
}
}
private static class SavedState extends BaseSavedState {
private boolean loading;
private String challenge;
private String image;
public SavedState(Parcelable superState) {
super(superState);
}
@Override
public void writeToParcel(Parcel out, int flags) {
super.writeToParcel(out, flags);
out.writeByte(loading ? (byte) 1 : (byte) 0);
out.writeString(challenge);
out.writeString(image);
}
public static final Parcelable.Creator<SavedState> CREATOR
= new Parcelable.Creator<SavedState>() {
@Override
public SavedState createFromParcel(Parcel in) {
return new SavedState(in);
}
@Override
public SavedState[] newArray(int size) {
return new SavedState[size];
}
};
public SavedState(Parcel source) {
super(source);
loading = source.readByte() != 0;
challenge = source.readString();
image = source.readString();
}
}
}
@@ -0,0 +1,236 @@
/*
* Copyright 2017 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;
/*
* Created by Hippo on 2017/9/4.
*/
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteStatement;
import android.support.annotation.Nullable;
import android.util.Log;
import com.hippo.database.MSQLiteBuilder;
import com.hippo.util.SqlUtils;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import okhttp3.Cookie;
class CookieDatabase {
private static final String LOG_TAG = CookieDatabase.class.getSimpleName();
private static final int VERSION_1 = 1;
private static final String TABLE_COOKIE = "OK_HTTP_3_COOKIE";
private static final String COLUMN_ID = "_id";
private static final String COLUMN_NAME = "NAME";
private static final String COLUMN_VALUE = "VALUE";
private static final String COLUMN_EXPIRES_AT = "EXPIRES_AT";
private static final String COLUMN_DOMAIN = "DOMAIN";
private static final String COLUMN_PATH = "PATH";
private static final String COLUMN_SECURE = "SECURE";
private static final String COLUMN_HTTP_ONLY = "HTTP_ONLY";
private static final String COLUMN_PERSISTENT = "PERSISTENT";
private static final String COLUMN_HOST_ONLY = "HOST_ONLY";
private static final int DB_VERSION = VERSION_1;
private final Map<Cookie, Long> cookieIdMap = new HashMap<>();
private final SQLiteOpenHelper helper;
private final SQLiteDatabase db;
public CookieDatabase(Context context, String name) {
helper = new MSQLiteBuilder()
.version(VERSION_1)
.createTable(TABLE_COOKIE)
.insertColumn(TABLE_COOKIE, COLUMN_NAME, String.class)
.insertColumn(TABLE_COOKIE, COLUMN_VALUE, String.class)
.insertColumn(TABLE_COOKIE, COLUMN_EXPIRES_AT, long.class)
.insertColumn(TABLE_COOKIE, COLUMN_DOMAIN, String.class)
.insertColumn(TABLE_COOKIE, COLUMN_PATH, String.class)
.insertColumn(TABLE_COOKIE, COLUMN_SECURE, boolean.class)
.insertColumn(TABLE_COOKIE, COLUMN_HTTP_ONLY, boolean.class)
.insertColumn(TABLE_COOKIE, COLUMN_PERSISTENT, boolean.class)
.insertColumn(TABLE_COOKIE, COLUMN_HOST_ONLY, boolean.class)
.build(context, name, DB_VERSION);
db = helper.getWritableDatabase();
}
@Nullable
private static Cookie getCookie(Cursor cursor, long now) {
String name = SqlUtils.getString(cursor, COLUMN_NAME, null);
String value = SqlUtils.getString(cursor, COLUMN_VALUE, null);
long expiresAt = SqlUtils.getLong(cursor, COLUMN_EXPIRES_AT, 0);
String domain = SqlUtils.getString(cursor, COLUMN_DOMAIN, null);
String path = SqlUtils.getString(cursor, COLUMN_PATH, null);
boolean secure = SqlUtils.getBoolean(cursor, COLUMN_SECURE, false);
boolean httpOnly = SqlUtils.getBoolean(cursor, COLUMN_HTTP_ONLY, false);
boolean persistent = SqlUtils.getBoolean(cursor, COLUMN_PERSISTENT, false);
boolean hostOnly = SqlUtils.getBoolean(cursor, COLUMN_HOST_ONLY, false);
if (name == null || domain == null || path == null) {
return null;
}
// Check non-persistent or expired
if (!persistent || expiresAt <= now) {
return null;
}
Cookie.Builder builder = new Cookie.Builder();
builder.name(name);
builder.value(value);
if (hostOnly) {
builder.hostOnlyDomain(domain);
} else {
builder.domain(domain);
}
builder.path(path);
builder.expiresAt(expiresAt);
if (secure) builder.secure();
if (httpOnly) builder.httpOnly();
return builder.build();
}
public Map<String, CookieSet> getAllCookies() {
long now = System.currentTimeMillis();
Map<String, CookieSet> map = new HashMap<>();
List<Long> toRemove = new ArrayList<>();
Cursor cursor = db.rawQuery("SELECT * FROM " + TABLE_COOKIE + ";", null);
try {
while (cursor.moveToNext()) {
long id = SqlUtils.getLong(cursor, COLUMN_ID, 0);
Cookie cookie = getCookie(cursor, now);
if (cookie != null) {
// Save id of the cookie in db
cookieIdMap.put(cookie, id);
// Put cookie to set
CookieSet set = map.get(cookie.domain());
if (set == null) {
set = new CookieSet();
map.put(cookie.domain(), set);
}
set.add(cookie);
} else {
// Mark to remove the cookie
toRemove.add(id);
}
}
} finally {
cursor.close();
}
// Remove invalid or expired cookie
if (!toRemove.isEmpty()) {
SQLiteStatement statement = db.compileStatement(
"DELETE FROM " + TABLE_COOKIE + " WHERE " + COLUMN_ID + " = ?;");
db.beginTransaction();
try {
for (long id : toRemove) {
statement.bindLong(1, id);
statement.executeUpdateDelete();
}
db.setTransactionSuccessful();
} finally {
db.endTransaction();
}
}
return map;
}
public ContentValues toContentValues(Cookie cookie) {
ContentValues contentValues = new ContentValues(9);
contentValues.put(COLUMN_NAME, cookie.name());
contentValues.put(COLUMN_VALUE, cookie.value());
contentValues.put(COLUMN_EXPIRES_AT, cookie.expiresAt());
contentValues.put(COLUMN_DOMAIN, cookie.domain());
contentValues.put(COLUMN_PATH, cookie.path());
contentValues.put(COLUMN_SECURE, cookie.secure());
contentValues.put(COLUMN_HTTP_ONLY, cookie.httpOnly());
contentValues.put(COLUMN_PERSISTENT, cookie.persistent());
contentValues.put(COLUMN_HOST_ONLY, cookie.hostOnly());
return contentValues;
}
public void add(Cookie cookie) {
long id = db.insert(TABLE_COOKIE, null, toContentValues(cookie));
if (id != -1L) {
Long oldId = cookieIdMap.put(cookie, id);
if (oldId != null) Log.e(LOG_TAG, "Add a duplicate cookie");
} else {
Log.e(LOG_TAG, "An error occurred when insert a cookie");
}
}
public void update(Cookie from, Cookie to) {
Long id = cookieIdMap.get(from);
if (id == null) {
Log.e(LOG_TAG, "Can't get id when update the cookie");
return;
}
ContentValues values = toContentValues(to);
String whereClause = COLUMN_ID + " = ?";
String[] whereArgs = { id.toString() };
int count = db.update(TABLE_COOKIE, values, whereClause, whereArgs);
if (count != 1) {
Log.e(LOG_TAG, "Bad result when update cookie: " + count);
}
// Update it in cookie-id map
cookieIdMap.remove(from);
cookieIdMap.put(to, id);
}
public void remove(Cookie cookie) {
Long id = cookieIdMap.get(cookie);
if (id == null) {
Log.e(LOG_TAG, "Can't get id when remove the cookie");
return;
}
String whereClause = COLUMN_ID + " = ?";
String[] whereArgs = { id.toString() };
int count = db.delete(TABLE_COOKIE, whereClause, whereArgs);
if (count != 1) {
Log.e(LOG_TAG, "Bad result when remove cookie: " + count);
}
// Remove it from cookie-id map
cookieIdMap.remove(cookie);
}
public void clear() {
db.delete(TABLE_COOKIE, null, null);
cookieIdMap.clear();
}
public void close() {
db.close();
helper.close();
}
}
@@ -0,0 +1,188 @@
/*
* Copyright 2017 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;
/*
* Created by Hippo on 2017/9/4.
*/
import android.content.Context;
import com.hippo.yorozuya.ObjectUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.HttpUrl;
import okhttp3.Request;
public class CookieRepository implements CookieJar {
private CookieDatabase db;
private Map<String, CookieSet> map;
public CookieRepository(Context context, String name) {
db = new CookieDatabase(context, name);
map = db.getAllCookies();
}
public synchronized void addCookie(Cookie cookie) {
// For cookie database
Cookie toAdd = null;
Cookie toUpdate = null;
Cookie toRemove = null;
CookieSet set = map.get(cookie.domain());
if (set == null) {
set = new CookieSet();
map.put(cookie.domain(), set);
}
if (cookie.expiresAt() <= System.currentTimeMillis()) {
toRemove = set.remove(cookie);
// If the cookie is not persistent, it's not in database
if (toRemove != null && !toRemove.persistent()) {
toRemove = null;
}
} else {
toAdd = cookie;
toUpdate = set.add(cookie);
// If the cookie is not persistent, it's not in database
if (!toAdd.persistent()) toAdd = null;
if (toUpdate != null && !toUpdate.persistent()) toUpdate = null;
// Remove the cookie if it updates to null
if (toAdd == null && toUpdate != null) {
toRemove = toUpdate;
toUpdate = null;
}
}
if (toRemove != null) {
db.remove(toRemove);
}
if (toAdd != null) {
if (toUpdate != null) {
db.update(toUpdate, toAdd);
} else {
db.add(toAdd);
}
}
}
public synchronized List<Cookie> getCookies(HttpUrl url) {
List<Cookie> accepted = new ArrayList<>();
List<Cookie> expired = new ArrayList<>();
for (Map.Entry<String, CookieSet> entry : map.entrySet()) {
String domain = entry.getKey();
CookieSet cookieSet = entry.getValue();
if (domainMatch(url, domain)) {
cookieSet.get(url, accepted, expired);
}
}
for (Cookie cookie : expired) {
if (cookie.persistent()) {
db.remove(cookie);
}
}
// RFC 6265 Section-5.4 step 2, sort the cookie-list
// Cookies with longer paths are listed before cookies with shorter paths.
// Ignore creation-time, we don't store them.
Collections.sort(accepted, new Comparator<Cookie>() {
@Override
public int compare(Cookie o1, Cookie o2) {
return o2.path().length() - o1.path().length();
}
});
return accepted;
}
public boolean contains(HttpUrl url, String name) {
for (Cookie cookie : getCookies(url)) {
if (ObjectUtils.equal(cookie.name(), name)) {
return true;
}
}
return false;
}
/**
* Remove all cookies in this {@code CookieRepository}.
*/
public synchronized void clear() {
map.clear();
db.clear();
}
public synchronized void close() {
db.close();
}
@Override
public void saveFromResponse(HttpUrl httpUrl, List<Cookie> list) {
for (Cookie cookie : list) {
addCookie(cookie);
}
}
@Override
public List<Cookie> loadForRequest(HttpUrl httpUrl, Request request) {
return getCookies(httpUrl);
}
/**
* Quick and dirty pattern to differentiate IP addresses from hostnames. This is an approximation
* of Android's private InetAddress#isNumeric API.
*
* This matches IPv6 addresses as a hex string containing at least one colon, and possibly
* including dots after the first colon. It matches IPv4 addresses as strings containing only
* decimal digits and dots. This pattern matches strings like "a:.23" and "54" that are neither IP
* addresses nor hostnames; they will be verified as IP addresses (which is a more strict
* verification).
*/
private static final Pattern VERIFY_AS_IP_ADDRESS = Pattern.compile("([0-9a-fA-F]*:[0-9a-fA-F:.]*)|([\\d.]+)");
/**
* Returns true if `host` is not a host name and might be an IP address.
*/
private static boolean verifyAsIpAddress(String host) {
return VERIFY_AS_IP_ADDRESS.matcher(host).matches();
}
// okhttp3.Cookie.domainMatch(HttpUrl, String)
protected static boolean domainMatch(HttpUrl url, String domain) {
String urlHost = url.host();
if (urlHost.equals(domain)) {
return true; // As in 'example.com' matching 'example.com'.
}
if (urlHost.endsWith(domain)
&& urlHost.charAt(urlHost.length() - domain.length() - 1) == '.'
&& !verifyAsIpAddress(urlHost)) {
return true; // As in 'example.com' matching 'www.example.com'.
}
return false;
}
}
@@ -0,0 +1,104 @@
/*
* Copyright 2017 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;
/*
* Created by Hippo on 2017/9/4.
*/
import com.hippo.util.HashCodeUtils;
import com.hippo.yorozuya.ObjectUtils;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import okhttp3.Cookie;
import okhttp3.HttpUrl;
class CookieSet {
private Map<Key, Cookie> map = new HashMap<>();
/**
* Adds a cookie to this {@code CookieSet}.
* Returns a previous cookie with
* the same name, domain and path or {@code null}.
*/
public Cookie add(Cookie cookie) {
return map.put(new Key(cookie), cookie);
}
/**
* Removes a cookie with the same name,
* domain and path as the cookie.
* Returns the removed cookie or {@code null}.
*/
public Cookie remove(Cookie cookie) {
return map.remove(new Key(cookie));
}
/**
* Get cookies for the url. Fill {@code accepted} and {@code expired}.
*/
public void get(HttpUrl url, List<Cookie> accepted, List<Cookie> expired) {
long now = System.currentTimeMillis();
Iterator<Map.Entry<Key, Cookie>> iterator = map.entrySet().iterator();
while (iterator.hasNext()) {
Cookie cookie = iterator.next().getValue();
if (cookie.expiresAt() <= now) {
iterator.remove();
expired.add(cookie);
} else if (cookie.matches(url)) {
accepted.add(cookie);
}
}
}
static class Key {
private String name;
private String domain;
private String path;
public Key(Cookie cookie) {
this.name = cookie.name();
this.domain = cookie.domain();
this.path = cookie.path();
}
@Override
public boolean equals(Object obj) {
if (obj == this) {
return true;
}
if (obj instanceof Key) {
Key key = (Key) obj;
return ObjectUtils.equal(key.name, this.name) &&
ObjectUtils.equal(key.domain, this.domain) &&
ObjectUtils.equal(key.path, this.path);
}
return false;
}
@Override
public int hashCode() {
return HashCodeUtils.hashCode(name, domain, path);
}
}
}
@@ -1,134 +0,0 @@
/*
* 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.okhttp;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import com.hippo.okhttp.dao.DaoMaster;
import com.hippo.okhttp.dao.DaoSession;
import com.hippo.okhttp.dao.OkHttp3CookieDao;
import com.hippo.okhttp.dao.OkHttp3CookieRaw;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import okhttp3.Cookie;
public class CookieDB {
private static DaoSession sDaoSession;
private static class DBOpenHelper extends DaoMaster.OpenHelper {
public DBOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory) {
super(context, name, factory);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
public static void initialize(Context context) {
DBOpenHelper helper = new DBOpenHelper(
context.getApplicationContext(), "okhttp3-cookie.db", null);
SQLiteDatabase db = helper.getWritableDatabase();
DaoMaster daoMaster = new DaoMaster(db);
sDaoSession = daoMaster.newSession();
}
static Map<String, List<CookieWithID>> getAllCookies() {
OkHttp3CookieDao dao = sDaoSession.getOkHttp3CookieDao();
List<OkHttp3CookieRaw> list = dao.queryBuilder().list();
long now = System.currentTimeMillis();
Map<String, List<CookieWithID>> result = new HashMap<>();
for (OkHttp3CookieRaw raw : list) {
// Check expired
if (!raw.getPersistent() || raw.getExpiresAt() <= now) {
dao.delete(raw);
continue;
}
// Avoid null error
String name = raw.getName();
String value = raw.getValue();
String domain = raw.getDomain();
if (name == null || value == null || domain == null) {
dao.delete(raw);
continue;
}
Cookie.Builder builder = new Cookie.Builder();
builder.name(name);
builder.value(value);
builder.expiresAt(raw.getExpiresAt());
if (raw.getHostOnly()) {
builder.hostOnlyDomain(domain);
} else {
builder.domain(raw.getDomain());
}
builder.path(raw.getPath());
if (raw.getSecure()) {
builder.secure();
}
if (raw.getHttpOnly()) {
builder.httpOnly();
}
List<CookieWithID> cookies = result.get(domain);
if (cookies == null) {
cookies = new ArrayList<>();
result.put(domain, cookies);
}
cookies.add(new CookieWithID(raw.getId(), builder.build()));
}
return result;
}
static void removeCookie(long id) {
sDaoSession.getOkHttp3CookieDao().deleteByKey(id);
}
static void removeAllCookies() {
sDaoSession.getOkHttp3CookieDao().deleteAll();
}
static long addCookie(Cookie cookie) {
OkHttp3CookieDao dao = sDaoSession.getOkHttp3CookieDao();
OkHttp3CookieRaw raw = new OkHttp3CookieRaw();
raw.setName(cookie.name());
raw.setValue(cookie.value());
raw.setExpiresAt(cookie.expiresAt());
raw.setDomain(cookie.domain());
raw.setPath(cookie.path());
raw.setSecure(cookie.secure());
raw.setHttpOnly(cookie.httpOnly());
raw.setPersistent(cookie.persistent());
raw.setHostOnly(cookie.hostOnly());
return dao.insert(raw);
}
}
@@ -1,236 +0,0 @@
/*
* 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.okhttp;
import android.support.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import okhttp3.Cookie;
import okhttp3.CookieJar;
import okhttp3.HttpUrl;
import okhttp3.Request;
public class CookieDBStore implements CookieJar {
private final Map<String, List<CookieWithID>> map;
public CookieDBStore() {
map = CookieDB.getAllCookies();
}
private static boolean hasExpired(Cookie cookie) {
return cookie.expiresAt() < System.currentTimeMillis();
}
private static boolean domainMatch(Cookie cookie, String urlHost) {
return cookie.hostOnly()
? urlHost.equals(cookie.domain())
: domainMatch(urlHost, cookie.domain());
}
public static boolean domainMatch(String urlHost, String cookieDomain) {
if (urlHost.equals(cookieDomain)) {
return true; // As in 'example.com' matching 'example.com'.
}
return urlHost.endsWith(cookieDomain)
&& urlHost.charAt(urlHost.length() - cookieDomain.length() - 1) == '.';
}
private static CookieWithID removeCookie(List<CookieWithID> list, String name) {
for (int i = 0, n = list.size(); i < n; i++) {
CookieWithID cwi = list.get(i);
if (cwi.cookie.name().equals(name)) {
list.remove(i);
return cwi;
}
}
return null;
}
private boolean containInternal(String host, String name, List<CookieWithID> cookies) {
for (int i = 0, n = cookies.size(); i < n; i++) {
Cookie cookie = cookies.get(i).cookie;
if (domainMatch(cookie, host) && cookie.name().equals(name)) {
return true;
}
}
return false;
}
public synchronized boolean contain(String host, String name) {
for (String key : map.keySet()) {
if (domainMatch(host, key)) {
List<CookieWithID> cookies = map.get(key);
// cookies can not be null
if (containInternal(host, name, cookies)) {
return true;
}
}
}
return false;
}
private synchronized void removeInternal(Cookie cookie) {
String domain = cookie.domain();
List<CookieWithID> cookies = map.get(domain);
if (cookies != null) {
// Remove from list
CookieWithID cwi = removeCookie(cookies, cookie.name());
if (cwi != null) {
// Remove from DB
CookieDB.removeCookie(cwi.id);
}
}
}
private void removeInternal(String host, List<CookieWithID> cookies) {
for (Iterator<CookieWithID> i = cookies.iterator(); i.hasNext();) {
CookieWithID cwi = i.next();
Cookie cookie = cwi.cookie;
// Check match host or has expired
if (domainMatch(cookie, host) || hasExpired(cookie)) {
// Remove from list
i.remove();
// Remove from DB
CookieDB.removeCookie(cwi.id);
}
}
}
public synchronized void remove(String host) {
for (String key : map.keySet()) {
if (domainMatch(host, key)) {
List<CookieWithID> cookies = map.get(key);
// cookies can not be null
removeInternal(host, cookies);
}
}
}
public synchronized void removeAll() {
map.clear();
CookieDB.removeAllCookies();
}
public synchronized void add(Cookie cookie) {
String domain = cookie.domain();
// Check expired
if (hasExpired(cookie)) {
removeInternal(cookie);
return;
}
List<CookieWithID> cookies = map.get(domain);
if (cookies == null) {
cookies = new ArrayList<>();
map.put(domain, cookies);
} else {
// Remove old cookie
// Remove from list
CookieWithID cwi = removeCookie(cookies, cookie.name());
if (cwi != null) {
// Remove from DB
CookieDB.removeCookie(cwi.id);
}
}
// Add to DB
long id = CookieDB.addCookie(cookie);
// Add to list
cookies.add(new CookieWithID(id, cookie));
}
private void getInternal(HttpUrl url, List<CookieWithID> cookies, List<Cookie> result) {
for (Iterator<CookieWithID> i = cookies.iterator(); i.hasNext();) {
CookieWithID cwi = i.next();
Cookie cookie = cwi.cookie;
// Check expired
if (hasExpired(cookie)) {
// Remove from list
i.remove();
// Remove from DB
CookieDB.removeCookie(cwi.id);
} else if (cookie.matches(url)) {
result.add(cookie);
}
}
}
private Cookie getInternal(HttpUrl url, String name, List<CookieWithID> cookies) {
for (Iterator<CookieWithID> i = cookies.iterator(); i.hasNext();) {
CookieWithID cwi = i.next();
Cookie cookie = cwi.cookie;
// Check expired
if (hasExpired(cookie)) {
// Remove from list
i.remove();
// Remove from DB
CookieDB.removeCookie(cwi.id);
} else if (cookie.name().equals(name) && cookie.matches(url)) {
return cookie;
}
}
return null;
}
@Nullable
public synchronized Cookie get(HttpUrl url, String name) {
String host = url.host();
for (String key : map.keySet()) {
if (domainMatch(host, key)) {
List<CookieWithID> cookies = map.get(key);
return getInternal(url, name, cookies);
}
}
return null;
}
public synchronized List<Cookie> get(HttpUrl url) {
List<Cookie> result = new ArrayList<>();
String host = url.host();
for (String key : map.keySet()) {
if (domainMatch(host, key)) {
List<CookieWithID> cookies = map.get(key);
// cookies can not be null
getInternal(url, cookies, result);
}
}
return Collections.unmodifiableList(result);
}
@Override
public void saveFromResponse(HttpUrl url, List<Cookie> cookies) {
for (Cookie cookie: cookies) {
add(cookie);
}
}
@Override
public List<Cookie> loadForRequest(HttpUrl url, Request request) {
return get(url);
}
}
@@ -1,5 +1,5 @@
/*
* Copyright 2016 Hippo Seven
* Copyright 2017 Hippo Seven
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,17 +14,29 @@
* limitations under the License.
*/
package com.hippo.okhttp;
package com.hippo.util;
/*
* Created by Hippo on 2017/9/4.
*/
import okhttp3.Cookie;
public class HashCodeUtils {
public class CookieWithID {
private static final int X = 31;
public long id;
public Cookie cookie;
public CookieWithID(long id, Cookie cookie) {
this.id = id;
this.cookie = cookie;
/**
* <pre>{@code
* args[0].hashCode()*31^(n-1) + args[1].hashCode()*31^(n-2) + ... + args[n-1].hashCode()
* }</pre>
* Returns 0 if {@code args == null}.
*/
public static int hashCode(Object... args) {
if (args == null) {
return 0;
}
int hash = 0;
for (Object o: args) {
hash = X * hash + (o != null ? o.hashCode() : 0);
}
return hash;
}
}
@@ -69,4 +69,54 @@ public class SqlUtils {
return sb.toString();
}
public static boolean getBoolean(Cursor cursor, String column, boolean defValue) {
try {
int index = cursor.getColumnIndex(column);
if (index != -1) {
return cursor.getInt(index) != 0;
}
} catch (Throwable e) { /* Ignore */ }
return defValue;
}
public static int getInt(Cursor cursor, String column, int defValue) {
try {
int index = cursor.getColumnIndex(column);
if (index != -1) {
return cursor.getInt(index);
}
} catch (Throwable e) { /* Ignore */ }
return defValue;
}
public static long getLong(Cursor cursor, String column, long defValue) {
try {
int index = cursor.getColumnIndex(column);
if (index != -1) {
return cursor.getLong(index);
}
} catch (Throwable e) { /* Ignore */ }
return defValue;
}
public static float getFloat(Cursor cursor, String column, float defValue) {
try {
int index = cursor.getColumnIndex(column);
if (index != -1) {
return cursor.getFloat(index);
}
} catch (Throwable e) { /* Ignore */ }
return defValue;
}
public static String getString(Cursor cursor, String column, String defValue) {
try {
int index = cursor.getColumnIndex(column);
if (index != -1) {
return cursor.getString(index);
}
} catch (Throwable e) { /* Ignore */ }
return defValue;
}
}
+28 -1
View File
@@ -71,13 +71,40 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/password"
android:imeOptions="actionDone"
android:imeOptions="actionNext"
android:inputType="textPassword"
android:maxLines="1"
android:singleLine="true"/>
</android.support.design.widget.TextInputLayout>
<android.support.design.widget.TextInputLayout
android:id="@+id/recaptcha_layout"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:minWidth="@dimen/single_max_width">
<android.support.design.widget.TextInputEditText
android:id="@+id/recaptcha"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/recaptcha"
android:imeOptions="actionDone"
android:inputType="text"
android:maxLines="1"
android:singleLine="true"/>
</android.support.design.widget.TextInputLayout>
<com.hippo.ehviewer.widget.RecaptchaView
android:id="@+id/recaptcha_image"
android:layout_width="wrap_content"
android:layout_height="48dp"
android:layout_gravity="center_horizontal"
android:minWidth="@dimen/single_max_width"
android:scaleType="fitCenter"/>
<android.support.v4.widget.Space
android:layout_width="wrap_content"
android:layout_height="0dp"
@@ -28,6 +28,11 @@
<string name="username">用户名</string>
<string name="password">密码</string>
<string name="recaptcha">验证码(非必需)</string>
<string name="recaptcha_none">点我</string>
<string name="recaptcha_loading">加载中…</string>
<string name="recaptcha_failure">失败</string>
<string name="sign_in">登录</string>
<string name="register">注册</string>
@@ -28,6 +28,11 @@
<string name="username">用户名</string>
<string name="password">密碼</string>
<string name="recaptcha">驗證碼(非必需)</string>
<string name="recaptcha_none">點我</string>
<string name="recaptcha_loading">加載中…</string>
<string name="recaptcha_failure">失敗</string>
<string name="sign_in">登錄</string>
<string name="register">註冊</string>
@@ -28,6 +28,11 @@
<string name="username">使用者名稱</string>
<string name="password">密碼</string>
<string name="recaptcha">驗證碼(非必需)</string>
<string name="recaptcha_none">點我</string>
<string name="recaptcha_loading">載入中…</string>
<string name="recaptcha_failure">失敗</string>
<string name="sign_in">登入</string>
<string name="register">註冊</string>
+5
View File
@@ -44,6 +44,11 @@
<string name="username">Username</string>
<string name="password">Password</string>
<string name="recaptcha">Recaptcha (Not required)</string>
<string name="recaptcha_none">Click me</string>
<string name="recaptcha_loading">Loading…</string>
<string name="recaptcha_failure">Failed</string>
<string name="sign_in">Sign in</string>
<string name="register">Register</string>
@@ -0,0 +1,51 @@
/*
* Copyright 2017 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.database;
/*
* Created by Hippo on 2017/9/4.
*/
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
@Config(manifest = Config.NONE)
@RunWith(RobolectricTestRunner.class)
public class MSQLiteBuilderTest {
@Test
public void testGetStatements() {
MSQLiteBuilder builder = new MSQLiteBuilder()
.version(1)
.statement("11")
.statement("12")
.version(3)
.statement("31")
.statement("32");
List<String> list = new ArrayList<>();
list.add("31");
list.add("32");
assertEquals(list, builder.getStatements(1, 3));
}
}
@@ -0,0 +1,336 @@
/*
* Copyright 2017 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;
/*
* Created by Hippo on 2017/9/4.
*/
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import android.content.Context;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import okhttp3.Cookie;
import okhttp3.HttpUrl;
import org.joor.Reflect;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
@Config(manifest = Config.NONE)
@RunWith(RobolectricTestRunner.class)
public class CookieRepositoryTest {
private void equals(CookieSet cookieSet, List<Cookie> cookies) {
assertNotNull(cookieSet);
assertNotNull(cookies);
Map<CookieSet.Key, Cookie> map = Reflect.on(cookieSet).field("map").get();
assertEquals(cookies.size(), map.size());
for (Cookie cookie: cookies) {
assertEquals(cookie, map.get(new CookieSet.Key(cookie)));
}
}
private void equals(List<Cookie> cookies1, List<Cookie> cookies2) {
assertNotNull(cookies1);
assertNotNull(cookies2);
assertEquals(cookies1.size(), cookies2.size());
for (Cookie cookie: cookies1) {
assertTrue(cookies2.contains(cookie));
}
}
@Test
public void testPersistent() {
Context app = RuntimeEnvironment.application;
HttpUrl urlEh = HttpUrl.parse("http://www.ehviewer.com/");
Cookie cookieEh1 = new Cookie.Builder()
.name("user")
.value("1234567890")
.domain("ehviewer.com")
.path("/")
.build();
Cookie cookieEh2 = new Cookie.Builder()
.name("level")
.value("999")
.domain("www.ehviewer.com")
.path("/")
.expiresAt(System.currentTimeMillis() + 100000)
.build();
Cookie cookieEh3 = new Cookie.Builder()
.name("speed")
.value("10")
.domain("www.ehviewer.com")
.path("/")
.expiresAt(System.currentTimeMillis() + 100000)
.build();
HttpUrl urlNMB = HttpUrl.parse("http://h.nimingban.com/");
Cookie cookieNMB = new Cookie.Builder()
.name("hash")
.value("0987654321")
.domain("nimingban.com")
.expiresAt(System.currentTimeMillis() + 100000)
.path("/")
.build();
CookieRepository repository = new CookieRepository(app, "cookie.db");
repository.saveFromResponse(urlEh, Arrays.asList(cookieEh1, cookieEh2, cookieEh3));
repository.saveFromResponse(urlNMB, Collections.singletonList(cookieNMB));
Map<String, CookieSet> map = Reflect.on(repository).field("map").get();
assertEquals(3, map.size());
equals(map.get("ehviewer.com"), Collections.singletonList(cookieEh1));
equals(map.get("www.ehviewer.com"), Arrays.asList(cookieEh2, cookieEh3));
equals(map.get("nimingban.com"), Collections.singletonList(cookieNMB));
repository.close();
repository = new CookieRepository(app, "cookie.db");
map = Reflect.on(repository).field("map").get();
assertEquals(2, map.size());
equals(map.get("www.ehviewer.com"), Arrays.asList(cookieEh2, cookieEh3));
equals(map.get("nimingban.com"), Collections.singletonList(cookieNMB));
repository.close();
}
@Test
public void testUpdate() {
Context app = RuntimeEnvironment.application;
HttpUrl urlEh = HttpUrl.parse("http://www.ehviewer.com/");
Cookie cookieEh1 = new Cookie.Builder()
.name("level")
.value("999")
.domain("www.ehviewer.com")
.path("/")
.expiresAt(System.currentTimeMillis() + 100000)
.build();
Cookie cookieEh2 = new Cookie.Builder()
.name("level")
.value("0")
.domain("www.ehviewer.com")
.path("/")
.expiresAt(System.currentTimeMillis() + 100000)
.build();
CookieRepository repository = new CookieRepository(app, "cookie.db");
repository.saveFromResponse(urlEh, Collections.singletonList(cookieEh1));
repository.saveFromResponse(urlEh, Collections.singletonList(cookieEh2));
Map<String, CookieSet> map = Reflect.on(repository).field("map").get();
assertEquals(1, map.size());
equals(map.get("www.ehviewer.com"), Collections.singletonList(cookieEh2));
repository.close();
repository = new CookieRepository(app, "cookie.db");
map = Reflect.on(repository).field("map").get();
assertEquals(1, map.size());
equals(map.get("www.ehviewer.com"), Collections.singletonList(cookieEh2));
repository.close();
}
@Test
public void testRemoveByExpired() {
Context app = RuntimeEnvironment.application;
HttpUrl urlEh = HttpUrl.parse("http://www.ehviewer.com/");
Cookie cookieEh1 = new Cookie.Builder()
.name("level")
.value("999")
.domain("www.ehviewer.com")
.path("/")
.expiresAt(System.currentTimeMillis() + 100000)
.build();
Cookie cookieEh2 = new Cookie.Builder()
.name("level")
.value("0")
.domain("www.ehviewer.com")
.path("/")
.expiresAt(System.currentTimeMillis() - 100000)
.build();
CookieRepository repository = new CookieRepository(app, "cookie.db");
repository.saveFromResponse(urlEh, Collections.singletonList(cookieEh1));
repository.saveFromResponse(urlEh, Collections.singletonList(cookieEh2));
Map<String, CookieSet> map = Reflect.on(repository).field("map").get();
assertEquals(1, map.size());
equals(map.get("www.ehviewer.com"), Collections.<Cookie>emptyList());
repository.close();
repository = new CookieRepository(app, "cookie.db");
map = Reflect.on(repository).field("map").get();
assertEquals(0, map.size());
repository.close();
}
@Test
public void testRemoveByNonPersistent() {
Context app = RuntimeEnvironment.application;
HttpUrl urlEh = HttpUrl.parse("http://www.ehviewer.com/");
Cookie cookieEh1 = new Cookie.Builder()
.name("level")
.value("999")
.domain("www.ehviewer.com")
.path("/")
.expiresAt(System.currentTimeMillis() + 100000)
.build();
Cookie cookieEh2 = new Cookie.Builder()
.name("level")
.value("0")
.domain("www.ehviewer.com")
.path("/")
.build();
CookieRepository repository = new CookieRepository(app, "cookie.db");
repository.saveFromResponse(urlEh, Collections.singletonList(cookieEh1));
repository.saveFromResponse(urlEh, Collections.singletonList(cookieEh2));
Map<String, CookieSet> map = Reflect.on(repository).field("map").get();
assertEquals(1, map.size());
equals(map.get("www.ehviewer.com"), Collections.singletonList(cookieEh2));
repository.close();
repository = new CookieRepository(app, "cookie.db");
map = Reflect.on(repository).field("map").get();
assertEquals(0, map.size());
repository.close();
}
@Test
public void testGet() throws InterruptedException {
Context app = RuntimeEnvironment.application;
HttpUrl urlEh1 = HttpUrl.parse("http://www.ehviewer.com/");
HttpUrl urlEh2 = HttpUrl.parse("http://ehviewer.com/");
Cookie cookieEh1 = new Cookie.Builder()
.name("user")
.value("1234567890")
.domain("ehviewer.com")
.path("/")
.expiresAt(System.currentTimeMillis() + 3000)
.build();
Cookie cookieEh2 = new Cookie.Builder()
.name("level")
.value("999")
.domain("www.ehviewer.com")
.path("/")
.build();
Cookie cookieEh3 = new Cookie.Builder()
.name("speed")
.value("10")
.domain("ehviewer.com")
.path("/")
.build();
HttpUrl urlNMB = HttpUrl.parse("http://h.nimingban.com/");
Cookie cookieNMB = new Cookie.Builder()
.name("hash")
.value("0987654321")
.domain("nimingban.com")
.path("/")
.build();
CookieRepository repository = new CookieRepository(app, "cookie.db");
repository.saveFromResponse(urlEh1, Arrays.asList(cookieEh1, cookieEh2));
repository.saveFromResponse(urlEh1, Collections.singletonList(cookieEh3));
repository.saveFromResponse(urlNMB, Collections.singletonList(cookieNMB));
equals(Arrays.asList(cookieEh1, cookieEh3), repository.loadForRequest(urlEh2, null));
Thread.sleep(3000);
equals(Collections.singletonList(cookieEh3), repository.loadForRequest(urlEh2, null));
repository.close();
}
@Test
public void testClear() {
Context app = RuntimeEnvironment.application;
HttpUrl url = HttpUrl.parse("http://www.ehviewer.com/");
Cookie cookie = new Cookie.Builder()
.name("user")
.value("1234567890")
.domain("ehviewer.com")
.path("/")
.expiresAt(System.currentTimeMillis() + 3000)
.build();
CookieRepository repository = new CookieRepository(app, "cookie.db");
repository.saveFromResponse(url, Collections.singletonList(cookie));
Map<String, CookieSet> map = Reflect.on(repository).field("map").get();
assertEquals(1, map.size());
equals(map.get("ehviewer.com"), Collections.singletonList(cookie));
repository.clear();
map = Reflect.on(repository).field("map").get();
assertEquals(0, map.size());
repository.close();
repository = new CookieRepository(app, "cookie.db");
map = Reflect.on(repository).field("map").get();
assertEquals(0, map.size());
repository.close();
}
@Test
public void testSort() {
Context app = RuntimeEnvironment.application;
HttpUrl url = HttpUrl.parse("http://www.ehviewer.com/long/long/long/");
Cookie cookie1 = new Cookie.Builder()
.name("user")
.value("1234567890")
.domain("ehviewer.com")
.path("/")
.build();
Cookie cookie2 = new Cookie.Builder()
.name("supersuperme")
.value("99999")
.domain("ehviewer.com")
.path("/long/")
.build();
Cookie cookie3 = new Cookie.Builder()
.name("a")
.value("b")
.domain("ehviewer.com")
.path("/long/long/long/")
.build();
Cookie cookie4 = new Cookie.Builder()
.name("speed")
.value("100")
.domain("ehviewer.com")
.path("/long/long/")
.build();
CookieRepository repository = new CookieRepository(app, "cookie.db");
repository.saveFromResponse(url, Arrays.asList(cookie1, cookie2, cookie3, cookie4));
List<Cookie> list = repository.loadForRequest(url, null);
List<Cookie> expected = Arrays.asList(cookie3, cookie4, cookie2, cookie1);
assertEquals(expected.size(), list.size());
for (int i = 0; i < list.size(); i++) {
assertEquals(expected.get(i), list.get(i));
}
repository.close();
}
}
+1 -1
View File
@@ -6,7 +6,7 @@ buildscript {
maven { url "https://jitpack.io" }
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.2'
classpath 'com.android.tools.build:gradle:2.3.3'
classpath 'com.github.seven332:android-chinese-string-gradle-plugin:0.1.0'
// NOTE: Do not place your application dependencies here; they belong
@@ -1,58 +0,0 @@
/*
* 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.daogenerator;
import java.io.File;
import de.greenrobot.daogenerator.DaoGenerator;
import de.greenrobot.daogenerator.Entity;
import de.greenrobot.daogenerator.Schema;
public class CookieDaoGenerator {
private static final String PACKAGE = "com.hippo.okhttp.dao";
private static final String OUT_DIR = "../app/src/main/java-gen";
private static final String DELETE_DIR = "../app/src/main/java-gen/com/hippo/okhttp/dao";
public static void generate() throws Exception {
Utilities.deleteContents(new File(DELETE_DIR));
File outDir = new File(OUT_DIR);
outDir.delete();
outDir.mkdirs();
Schema schema = new Schema(1, PACKAGE);
addOkHttp3Cookie(schema);
new DaoGenerator().generateAll(schema, OUT_DIR);
}
private static void addOkHttp3Cookie(Schema schema) {
Entity entity = schema.addEntity("OkHttp3CookieRaw");
entity.setTableName("OK_HTTP_3_COOKIE");
entity.setClassNameDao("OkHttp3CookieDao");
entity.addIdProperty();
entity.addStringProperty("name");
entity.addStringProperty("value");
entity.addLongProperty("expiresAt");
entity.addStringProperty("domain");
entity.addStringProperty("path");
entity.addBooleanProperty("secure");
entity.addBooleanProperty("httpOnly");
entity.addBooleanProperty("persistent");
entity.addBooleanProperty("hostOnly");
}
}
@@ -19,7 +19,6 @@ package com.hippo.ehviewer.daogenerator;
public class Main {
public static void main(String args[]) throws Exception {
CookieDaoGenerator.generate();
EhDaoGenerator.generate();
}
}