Add eh gallery spider
This commit is contained in:
1 parent
6f37491471
commit
31ffa6f8a9
43 files changed
+2337
-180
No files matched your search
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.Environment;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.hippo.yorozuya.FileUtils;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class AppConfig {
|
||||
|
||||
private static final String APP_DIRNAME = "EhViewer";
|
||||
|
||||
private static final String SPIDER_INFO = "spider_info";
|
||||
private static final String DOWNLOAD = "download";
|
||||
|
||||
private static Context sContext;
|
||||
|
||||
public static void initialize(Context context) {
|
||||
sContext = context.getApplicationContext();
|
||||
}
|
||||
|
||||
public static File getSpiderInfoCacheDir() {
|
||||
File dir = new File(sContext.getCacheDir(), SPIDER_INFO);
|
||||
return FileUtils.ensureDirectory(dir) ? dir : null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static File getExternalAppDir() {
|
||||
if (Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState())) {
|
||||
File dir = new File(Environment.getExternalStorageDirectory(), APP_DIRNAME);
|
||||
return FileUtils.ensureDirectory(dir) ? dir : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* mkdirs and get
|
||||
*/
|
||||
@Nullable
|
||||
public static File getDirInAppDir(String filename) {
|
||||
File appFolder = getExternalAppDir();
|
||||
if (appFolder != null) {
|
||||
File dir = new File(appFolder, filename);
|
||||
return FileUtils.ensureDirectory(dir) ? dir : null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static File getDefaultDownloadDir() {
|
||||
return getDirInAppDir(DOWNLOAD);
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,7 @@ import com.hippo.ehviewer.client.EhClient;
|
||||
import com.hippo.ehviewer.client.EhCookieStore;
|
||||
import com.hippo.ehviewer.client.data.GalleryDetail;
|
||||
import com.hippo.ehviewer.client.data.LargePreviewSet;
|
||||
import com.hippo.ehviewer.spider.SpiderDen;
|
||||
import com.hippo.network.StatusCodeException;
|
||||
import com.hippo.okhttp.CookieDB;
|
||||
import com.hippo.scene.SceneApplication;
|
||||
@@ -73,6 +74,8 @@ public class EhApplication extends SceneApplication {
|
||||
Settings.initialize(this);
|
||||
ReadableTime.initialize(this);
|
||||
Html.initialize(this);
|
||||
AppConfig.initialize(this);
|
||||
SpiderDen.initialize(this);
|
||||
|
||||
if (DEBUG_NATIVE_MEMORY) {
|
||||
debugNativeMemory();
|
||||
|
||||
@@ -18,9 +18,13 @@ package com.hippo.ehviewer;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.net.Uri;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.hippo.ehviewer.client.EhConfig;
|
||||
import com.hippo.unifile.UniFile;
|
||||
import com.hippo.yorozuya.NumberUtils;
|
||||
|
||||
public class Settings {
|
||||
@@ -121,4 +125,36 @@ public class Settings {
|
||||
public static boolean getShowJpnTitle() {
|
||||
return getBoolean(KEY_SHOW_JPN_TITLE, DEFAULT_SHOW_JPN_TITLE);
|
||||
}
|
||||
|
||||
public static final String KEY_DOWNLOAD_SAVE_SCHEME = "image_scheme";
|
||||
public static final String KEY_DOWNLOAD_SAVE_AUTHORITY = "image_authority";
|
||||
public static final String KEY_DOWNLOAD_SAVE_PATH = "image_path";
|
||||
public static final String KEY_DOWNLOAD_SAVE_QUERY = "image_query";
|
||||
public static final String KEY_DOWNLOAD_SAVE_FRAGMENT = "image_fragment";
|
||||
|
||||
@Nullable
|
||||
public static UniFile getDownloadLocation() {
|
||||
UniFile dir = null;
|
||||
try {
|
||||
Uri.Builder builder = new Uri.Builder();
|
||||
builder.scheme(getString(KEY_DOWNLOAD_SAVE_SCHEME, null));
|
||||
builder.encodedAuthority(getString(KEY_DOWNLOAD_SAVE_AUTHORITY, null));
|
||||
builder.encodedPath(getString(KEY_DOWNLOAD_SAVE_PATH, null));
|
||||
builder.encodedQuery(getString(KEY_DOWNLOAD_SAVE_QUERY, null));
|
||||
builder.encodedFragment(getString(KEY_DOWNLOAD_SAVE_FRAGMENT, null));
|
||||
dir = UniFile.fromUri(sContext, builder.build());
|
||||
} catch (Exception e) {
|
||||
// Ignore
|
||||
}
|
||||
return dir != null ? dir : UniFile.fromFile(AppConfig.getDefaultDownloadDir());
|
||||
}
|
||||
|
||||
public static void putImageSaveLocation(@NonNull UniFile location) {
|
||||
Uri uri = location.getUri();
|
||||
putString(KEY_DOWNLOAD_SAVE_SCHEME, uri.getScheme());
|
||||
putString(KEY_DOWNLOAD_SAVE_AUTHORITY, uri.getEncodedAuthority());
|
||||
putString(KEY_DOWNLOAD_SAVE_PATH, uri.getEncodedPath());
|
||||
putString(KEY_DOWNLOAD_SAVE_QUERY, uri.getEncodedQuery());
|
||||
putString(KEY_DOWNLOAD_SAVE_FRAGMENT, uri.getEncodedFragment());
|
||||
}
|
||||
}
|
||||
@@ -39,6 +39,7 @@ import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -87,7 +88,7 @@ public class EhEngine {
|
||||
}
|
||||
|
||||
public static Call prepareSignIn(OkHttpClient okHttpClient,
|
||||
EhConfig ehConfig, String username, String password) {
|
||||
EhConfig ehConfig, String username, String password) throws MalformedURLException {
|
||||
FormBody.Builder builder = new FormBody.Builder()
|
||||
.add("UserName", username)
|
||||
.add("PassWord", password)
|
||||
@@ -120,7 +121,7 @@ public class EhEngine {
|
||||
}
|
||||
|
||||
public static Call prepareGetGalleryList(OkHttpClient okHttpClient,
|
||||
EhConfig ehConfig, String url) {
|
||||
EhConfig ehConfig, String url) throws MalformedURLException {
|
||||
Log.d(TAG, url);
|
||||
Request request = new EhRequestBuilder(url, ehConfig).build();
|
||||
return okHttpClient.newCall(request);
|
||||
@@ -232,7 +233,7 @@ public class EhEngine {
|
||||
}
|
||||
|
||||
public static Call prepareGetGalleryDetail(OkHttpClient okHttpClient,
|
||||
EhConfig ehConfig, String url) {
|
||||
EhConfig ehConfig, String url) throws MalformedURLException {
|
||||
Log.d(TAG, url);
|
||||
Request request = new EhRequestBuilder(url, ehConfig).build();
|
||||
return okHttpClient.newCall(request);
|
||||
@@ -255,7 +256,7 @@ public class EhEngine {
|
||||
}
|
||||
|
||||
public static Call prepareGetLargePreviewSet(OkHttpClient okHttpClient,
|
||||
EhConfig ehConfig, String url) {
|
||||
EhConfig ehConfig, String url) throws MalformedURLException {
|
||||
Log.d(TAG, url);
|
||||
Request request = new EhRequestBuilder(url, ehConfig).build();
|
||||
return okHttpClient.newCall(request);
|
||||
@@ -279,7 +280,7 @@ public class EhEngine {
|
||||
|
||||
// rating 0.0 - 0.5
|
||||
public static Call prepareRateGallery(OkHttpClient okHttpClient,
|
||||
EhConfig ehConfig, int gid, String token, float rating) throws JSONException {
|
||||
EhConfig ehConfig, int gid, String token, float rating) throws JSONException, MalformedURLException {
|
||||
final JSONObject json = new JSONObject();
|
||||
json.put("method", "rategallery");
|
||||
json.put("apiuid", APIUID);
|
||||
@@ -316,7 +317,7 @@ public class EhEngine {
|
||||
}
|
||||
|
||||
public static Call prepareCommentGallery(OkHttpClient okHttpClient,
|
||||
EhConfig ehConfig, String url, String comment) {
|
||||
EhConfig ehConfig, String url, String comment) throws MalformedURLException {
|
||||
FormBody.Builder builder = new FormBody.Builder()
|
||||
.add("commenttext", comment)
|
||||
.add("postcomment", "Post New");
|
||||
@@ -354,7 +355,7 @@ public class EhEngine {
|
||||
* }
|
||||
*/
|
||||
public static Call prepareGetGalleryToken(OkHttpClient okHttpClient,
|
||||
EhConfig ehConfig, int gid, String gtoken, int page) throws JSONException {
|
||||
EhConfig ehConfig, int gid, String gtoken, int page) throws JSONException, MalformedURLException {
|
||||
JSONObject json = new JSONObject()
|
||||
.put("method", "gtoken")
|
||||
.put("pagelist", new JSONArray().put(
|
||||
|
||||
@@ -19,13 +19,15 @@ package com.hippo.ehviewer.client;
|
||||
import com.hippo.ehviewer.Settings;
|
||||
import com.hippo.okhttp.ChromeRequestBuilder;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
|
||||
public class EhRequestBuilder extends ChromeRequestBuilder {
|
||||
|
||||
public EhRequestBuilder(String url) {
|
||||
public EhRequestBuilder(String url) throws MalformedURLException {
|
||||
this(url, Settings.getEhConfig());
|
||||
}
|
||||
|
||||
public EhRequestBuilder(String url, EhConfig ehConfig) {
|
||||
public EhRequestBuilder(String url, EhConfig ehConfig) throws MalformedURLException {
|
||||
super(url);
|
||||
tag(ehConfig);
|
||||
}
|
||||
|
||||
@@ -46,4 +46,8 @@ public class EhUrl {
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public static String getPageUrl(int gid, int index, String pToken) {
|
||||
return HOST_EX + "s/" + pToken + '/' + gid + '-' + (index + 1);
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ import android.util.Log;
|
||||
import com.hippo.ehviewer.client.data.ListUrlBuilder;
|
||||
import com.hippo.ehviewer.client.parser.GalleryDetailUrlParser;
|
||||
import com.hippo.ehviewer.client.parser.GalleryListUrlParser;
|
||||
import com.hippo.ehviewer.client.parser.GalleryUrlParser;
|
||||
import com.hippo.ehviewer.client.parser.GalleryPageUrlParser;
|
||||
import com.hippo.ehviewer.ui.MainActivity;
|
||||
import com.hippo.ehviewer.ui.scene.GalleryDetailScene;
|
||||
import com.hippo.ehviewer.ui.scene.GalleryListScene;
|
||||
@@ -68,7 +68,7 @@ public class EhUrlOpener {
|
||||
return true;
|
||||
}
|
||||
|
||||
GalleryUrlParser.Result result2 = GalleryUrlParser.parse(url);
|
||||
GalleryPageUrlParser.Result result2 = GalleryPageUrlParser.parse(url);
|
||||
if (result2 != null) {
|
||||
Bundle args = new Bundle();
|
||||
args.putString(ProgressScene.KEY_ACTION, ProgressScene.ACTION_GALLERY_TOKEN);
|
||||
|
||||
@@ -17,6 +17,9 @@
|
||||
package com.hippo.ehviewer.client.data;
|
||||
|
||||
import android.os.Parcel;
|
||||
import android.os.Parcelable;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public class GalleryDetail extends GalleryInfo {
|
||||
|
||||
@@ -78,17 +81,29 @@ public class GalleryDetail extends GalleryInfo {
|
||||
this.favoredTimes = in.readInt();
|
||||
this.isFavored = in.readByte() != 0;
|
||||
this.ratedTimes = in.readInt();
|
||||
this.tags = in.createTypedArray(GalleryTagGroup.CREATOR);
|
||||
this.comments = in.createTypedArray(GalleryComment.CREATOR);
|
||||
Parcelable[] array = in.readParcelableArray(GalleryTagGroup.class.getClassLoader());
|
||||
if (array != null) {
|
||||
this.tags = Arrays.copyOf(array, array.length, GalleryTagGroup[].class);
|
||||
} else {
|
||||
this.tags = null;
|
||||
}
|
||||
array = in.readParcelableArray(GalleryComment.class.getClassLoader());
|
||||
if (array != null) {
|
||||
this.comments = Arrays.copyOf(array, array.length, GalleryComment[].class);
|
||||
} else {
|
||||
this.comments = null;
|
||||
}
|
||||
this.previewPages = in.readInt();
|
||||
this.previewSet = in.readParcelable(LargePreviewSet.class.getClassLoader());
|
||||
}
|
||||
|
||||
public static final Creator<GalleryDetail> CREATOR = new Creator<GalleryDetail>() {
|
||||
@Override
|
||||
public GalleryDetail createFromParcel(Parcel source) {
|
||||
return new GalleryDetail(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GalleryDetail[] newArray(int size) {
|
||||
return new GalleryDetail[size];
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ import java.util.ArrayList;
|
||||
public class GalleryTagGroup implements Parcelable {
|
||||
|
||||
public String groupName;
|
||||
private ArrayList<String> mTagList = new ArrayList<>();
|
||||
private ArrayList<String> mTagList;
|
||||
|
||||
public void addTag(String tag) {
|
||||
mTagList.add(tag);
|
||||
@@ -50,6 +50,7 @@ public class GalleryTagGroup implements Parcelable {
|
||||
}
|
||||
|
||||
public GalleryTagGroup() {
|
||||
mTagList = new ArrayList<>();
|
||||
}
|
||||
|
||||
protected GalleryTagGroup(Parcel in) {
|
||||
@@ -58,10 +59,12 @@ public class GalleryTagGroup implements Parcelable {
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<GalleryTagGroup> CREATOR = new Parcelable.Creator<GalleryTagGroup>() {
|
||||
@Override
|
||||
public GalleryTagGroup createFromParcel(Parcel source) {
|
||||
return new GalleryTagGroup(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public GalleryTagGroup[] newArray(int size) {
|
||||
return new GalleryTagGroup[size];
|
||||
}
|
||||
|
||||
@@ -25,9 +25,9 @@ import java.util.ArrayList;
|
||||
|
||||
public class LargePreviewSet implements Parcelable {
|
||||
|
||||
private IntList mIndexList = new IntList();
|
||||
private ArrayList<String> mImageUrlList = new ArrayList<>();
|
||||
private ArrayList<String> mPageUrlList = new ArrayList<>();
|
||||
private IntList mIndexList;
|
||||
private ArrayList<String> mImageUrlList;
|
||||
private ArrayList<String> mPageUrlList;
|
||||
|
||||
public int size() {
|
||||
return mImageUrlList.size();
|
||||
@@ -58,26 +58,30 @@ public class LargePreviewSet implements Parcelable {
|
||||
|
||||
@Override
|
||||
public void writeToParcel(Parcel dest, int flags) {
|
||||
this.mIndexList.writeToParcel(dest, flags);
|
||||
dest.writeParcelable(this.mIndexList, 0);
|
||||
dest.writeParcelable(this.mIndexList, flags);
|
||||
dest.writeStringList(this.mImageUrlList);
|
||||
dest.writeStringList(this.mPageUrlList);
|
||||
}
|
||||
|
||||
public LargePreviewSet() {
|
||||
mIndexList = new IntList();
|
||||
mImageUrlList = new ArrayList<>();
|
||||
mPageUrlList = new ArrayList<>();
|
||||
}
|
||||
|
||||
protected LargePreviewSet(Parcel in) {
|
||||
this.mIndexList = IntList.CREATOR.createFromParcel(in);
|
||||
this.mIndexList = in.readParcelable(IntList.class.getClassLoader());
|
||||
this.mImageUrlList = in.createStringArrayList();
|
||||
this.mPageUrlList = in.createStringArrayList();
|
||||
}
|
||||
|
||||
public static final Parcelable.Creator<LargePreviewSet> CREATOR = new Parcelable.Creator<LargePreviewSet>() {
|
||||
@Override
|
||||
public LargePreviewSet createFromParcel(Parcel source) {
|
||||
return new LargePreviewSet(source);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LargePreviewSet[] newArray(int size) {
|
||||
return new LargePreviewSet[size];
|
||||
}
|
||||
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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.client.data;
|
||||
|
||||
import com.hippo.yorozuya.IntList;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class NormalPreviewSet {
|
||||
|
||||
private IntList mIndexList = new IntList();
|
||||
private ArrayList<String> mImageUrlList = new ArrayList<>();
|
||||
private IntList mXOffsetList = new IntList();
|
||||
private IntList mYOffsetList = new IntList();
|
||||
private IntList mWidthList = new IntList();
|
||||
private IntList mHeightList = new IntList();
|
||||
private ArrayList<String> mPageUrlList = new ArrayList<>();
|
||||
|
||||
public void addItem(int index, String imageUrl, int xOffset, int yOffset, int width,
|
||||
int height, String pageUrl) {
|
||||
mIndexList.add(index);
|
||||
mImageUrlList.add(imageUrl);
|
||||
mXOffsetList.add(xOffset);
|
||||
mYOffsetList.add(yOffset);
|
||||
mWidthList.add(width);
|
||||
mHeightList.add(height);
|
||||
mPageUrlList.add(pageUrl);
|
||||
}
|
||||
|
||||
public int size() {
|
||||
return mIndexList.size();
|
||||
}
|
||||
|
||||
public int getIndexAt(int index) {
|
||||
return mIndexList.get(index);
|
||||
}
|
||||
|
||||
public String getPageUrlAt(int index) {
|
||||
return mPageUrlList.get(index);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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.client.exception;
|
||||
|
||||
public class Image509Exception extends EhException {
|
||||
|
||||
public Image509Exception() {
|
||||
super("509");
|
||||
}
|
||||
}
|
||||
@@ -16,22 +16,18 @@
|
||||
|
||||
package com.hippo.ehviewer.client.parser;
|
||||
|
||||
import android.util.Log;
|
||||
|
||||
import com.hippo.ehviewer.client.EhUtils;
|
||||
import com.hippo.ehviewer.client.data.GalleryComment;
|
||||
import com.hippo.ehviewer.client.data.GalleryDetail;
|
||||
import com.hippo.ehviewer.client.data.GalleryTagGroup;
|
||||
import com.hippo.ehviewer.client.data.LargePreviewSet;
|
||||
import com.hippo.ehviewer.client.data.NormalPreviewSet;
|
||||
import com.hippo.ehviewer.client.exception.EhException;
|
||||
import com.hippo.ehviewer.client.exception.OffensiveException;
|
||||
import com.hippo.ehviewer.client.exception.ParseException;
|
||||
import com.hippo.ehviewer.client.exception.PiningException;
|
||||
import com.hippo.yorozuya.NumberUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
@@ -74,9 +70,11 @@ public class GalleryDetailParser {
|
||||
+ ".+?"
|
||||
+ "<td id=\"grt3\"><span id=\"rating_count\">([\\d,]+)</span></td>" // 18 ratedTimes
|
||||
+ "</tr>"
|
||||
+ "<tr><td[^<>]*>([^<>]+)</td>" // 19 rating "Average: x.xx" or "Not Yet Rated"
|
||||
+ ".+?"
|
||||
+ "<a id=\"favoritelink\"[^<>]*>(.+?)</a>", Pattern.DOTALL); // 20 isFavored "Favorite Gallery" for favorite
|
||||
+ "<tr><td[^<>]*>([^<>]+)</td>", // 19 rating "Average: x.xx" or "Not Yet Rated"
|
||||
Pattern.DOTALL);
|
||||
|
||||
private static final Pattern IS_FAVORED_PATTERN = Pattern.compile("<a id=\"favoritelink\"[^<>]*>(.+?)</a>"); // isFavored "Favorite Gallery" for favorite
|
||||
|
||||
private static final Pattern TAG_GROUP_PATTERN = Pattern.compile("<tr><td[^<>]+>([\\w\\s]+):</td><td>(?:<div[^<>]+><a[^<>]+>[\\w\\s]+</a></div>)+</td></tr>");
|
||||
private static final Pattern TAG_PATTERN = Pattern.compile("<div[^<>]+><a[^<>]+>([\\w\\s]+)</a></div>");
|
||||
|
||||
@@ -85,7 +83,7 @@ public class GalleryDetailParser {
|
||||
|
||||
public static final Pattern PAGES_PATTERN = Pattern.compile("<tr><td[^<>]*>Length:</td><td[^<>]*>([\\d,]+) pages</td></tr>");
|
||||
public static final Pattern PREVIEW_PAGES_PATTERN = Pattern.compile("<td[^>]+><a[^>]+>([\\d,]+)</a></td><td[^>]+>(?:<a[^>]+>)?>(?:</a>)?</td>");
|
||||
private static final Pattern NORMAL_PREVIEW_PATTERN = Pattern.compile("<div[^<>]*class=\"gdtm\"[^<>]*><div[^<>]*width:(\\d+)[^<>]*height:(\\d+)[^<>]*\\((.+?)\\)[^<>]*-(\\d+)px[^<>]*><a[^<>]*href=\"(.+?)\"[^<>]*>");
|
||||
private static final Pattern NORMAL_PREVIEW_PATTERN = Pattern.compile("<div class=\"gdtm\"[^<>]*><div[^<>]*width:(\\d+)[^<>]*height:(\\d+)[^<>]*\\((.+?)\\)[^<>]*-(\\d+)px[^<>]*><a[^<>]*href=\"(.+?)\"[^<>]*><img alt=\"([\\d,]+)\"");
|
||||
private static final Pattern LARGE_PREVIEW_PATTERN = Pattern.compile("<div class=\"gdtl\".+?<a href=\"(.+?)\"><img alt=\"([\\d,]+)\".+?src=\"(.+?)\"");
|
||||
|
||||
static {
|
||||
@@ -117,7 +115,7 @@ public class GalleryDetailParser {
|
||||
galleryDetail.tags = parseTagGroup(body);
|
||||
galleryDetail.comments = parseComment(body);
|
||||
galleryDetail.previewPages = parsePreviewPages(body);
|
||||
galleryDetail.previewSet = parsePreview(body);
|
||||
galleryDetail.previewSet = parseLargePreview(body);
|
||||
return galleryDetail;
|
||||
}
|
||||
|
||||
@@ -176,10 +174,10 @@ public class GalleryDetailParser {
|
||||
}
|
||||
}
|
||||
|
||||
gd.isFavored = "Favorite Gallery".equals(ParserUtils.trim(m.group(20)));
|
||||
m = IS_FAVORED_PATTERN.matcher(body);
|
||||
gd.isFavored = m.find() && "Favorite Gallery".equals(ParserUtils.trim(m.group(1)));
|
||||
}
|
||||
|
||||
|
||||
public static GalleryTagGroup[] parseTagGroup(String body) throws EhException {
|
||||
List<GalleryTagGroup> list = new LinkedList<>();
|
||||
|
||||
@@ -246,18 +244,7 @@ public class GalleryDetailParser {
|
||||
}
|
||||
}
|
||||
|
||||
public static LargePreviewSet parsePreview(String body) throws EhException {
|
||||
return parseLargePreview(body);
|
||||
/*
|
||||
if (body.contains("<div class=\"gdtm\"")) {
|
||||
throw new EhException("Not support normal preview now");
|
||||
} else {
|
||||
return parseLargePreview(body);
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
public static LargePreviewSet parseLargePreview(String body) {
|
||||
public static LargePreviewSet parseLargePreview(String body) throws ParseException {
|
||||
Matcher m = LARGE_PREVIEW_PATTERN.matcher(body);
|
||||
LargePreviewSet largePreviewSet = new LargePreviewSet();
|
||||
|
||||
@@ -267,16 +254,27 @@ public class GalleryDetailParser {
|
||||
}
|
||||
|
||||
if (largePreviewSet.size() == 0) {
|
||||
Log.d("TAG", "largePreviewSet.size() == 0");
|
||||
try {
|
||||
OutputStream os = new FileOutputStream(new File("/data/data/com.hippo.ehviewer/cache/empty.txt"));
|
||||
os.write(body.getBytes("utf-8"));
|
||||
os.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
throw new ParseException("Can't parse large preview", body);
|
||||
}
|
||||
|
||||
return largePreviewSet;
|
||||
}
|
||||
|
||||
public static NormalPreviewSet parseNormalPreviewSet(String body) throws ParseException {
|
||||
Matcher m = NORMAL_PREVIEW_PATTERN.matcher(body);
|
||||
NormalPreviewSet normalPreviewSet = new NormalPreviewSet();
|
||||
while (m.find()) {
|
||||
normalPreviewSet.addItem(ParserUtils.parseInt(m.group(6)) - 1,
|
||||
ParserUtils.trim(m.group(3)), ParserUtils.parseInt((m.group(4))), 0,
|
||||
ParserUtils.parseInt(m.group(1)), ParserUtils.parseInt(m.group(2)),
|
||||
ParserUtils.trim(m.group(5)));
|
||||
}
|
||||
|
||||
if (normalPreviewSet.size() == 0) {
|
||||
throw new ParseException("Can't parse large preview", body);
|
||||
}
|
||||
|
||||
return normalPreviewSet;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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.client.parser;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.hippo.ehviewer.client.exception.ParseException;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class GalleryPageParser {
|
||||
|
||||
private static Pattern IMAGE_URL_PATTERN = Pattern.compile("<div id=\"i3\"><a[^>]+><img id=\"img\" src=\"([^\"]+)\"");
|
||||
private static Pattern SKIP_HATH_KEY_PATTERN = Pattern.compile("onclick=\"return nl\\('([^\\)]+)'\\)");
|
||||
|
||||
public static Result parse(String body) throws ParseException {
|
||||
Matcher m;
|
||||
Result result = new Result();
|
||||
m = IMAGE_URL_PATTERN.matcher(body);
|
||||
if (m.find()) {
|
||||
result.imageUrl = ParserUtils.trim(m.group(1));
|
||||
}
|
||||
m = SKIP_HATH_KEY_PATTERN.matcher(body);
|
||||
if (m.find()) {
|
||||
result.skipHathKey = ParserUtils.trim(m.group(1));
|
||||
}
|
||||
if (!TextUtils.isEmpty(result.imageUrl) && !TextUtils.isEmpty(result.skipHathKey)) {
|
||||
return result;
|
||||
} else {
|
||||
throw new ParseException("Parse image url and skip hath key error", body);
|
||||
}
|
||||
}
|
||||
|
||||
public static class Result {
|
||||
public String imageUrl;
|
||||
public String skipHathKey;
|
||||
}
|
||||
}
|
||||
+1
-1
@@ -24,7 +24,7 @@ import java.util.regex.Pattern;
|
||||
/**
|
||||
* Like http://exhentai.org/s/91ea4b6d89/901103-12
|
||||
*/
|
||||
public final class GalleryUrlParser {
|
||||
public final class GalleryPageUrlParser {
|
||||
|
||||
public static final Pattern URL_PATTERN = Pattern.compile("http://(?:" +
|
||||
EhUrl.DOMAIN_EX + "|" + EhUrl.DOMAIN_G + "|" + EhUrl.DOMAIN_LOFI + ")/s/(\\w+)/(\\d+)-(\\d+)");
|
||||
@@ -46,7 +46,6 @@ public class DirGalleryProvider extends GalleryProvider implements Runnable {
|
||||
private Thread mBgThread;
|
||||
private volatile int mSize = STATE_WAIT;
|
||||
private String mError;
|
||||
private boolean mStarted = false;
|
||||
|
||||
public DirGalleryProvider(File dir) {
|
||||
mDir = dir;
|
||||
@@ -54,26 +53,21 @@ public class DirGalleryProvider extends GalleryProvider implements Runnable {
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
if (mStarted) {
|
||||
throw new IllegalStateException("Can't start it twice");
|
||||
}
|
||||
mStarted = true;
|
||||
super.start();
|
||||
|
||||
if (mBgThread == null || mBgThread.isInterrupted()) {
|
||||
mBgThread = new PriorityThread(this, TAG + '-' + sIdGenerator.incrementAndGet(),
|
||||
Process.THREAD_PRIORITY_BACKGROUND);
|
||||
mBgThread.start();
|
||||
}
|
||||
mBgThread = new PriorityThread(this, TAG + '-' + sIdGenerator.incrementAndGet(),
|
||||
Process.THREAD_PRIORITY_BACKGROUND);
|
||||
mBgThread.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
if (mBgThread == null || mBgThread.isInterrupted()) {
|
||||
return;
|
||||
}
|
||||
super.stop();
|
||||
|
||||
mBgThread.interrupt();
|
||||
mBgThread = null;
|
||||
if (mBgThread != null) {
|
||||
mBgThread.interrupt();
|
||||
mBgThread = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -82,16 +76,10 @@ public class DirGalleryProvider extends GalleryProvider implements Runnable {
|
||||
}
|
||||
|
||||
@Override
|
||||
@Result
|
||||
public int request(int index) {
|
||||
if (index < 0 || index >= size()) {
|
||||
return RESULT_ERROR;
|
||||
} else {
|
||||
synchronized (mRequests) {
|
||||
mRequests.add(index);
|
||||
mRequests.notify();
|
||||
}
|
||||
return RESULT_WAIT;
|
||||
public void request(int index) {
|
||||
synchronized (mRequests) {
|
||||
mRequests.add(index);
|
||||
mRequests.notify();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -108,7 +96,6 @@ public class DirGalleryProvider extends GalleryProvider implements Runnable {
|
||||
if (files == null) {
|
||||
mSize = STATE_ERROR;
|
||||
mError = GetText.getString(R.string.error_not_folder_path);
|
||||
mBgThread = null;
|
||||
|
||||
// Notify to to show error
|
||||
notifyDataChanged();
|
||||
@@ -139,6 +126,12 @@ public class DirGalleryProvider extends GalleryProvider implements Runnable {
|
||||
index = mRequests.pop();
|
||||
}
|
||||
|
||||
// Check index valid
|
||||
if (index < 0 || index >= files.length) {
|
||||
notifyPageFailed(index, GetText.getString(R.string.error_out_of_range));
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
InputStream is = new FileInputStream(new File(mDir, files[index]));
|
||||
Image image = Image.decode(is, false);
|
||||
@@ -152,9 +145,6 @@ public class DirGalleryProvider extends GalleryProvider implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
// Clear
|
||||
mBgThread = null;
|
||||
|
||||
Log.i(TAG, "ImageDecoder end");
|
||||
}
|
||||
|
||||
|
||||
@@ -16,30 +16,107 @@
|
||||
|
||||
package com.hippo.ehviewer.gallery;
|
||||
|
||||
public class EhGalleryProvider extends GalleryProvider {
|
||||
import android.content.Context;
|
||||
import android.support.annotation.Nullable;
|
||||
|
||||
import com.hippo.ehviewer.client.data.GalleryInfo;
|
||||
import com.hippo.ehviewer.spider.SpiderQueen;
|
||||
import com.hippo.image.Image;
|
||||
|
||||
public class EhGalleryProvider extends GalleryProvider implements SpiderQueen.OnSpiderListener {
|
||||
|
||||
private Context mContext;
|
||||
private GalleryInfo mGalleryInfo;
|
||||
@Nullable
|
||||
private SpiderQueen mSpiderQueen;
|
||||
|
||||
public EhGalleryProvider(Context context, GalleryInfo galleryInfo) {
|
||||
mContext = context;
|
||||
mGalleryInfo = galleryInfo;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
super.start();
|
||||
|
||||
mSpiderQueen = SpiderQueen.obtainSpiderQueen(mContext, mGalleryInfo, SpiderQueen.MODE_READ);
|
||||
mSpiderQueen.addOnSpiderListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
super.stop();
|
||||
|
||||
if (mSpiderQueen != null) {
|
||||
mSpiderQueen.removeOnSpiderListener(this);
|
||||
SpiderQueen.releaseSpiderQueen(mSpiderQueen, SpiderQueen.MODE_READ);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int size() {
|
||||
return 0;
|
||||
if (mSpiderQueen != null) {
|
||||
return mSpiderQueen.size();
|
||||
} else {
|
||||
return GalleryProvider.STATE_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int request(int index) {
|
||||
return 0;
|
||||
public void request(int index) {
|
||||
if (mSpiderQueen != null) {
|
||||
Object object = mSpiderQueen.request(index);
|
||||
if (object instanceof Float) {
|
||||
notifyPagePercent(index, (Float) object);
|
||||
} else if (object instanceof String) {
|
||||
notifyPageFailed(index, (String) object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getError() {
|
||||
return null;
|
||||
if (mSpiderQueen != null) {
|
||||
return mSpiderQueen.getError();
|
||||
} else {
|
||||
return "Error"; // TODO
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGetPages(int pages) {
|
||||
notifyDataChanged();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGet509(int index) {
|
||||
// TODO
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDownload(int index, long contentLength, long receivedSize, int bytesRead) {
|
||||
if (contentLength > 0) {
|
||||
notifyPagePercent(index, (float) receivedSize / contentLength);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSuccess(int index) {
|
||||
notifyDataChanged(index);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFailure(int index, String error) {
|
||||
notifyPageFailed(index, error);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGetImageSuccess(int index, Image image) {
|
||||
notifyPageSucceed(index, image);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGetImageFailure(int index, String error) {
|
||||
notifyPageFailed(index, error);
|
||||
}
|
||||
}
|
||||
@@ -18,28 +18,22 @@ package com.hippo.ehviewer.gallery;
|
||||
|
||||
import android.os.Handler;
|
||||
import android.support.annotation.IntDef;
|
||||
import android.support.annotation.UiThread;
|
||||
|
||||
import com.hippo.image.Image;
|
||||
import com.hippo.yorozuya.OSUtils;
|
||||
import com.hippo.yorozuya.Pool;
|
||||
import com.hippo.yorozuya.SimpleHandler;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class GalleryProvider {
|
||||
|
||||
@IntDef({RESULT_WAIT, RESULT_ERROR})
|
||||
@Retention(RetentionPolicy.SOURCE)
|
||||
public @interface Result {}
|
||||
|
||||
public static final int RESULT_WAIT = 0;
|
||||
public static final int RESULT_ERROR = 1;
|
||||
|
||||
public static final int STATE_WAIT = -1;
|
||||
public static final int STATE_ERROR = -2;
|
||||
|
||||
// With dot
|
||||
public static final String[] SUPPORT_IMAGE_EXTENSIONS = {
|
||||
".jpg", // Joint Photographic Experts Group
|
||||
".jpeg",
|
||||
@@ -47,34 +41,46 @@ public abstract class GalleryProvider {
|
||||
".gif", // Graphics Interchange Format
|
||||
};
|
||||
|
||||
private List<GalleryProviderListener> mGalleryProviderListeners = new ArrayList<>(2);
|
||||
private GalleryProviderListener mGalleryProviderListener;
|
||||
private Pool<NotifyTask> mNotifyTaskPool = new Pool<>(5);
|
||||
private Handler mHandler = SimpleHandler.getInstance();
|
||||
|
||||
public abstract void start();
|
||||
private boolean mStarted = false;
|
||||
|
||||
public abstract void stop();
|
||||
@UiThread
|
||||
public void start() {
|
||||
OSUtils.checkMainLoop();
|
||||
|
||||
if (mStarted) {
|
||||
throw new IllegalStateException("Can't start it twice");
|
||||
}
|
||||
mStarted = true;
|
||||
}
|
||||
|
||||
@UiThread
|
||||
public void stop() {
|
||||
OSUtils.checkMainLoop();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return {@link #STATE_WAIT} for wait, 0 for empty
|
||||
*/
|
||||
public abstract int size();
|
||||
|
||||
@Result
|
||||
public abstract int request(int index);
|
||||
public abstract void request(int index);
|
||||
|
||||
public abstract String getError();
|
||||
|
||||
public void addGalleryProviderListener(GalleryProviderListener listener) {
|
||||
mGalleryProviderListeners.add(listener);
|
||||
}
|
||||
|
||||
public void removeGalleryProviderListener(GalleryProviderListener listener) {
|
||||
mGalleryProviderListeners.remove(listener);
|
||||
public void setGalleryProviderListener(GalleryProviderListener listener) {
|
||||
mGalleryProviderListener = listener;
|
||||
}
|
||||
|
||||
public void notifyDataChanged() {
|
||||
notify(NotifyTask.TYPE_DATA_CHANGED, 0, 0.0f, null, null);
|
||||
notify(NotifyTask.TYPE_DATA_CHANGED, -1, 0.0f, null, null);
|
||||
}
|
||||
|
||||
public void notifyDataChanged(int index) {
|
||||
notify(NotifyTask.TYPE_DATA_CHANGED, index, 0.0f, null, null);
|
||||
}
|
||||
|
||||
public void notifyPagePercent(int index, float percent) {
|
||||
@@ -90,9 +96,14 @@ public abstract class GalleryProvider {
|
||||
}
|
||||
|
||||
private void notify(@NotifyTask.Type int type, int index, float percent, Image image, String error) {
|
||||
GalleryProviderListener listener = mGalleryProviderListener;
|
||||
if (listener == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
NotifyTask task = mNotifyTaskPool.pop();
|
||||
if (task == null) {
|
||||
task = new NotifyTask(mGalleryProviderListeners, mNotifyTaskPool);
|
||||
task = new NotifyTask(listener, mNotifyTaskPool);
|
||||
}
|
||||
task.setData(type, index, percent, image, error);
|
||||
mHandler.post(task);
|
||||
@@ -109,7 +120,7 @@ public abstract class GalleryProvider {
|
||||
public static final int TYPE_SUCCEED = 2;
|
||||
public static final int TYPE_FAILED = 3;
|
||||
|
||||
private List<GalleryProviderListener> mGalleryProviderListeners;
|
||||
private GalleryProviderListener mGalleryProviderListener;
|
||||
private Pool<NotifyTask> mPool;
|
||||
|
||||
@Type
|
||||
@@ -119,8 +130,8 @@ public abstract class GalleryProvider {
|
||||
private Image mImage;
|
||||
private String mError;
|
||||
|
||||
public NotifyTask(List<GalleryProviderListener> galleryProviderListeners, Pool<NotifyTask> pool) {
|
||||
mGalleryProviderListeners = galleryProviderListeners;
|
||||
public NotifyTask(GalleryProviderListener galleryProviderListener, Pool<NotifyTask> pool) {
|
||||
mGalleryProviderListener = galleryProviderListener;
|
||||
mPool = pool;
|
||||
}
|
||||
|
||||
@@ -136,24 +147,20 @@ public abstract class GalleryProvider {
|
||||
public void run() {
|
||||
switch (mType) {
|
||||
case TYPE_DATA_CHANGED:
|
||||
for (int i = 0, n = mGalleryProviderListeners.size(); i < n; i++) {
|
||||
mGalleryProviderListeners.get(i).onDataChanged();
|
||||
if (mIndex < 0) {
|
||||
mGalleryProviderListener.onDataChanged();
|
||||
} else {
|
||||
mGalleryProviderListener.onDataChanged(mIndex);
|
||||
}
|
||||
break;
|
||||
case TYPE_PERCENT:
|
||||
for (int i = 0, n = mGalleryProviderListeners.size(); i < n; i++) {
|
||||
mGalleryProviderListeners.get(i).onPagePercent(mIndex, mPercent);
|
||||
}
|
||||
mGalleryProviderListener.onPagePercent(mIndex, mPercent);
|
||||
break;
|
||||
case TYPE_SUCCEED:
|
||||
for (int i = 0, n = mGalleryProviderListeners.size(); i < n; i++) {
|
||||
mGalleryProviderListeners.get(i).onPageSucceed(mIndex, mImage);
|
||||
}
|
||||
mGalleryProviderListener.onPageSucceed(mIndex, mImage);
|
||||
break;
|
||||
case TYPE_FAILED:
|
||||
for (int i = 0, n = mGalleryProviderListeners.size(); i < n; i++) {
|
||||
mGalleryProviderListeners.get(i).onPageFailed(mIndex, mError);
|
||||
}
|
||||
mGalleryProviderListener.onPageFailed(mIndex, mError);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -27,4 +27,6 @@ public interface GalleryProviderListener {
|
||||
void onPageSucceed(int index, Image image);
|
||||
|
||||
void onPageFailed(int index, String error);
|
||||
|
||||
void onDataChanged(int index);
|
||||
}
|
||||
@@ -51,7 +51,6 @@ public class ZipGalleryProvider extends GalleryProvider implements Runnable {
|
||||
private Thread mBgThread;
|
||||
private volatile int mSize = STATE_WAIT;
|
||||
private String mError;
|
||||
private boolean mStarted = false;
|
||||
|
||||
public ZipGalleryProvider(File file) {
|
||||
mFile = file;
|
||||
@@ -59,26 +58,21 @@ public class ZipGalleryProvider extends GalleryProvider implements Runnable {
|
||||
|
||||
@Override
|
||||
public void start() {
|
||||
if (mStarted) {
|
||||
throw new IllegalStateException("Can't start it twice");
|
||||
}
|
||||
mStarted = true;
|
||||
super.start();
|
||||
|
||||
if (mBgThread == null || mBgThread.isInterrupted()) {
|
||||
mBgThread = new PriorityThread(this, TAG + '-' + sIdGenerator.incrementAndGet(),
|
||||
Process.THREAD_PRIORITY_BACKGROUND);
|
||||
mBgThread.start();
|
||||
}
|
||||
mBgThread = new PriorityThread(this, TAG + '-' + sIdGenerator.incrementAndGet(),
|
||||
Process.THREAD_PRIORITY_BACKGROUND);
|
||||
mBgThread.start();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void stop() {
|
||||
if (mBgThread == null || mBgThread.isInterrupted()) {
|
||||
return;
|
||||
}
|
||||
super.stop();
|
||||
|
||||
mBgThread.interrupt();
|
||||
mBgThread = null;
|
||||
if (mBgThread != null) {
|
||||
mBgThread.interrupt();
|
||||
mBgThread = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -87,15 +81,10 @@ public class ZipGalleryProvider extends GalleryProvider implements Runnable {
|
||||
}
|
||||
|
||||
@Override
|
||||
public int request(int index) {
|
||||
if (index < 0 || index >= mSize) {
|
||||
return RESULT_ERROR;
|
||||
} else {
|
||||
synchronized (mRequests) {
|
||||
mRequests.add(index);
|
||||
mRequests.notify();
|
||||
}
|
||||
return RESULT_WAIT;
|
||||
public void request(int index) {
|
||||
synchronized (mRequests) {
|
||||
mRequests.add(index);
|
||||
mRequests.notify();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,7 +112,6 @@ public class ZipGalleryProvider extends GalleryProvider implements Runnable {
|
||||
if (mError == null) {
|
||||
mError = GetText.getString(R.string.error_unknown);
|
||||
}
|
||||
mBgThread = null;
|
||||
|
||||
// Notify to to show error
|
||||
notifyDataChanged();
|
||||
@@ -163,6 +151,12 @@ public class ZipGalleryProvider extends GalleryProvider implements Runnable {
|
||||
index = mRequests.pop();
|
||||
}
|
||||
|
||||
// Check index valid
|
||||
if (index < 0 || index >= filenames.size()) {
|
||||
notifyPageFailed(index, GetText.getString(R.string.error_out_of_range));
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
ZipEntry zipEntry = zipFile.getEntry(filenames.get(index));
|
||||
if (zipEntry != null) {
|
||||
@@ -187,7 +181,6 @@ public class ZipGalleryProvider extends GalleryProvider implements Runnable {
|
||||
} catch (IOException e) {
|
||||
// Ignore
|
||||
}
|
||||
mBgThread = null;
|
||||
|
||||
Log.i(TAG, "ImageDecoder end");
|
||||
}
|
||||
|
||||
@@ -35,6 +35,7 @@ import com.hippo.yorozuya.MathUtils;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
|
||||
// TODO Not safe ! Ensure change component in render thread
|
||||
public class PagerLayoutManager extends GalleryView.LayoutManager {
|
||||
|
||||
@IntDef({MODE_LEFT_TO_RIGHT, MODE_RIGHT_TO_LEFT})
|
||||
|
||||
@@ -30,6 +30,7 @@ import com.hippo.yorozuya.AssertUtils;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
|
||||
// TODO Not safe ! Ensure change component in render thread
|
||||
public class ScrollLayoutManager extends GalleryView.LayoutManager {
|
||||
|
||||
private static final String TAG = ScrollLayoutManager.class.getSimpleName();
|
||||
|
||||
@@ -0,0 +1,296 @@
|
||||
/*
|
||||
* 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.spider;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.webkit.MimeTypeMap;
|
||||
|
||||
import com.hippo.beerbelly.SimpleDiskCache;
|
||||
import com.hippo.ehviewer.Settings;
|
||||
import com.hippo.ehviewer.client.EhCacheKeyFactory;
|
||||
import com.hippo.ehviewer.client.data.GalleryInfo;
|
||||
import com.hippo.ehviewer.gallery.GalleryProvider;
|
||||
import com.hippo.io.UniFileInputStreamPipe;
|
||||
import com.hippo.io.UniFileOutputStreamPipe;
|
||||
import com.hippo.unifile.UniFile;
|
||||
import com.hippo.yorozuya.FileUtils;
|
||||
import com.hippo.yorozuya.IOUtils;
|
||||
import com.hippo.yorozuya.Utilities;
|
||||
import com.hippo.yorozuya.io.InputStreamPipe;
|
||||
import com.hippo.yorozuya.io.OutputStreamPipe;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Locale;
|
||||
|
||||
public final class SpiderDen {
|
||||
|
||||
private UniFile mDownloadDir;
|
||||
private volatile int mMode = SpiderQueen.MODE_READ;
|
||||
private final int mGid;
|
||||
|
||||
@Nullable
|
||||
private static SimpleDiskCache sCache;
|
||||
|
||||
public static void initialize(Context context) {
|
||||
try {
|
||||
sCache = new SimpleDiskCache(new File(context.getCacheDir(), "image"), 160 * 1024 * 1024);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public SpiderDen(GalleryInfo galleryInfo) {
|
||||
mGid = galleryInfo.gid;
|
||||
UniFile dir = Settings.getDownloadLocation();
|
||||
if (dir != null) {
|
||||
mDownloadDir = dir.subFile(FileUtils.sanitizeFilename(galleryInfo.gid + "-" + galleryInfo.title));
|
||||
}
|
||||
}
|
||||
|
||||
public void setMode(@SpiderQueen.Mode int mode) {
|
||||
mMode = mode;
|
||||
|
||||
if (mode == SpiderQueen.MODE_DOWNLOAD) {
|
||||
ensureDownloadDir();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean ensureDownloadDir() {
|
||||
return mDownloadDir != null && mDownloadDir.ensureDir();
|
||||
}
|
||||
|
||||
public UniFile getDownloadDir() {
|
||||
return mDownloadDir != null && mDownloadDir.isDirectory() ? mDownloadDir : null;
|
||||
}
|
||||
|
||||
private boolean containInCache(int index) {
|
||||
if (sCache == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
String key = EhCacheKeyFactory.getImageKey(mGid, index);
|
||||
return sCache.contain(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param extension with dot
|
||||
*/
|
||||
public static String generateImageFilename(int index, String extension) {
|
||||
return String.format(Locale.US, "%08d%s", index + 1, extension);
|
||||
}
|
||||
|
||||
private static UniFile findImageFile(UniFile dir, int index) {
|
||||
for (String extension : GalleryProvider.SUPPORT_IMAGE_EXTENSIONS) {
|
||||
String filename = generateImageFilename(index, extension);
|
||||
UniFile file = dir.findFile(filename);
|
||||
if (file != null) {
|
||||
return file;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean containInDownloadDir(int index) {
|
||||
UniFile dir = getDownloadDir();
|
||||
if (dir == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Find image file in download dir
|
||||
return findImageFile(dir, index) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param extension with dot
|
||||
*/
|
||||
private String fixExtension(String extension) {
|
||||
if (Utilities.contain(GalleryProvider.SUPPORT_IMAGE_EXTENSIONS, extension)) {
|
||||
return extension;
|
||||
} else {
|
||||
return GalleryProvider.SUPPORT_IMAGE_EXTENSIONS[0];
|
||||
}
|
||||
}
|
||||
|
||||
private boolean copyFromCacheToDownloadDir(int index) {
|
||||
if (sCache == null) {
|
||||
return false;
|
||||
}
|
||||
UniFile dir = getDownloadDir();
|
||||
if (dir == null) {
|
||||
return false;
|
||||
}
|
||||
// Find image file in cache
|
||||
String key = EhCacheKeyFactory.getImageKey(mGid, index);
|
||||
InputStreamPipe pipe = sCache.getInputStreamPipe(key);
|
||||
if (pipe == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
OutputStream os = null;
|
||||
try {
|
||||
// Get extension
|
||||
String extension;
|
||||
BitmapFactory.Options options = new BitmapFactory.Options();
|
||||
options.inJustDecodeBounds = true;
|
||||
pipe.obtain();
|
||||
BitmapFactory.decodeStream(pipe.open(), null, options);
|
||||
pipe.close();
|
||||
extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(options.outMimeType);
|
||||
if (extension != null) {
|
||||
extension = '.' + extension;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
// Fix extension
|
||||
extension = fixExtension(extension);
|
||||
// Copy from cache to download dir
|
||||
UniFile file = dir.createFile(generateImageFilename(index, extension));
|
||||
if (file == null) {
|
||||
return false;
|
||||
}
|
||||
os = file.openOutputStream();
|
||||
IOUtils.copy(pipe.open(), os);
|
||||
return true;
|
||||
} catch (IOException e) {
|
||||
return false;
|
||||
} finally {
|
||||
IOUtils.closeQuietly(os);
|
||||
pipe.close();
|
||||
pipe.release();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean contain(int index) {
|
||||
if (mMode == SpiderQueen.MODE_READ) {
|
||||
return containInCache(index) || containInDownloadDir(index);
|
||||
} else if (mMode == SpiderQueen.MODE_DOWNLOAD) {
|
||||
return containInDownloadDir(index) || copyFromCacheToDownloadDir(index);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
private void removeFromCache(int index) {
|
||||
if (sCache == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
String key = EhCacheKeyFactory.getImageKey(mGid, index);
|
||||
sCache.remove(key);
|
||||
}
|
||||
|
||||
private void removeFromDownloadDir(int index) {
|
||||
UniFile dir = getDownloadDir();
|
||||
if (dir == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (int i = 0, n = GalleryProvider.SUPPORT_IMAGE_EXTENSIONS.length; i < n; i++) {
|
||||
String filename = generateImageFilename(index, GalleryProvider.SUPPORT_IMAGE_EXTENSIONS[i]);
|
||||
UniFile file = dir.subFile(filename);
|
||||
if (file != null) {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void remove(int index) {
|
||||
removeFromCache(index);
|
||||
removeFromDownloadDir(index);
|
||||
}
|
||||
|
||||
private OutputStreamPipe openCacheOutputStreamPipe(int index) {
|
||||
if (sCache == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String key = EhCacheKeyFactory.getImageKey(mGid, index);
|
||||
return sCache.getOutputStreamPipe(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param extension without dot
|
||||
*/
|
||||
private OutputStreamPipe openDownloadOutputStreamPipe(int index, @Nullable String extension) {
|
||||
UniFile dir = getDownloadDir();
|
||||
if (dir == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
extension = fixExtension('.' + extension);
|
||||
UniFile file = dir.createFile(generateImageFilename(index, extension));
|
||||
if (file != null) {
|
||||
return new UniFileOutputStreamPipe(file);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public OutputStreamPipe openOutputStreamPipe(int index, @Nullable String extension) {
|
||||
if (mMode == SpiderQueen.MODE_READ) {
|
||||
return openCacheOutputStreamPipe(index);
|
||||
} else if (mMode == SpiderQueen.MODE_DOWNLOAD) {
|
||||
return openDownloadOutputStreamPipe(index, extension);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private InputStreamPipe openCacheInputStreamPipe(int index) {
|
||||
if (sCache == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String key = EhCacheKeyFactory.getImageKey(mGid, index);
|
||||
return sCache.getInputStreamPipe(key);
|
||||
}
|
||||
|
||||
public InputStreamPipe openDownloadInputStreamPipe(int index) {
|
||||
UniFile dir = getDownloadDir();
|
||||
if (dir == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
UniFile file = findImageFile(dir, index);
|
||||
if (file != null) {
|
||||
return new UniFileInputStreamPipe(file);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public InputStreamPipe openInputStreamPipe(int index) {
|
||||
if (mMode == SpiderQueen.MODE_READ) {
|
||||
InputStreamPipe pipe = openCacheInputStreamPipe(index);
|
||||
if (pipe == null) {
|
||||
pipe = openDownloadInputStreamPipe(index);
|
||||
}
|
||||
return pipe;
|
||||
} else if (mMode == SpiderQueen.MODE_DOWNLOAD) {
|
||||
return openDownloadInputStreamPipe(index);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* 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.spider;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.Log;
|
||||
import android.util.SparseArray;
|
||||
|
||||
import com.hippo.unifile.UniFile;
|
||||
import com.hippo.yorozuya.IOUtils;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.OutputStreamWriter;
|
||||
|
||||
public class SpiderInfo {
|
||||
|
||||
private static final String TAG = SpiderInfo.class.getSimpleName();
|
||||
|
||||
static final String TOKEN_FAILED = "failed";
|
||||
static final String TOKEN_WAIT = "wait";
|
||||
|
||||
int currentIndex = 0;
|
||||
int gid = -1;
|
||||
String token = null;
|
||||
int pages = -1;
|
||||
int previewPages = -1;
|
||||
int previewPerPage = -1;
|
||||
SparseArray<String> pTokenMap = null;
|
||||
|
||||
@SuppressWarnings("InfiniteLoopStatement")
|
||||
public static SpiderInfo readFromUniFile(@Nullable UniFile file) {
|
||||
if (file == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
InputStream is = null;
|
||||
SpiderInfo spiderInfo = null;
|
||||
try {
|
||||
is = file.openInputStream();
|
||||
spiderInfo = new SpiderInfo();
|
||||
// Current index
|
||||
spiderInfo.currentIndex = Integer.parseInt(IOUtils.readAsciiLine(is), 16);
|
||||
// Gid
|
||||
spiderInfo.gid = Integer.parseInt(IOUtils.readAsciiLine(is));
|
||||
// Token
|
||||
spiderInfo.token = IOUtils.readAsciiLine(is);
|
||||
// Deprecated, mode, only ex is support now, MUST be 1
|
||||
if (1 != Integer.parseInt(IOUtils.readAsciiLine(is))) {
|
||||
Log.w(TAG, "Not ex mode");
|
||||
return null;
|
||||
}
|
||||
// Preview pages
|
||||
spiderInfo.previewPages = Integer.parseInt(IOUtils.readAsciiLine(is));
|
||||
// Preview pre page
|
||||
spiderInfo.previewPerPage = Integer.parseInt(IOUtils.readAsciiLine(is));
|
||||
// Pages
|
||||
spiderInfo.pages = Integer.parseInt(IOUtils.readAsciiLine(is));
|
||||
// PToken
|
||||
spiderInfo.pTokenMap = new SparseArray<>(spiderInfo.pages);
|
||||
while (true) { // EOFException will raise
|
||||
String line = IOUtils.readAsciiLine(is);
|
||||
int pos = line.indexOf(" ");
|
||||
if (pos > 0 || pos < line.length() - 1) {
|
||||
int index = Integer.parseInt(line.substring(0, pos));
|
||||
String pToken = line.substring(pos + 1);
|
||||
spiderInfo.pTokenMap.put(index, pToken);
|
||||
} else {
|
||||
Log.e(TAG, "Can't parse index and pToken, index = " + pos);
|
||||
}
|
||||
}
|
||||
} catch (IOException | NumberFormatException e) {
|
||||
e.printStackTrace();
|
||||
} finally {
|
||||
IOUtils.closeQuietly(is);
|
||||
}
|
||||
|
||||
if (spiderInfo == null || spiderInfo.gid == -1 || spiderInfo.token == null ||
|
||||
spiderInfo.previewPages == -1 || spiderInfo.previewPerPage == -1 ||
|
||||
spiderInfo.pages == -1 || spiderInfo.pTokenMap == null) {
|
||||
return null;
|
||||
} else {
|
||||
return spiderInfo;
|
||||
}
|
||||
}
|
||||
|
||||
public void write(@NonNull OutputStream os) {
|
||||
OutputStreamWriter writer = null;
|
||||
try {
|
||||
writer = new OutputStreamWriter(os);
|
||||
writer.write(String.format("%08x", currentIndex));
|
||||
writer.write("\n");
|
||||
writer.write(Integer.toString(gid));
|
||||
writer.write("\n");
|
||||
writer.write(token);
|
||||
writer.write("\n");
|
||||
writer.write('1');
|
||||
writer.write("\n");
|
||||
writer.write(Integer.toString(previewPages));
|
||||
writer.write("\n");
|
||||
writer.write(Integer.toString(previewPerPage));
|
||||
writer.write("\n");
|
||||
writer.write(Integer.toString(pages));
|
||||
writer.write("\n");
|
||||
for (int i = 0; i < pTokenMap.size(); i++) {
|
||||
if (TOKEN_FAILED.equals(pTokenMap.valueAt(i))) {
|
||||
continue;
|
||||
}
|
||||
writer.write(Integer.toString(pTokenMap.keyAt(i)));
|
||||
writer.write(" ");
|
||||
writer.write(pTokenMap.valueAt(i));
|
||||
writer.write("\n");
|
||||
}
|
||||
writer.flush();
|
||||
} catch (IOException e) {
|
||||
// Ignore
|
||||
} finally {
|
||||
IOUtils.closeQuietly(writer);
|
||||
IOUtils.closeQuietly(os);
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -26,7 +26,9 @@ import android.util.SparseIntArray;
|
||||
import android.view.KeyEvent;
|
||||
|
||||
import com.hippo.ehviewer.R;
|
||||
import com.hippo.ehviewer.client.data.GalleryInfo;
|
||||
import com.hippo.ehviewer.gallery.DirGalleryProvider;
|
||||
import com.hippo.ehviewer.gallery.EhGalleryProvider;
|
||||
import com.hippo.ehviewer.gallery.GalleryProvider;
|
||||
import com.hippo.ehviewer.gallery.GalleryProviderListener;
|
||||
import com.hippo.ehviewer.gallery.ZipGalleryProvider;
|
||||
@@ -49,13 +51,11 @@ public class GalleryActivity extends AppCompatActivity implements GalleryProvide
|
||||
|
||||
public static final String KEY_ACTION = "action";
|
||||
public static final String KEY_FILENAME = "filename";
|
||||
public static final String KEY_GID = "gid";
|
||||
public static final String KEY_TOKEN = "token";
|
||||
public static final String KEY_GALLERY_INFO = "gallery_info";
|
||||
|
||||
private String mAction;
|
||||
private String mFilename;
|
||||
private int mGid;
|
||||
private String mToken;
|
||||
private GalleryInfo mGalleryInfo;
|
||||
|
||||
@Nullable
|
||||
private GalleryView mGalleryView;
|
||||
@@ -83,7 +83,9 @@ public class GalleryActivity extends AppCompatActivity implements GalleryProvide
|
||||
mGalleryProvider = new ZipGalleryProvider(new File(mFilename));
|
||||
}
|
||||
} else if (ACTION_EH.equals(mAction)) {
|
||||
|
||||
if (mGalleryInfo != null) {
|
||||
mGalleryProvider = new EhGalleryProvider(this, mGalleryInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,16 +97,14 @@ public class GalleryActivity extends AppCompatActivity implements GalleryProvide
|
||||
|
||||
mAction = intent.getAction();
|
||||
mFilename = intent.getStringExtra(KEY_FILENAME);
|
||||
mGid = intent.getIntExtra(KEY_GID, -1);
|
||||
mToken = intent.getStringExtra(KEY_TOKEN);
|
||||
mGalleryInfo = intent.getParcelableExtra(KEY_GALLERY_INFO);
|
||||
buildProvider();
|
||||
}
|
||||
|
||||
private void onRestore(@NonNull Bundle savedInstanceState) {
|
||||
mAction = savedInstanceState.getString(KEY_ACTION);
|
||||
mFilename = savedInstanceState.getString(KEY_FILENAME);
|
||||
mGid = savedInstanceState.getInt(KEY_GID, -1);
|
||||
mToken = savedInstanceState.getString(KEY_TOKEN);
|
||||
mGalleryInfo = savedInstanceState.getParcelable(KEY_GALLERY_INFO);
|
||||
buildProvider();
|
||||
}
|
||||
|
||||
@@ -113,8 +113,9 @@ public class GalleryActivity extends AppCompatActivity implements GalleryProvide
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putString(KEY_ACTION, mAction);
|
||||
outState.putString(KEY_FILENAME, mFilename);
|
||||
outState.putInt(KEY_GID, mGid);
|
||||
outState.putString(KEY_TOKEN, mToken);
|
||||
if (mGalleryInfo != null) {
|
||||
outState.putParcelable(KEY_GALLERY_INFO, mGalleryInfo);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -131,7 +132,7 @@ public class GalleryActivity extends AppCompatActivity implements GalleryProvide
|
||||
finish();
|
||||
return;
|
||||
}
|
||||
mGalleryProvider.addGalleryProviderListener(this);
|
||||
mGalleryProvider.setGalleryProviderListener(this);
|
||||
mGalleryProvider.start();
|
||||
|
||||
setContentView(R.layout.activity_gallery);
|
||||
@@ -161,7 +162,7 @@ public class GalleryActivity extends AppCompatActivity implements GalleryProvide
|
||||
mPageTextTexture = null;
|
||||
}
|
||||
if (mGalleryProvider != null) {
|
||||
mGalleryProvider.removeGalleryProviderListener(this);
|
||||
mGalleryProvider.setGalleryProviderListener(null);
|
||||
mGalleryProvider.stop();
|
||||
mGalleryProvider = null;
|
||||
}
|
||||
@@ -299,6 +300,14 @@ public class GalleryActivity extends AppCompatActivity implements GalleryProvide
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDataChanged(int index) {
|
||||
GalleryPageView page = findPageByIndex(index);
|
||||
if (page != null && mGalleryProvider != null) {
|
||||
mGalleryProvider.request(index);
|
||||
}
|
||||
}
|
||||
|
||||
private class GalleryPageIterator extends GalleryView.PageIterator {
|
||||
|
||||
private IntIdGenerator mIdGenerator = new IntIdGenerator();
|
||||
|
||||
@@ -871,8 +871,18 @@ public class GalleryDetailScene extends BaseScene implements View.OnClickListene
|
||||
} else if (mDownload == v) {
|
||||
// TODO
|
||||
} else if (mRead == v) {
|
||||
Intent intent = new Intent(getActivity(), GalleryActivity.class);
|
||||
startActivity(intent);
|
||||
GalleryInfo galleryInfo = null;
|
||||
if (mGalleryInfo != null) {
|
||||
galleryInfo = mGalleryInfo;
|
||||
} else if (mGalleryDetail != null) {
|
||||
galleryInfo = mGalleryDetail;
|
||||
}
|
||||
if (galleryInfo != null) {
|
||||
Intent intent = new Intent(getActivity(), GalleryActivity.class);
|
||||
intent.setAction(GalleryActivity.ACTION_EH);
|
||||
intent.putExtra(GalleryActivity.KEY_GALLERY_INFO, galleryInfo);
|
||||
startActivity(intent);
|
||||
}
|
||||
} else if (mInfo == v) {
|
||||
Bundle args = new Bundle();
|
||||
args.putParcelable(GalleryInfoScene.KEY_GALLERY_DETAIL, mGalleryDetail);
|
||||
@@ -929,11 +939,12 @@ public class GalleryDetailScene extends BaseScene implements View.OnClickListene
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
if (mViewTransition.getShownViewIndex() == 0 && ApiHelper.SUPPORT_TRANSITION) {
|
||||
if (mViewTransition.getShownViewIndex() == 0 && ApiHelper.SUPPORT_TRANSITION && mThumb.isShown()) {
|
||||
int[] location = new int[2];
|
||||
mThumb.getLocationInWindow(location);
|
||||
// Only show transaction when thumb can be seen
|
||||
if (location[1] + mThumb.getHeight() > 0) {
|
||||
setTransitionName();
|
||||
finish(new EnterGalleryListTransaction(mThumb, mTitle, mUploader, mCategory));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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.io;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.hippo.yorozuya.IOUtils;
|
||||
import com.hippo.yorozuya.io.InputStreamPipe;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class FileInputStreamPipe implements InputStreamPipe {
|
||||
|
||||
private File mFile;
|
||||
private InputStream mIs;
|
||||
|
||||
public FileInputStreamPipe(File file) {
|
||||
mFile = file;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void obtain() {
|
||||
// Empty
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
// Empty
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public InputStream open() throws IOException {
|
||||
if (mIs != null) {
|
||||
throw new IllegalStateException("Please close it first");
|
||||
}
|
||||
|
||||
mIs = new FileInputStream(mFile);
|
||||
return mIs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
IOUtils.closeQuietly(mIs);
|
||||
mIs = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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.io;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.hippo.yorozuya.IOUtils;
|
||||
import com.hippo.yorozuya.io.OutputStreamPipe;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class FileOutputStreamPipe implements OutputStreamPipe {
|
||||
|
||||
private File mFile;
|
||||
private OutputStream mOs;
|
||||
|
||||
public FileOutputStreamPipe(File file) {
|
||||
mFile = file;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void obtain() {
|
||||
// Empty
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
// Empty
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public OutputStream open() throws IOException {
|
||||
if (mOs != null) {
|
||||
throw new IllegalStateException("Please close it first");
|
||||
}
|
||||
|
||||
mOs = new FileOutputStream(mFile);
|
||||
return mOs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
IOUtils.closeQuietly(mOs);
|
||||
mOs = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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.io;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.hippo.unifile.UniFile;
|
||||
import com.hippo.yorozuya.IOUtils;
|
||||
import com.hippo.yorozuya.io.InputStreamPipe;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class UniFileInputStreamPipe implements InputStreamPipe {
|
||||
|
||||
private UniFile mFile;
|
||||
private InputStream mIs;
|
||||
|
||||
public UniFileInputStreamPipe(UniFile file) {
|
||||
mFile = file;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void obtain() {
|
||||
// Empty
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
// Empty
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public InputStream open() throws IOException {
|
||||
if (mIs != null) {
|
||||
throw new IllegalStateException("Please close it first");
|
||||
}
|
||||
|
||||
mIs = mFile.openInputStream();
|
||||
return mIs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
IOUtils.closeQuietly(mIs);
|
||||
mIs = null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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.io;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
|
||||
import com.hippo.unifile.UniFile;
|
||||
import com.hippo.yorozuya.IOUtils;
|
||||
import com.hippo.yorozuya.io.OutputStreamPipe;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
public class UniFileOutputStreamPipe implements OutputStreamPipe {
|
||||
|
||||
private UniFile mUniFile;
|
||||
|
||||
private OutputStream mOs;
|
||||
|
||||
public UniFileOutputStreamPipe(UniFile uniFile) {
|
||||
mUniFile = uniFile;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void obtain() {
|
||||
// Empty
|
||||
}
|
||||
|
||||
@Override
|
||||
public void release() {
|
||||
// Empty
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull OutputStream open() throws IOException {
|
||||
if (mOs != null) {
|
||||
throw new IllegalStateException("Please close it first");
|
||||
}
|
||||
|
||||
mOs = mUniFile.openOutputStream();
|
||||
return mOs;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() {
|
||||
IOUtils.closeQuietly(mOs);
|
||||
mOs = null;
|
||||
}
|
||||
}
|
||||
@@ -26,16 +26,8 @@ public class ChromeRequestBuilder extends Request.Builder {
|
||||
private static final String CHROME_USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) " +
|
||||
"AppleWebKit/537.36 (KHTML, like Gecko) Chrome/48.0.2564.103 Safari/537.36";
|
||||
|
||||
public ChromeRequestBuilder(String url) {
|
||||
URL u;
|
||||
try {
|
||||
u = new URL(url);
|
||||
} catch (MalformedURLException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
|
||||
url(u);
|
||||
|
||||
public ChromeRequestBuilder(String url) throws MalformedURLException {
|
||||
url(new URL(url));
|
||||
addHeader("User-Agent", CHROME_USER_AGENT);
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user