完善下载功能
This commit is contained in:
1 parent
05cfabae10
commit
7235e3abd5
12 files changed
+523
-89
No files matched your search
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (C) 2014 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 com.hippo.ehviewer.data.GalleryInfo;
|
||||
|
||||
public class GalleryDownloadInfo {
|
||||
|
||||
public static final int NONE = 0x0;
|
||||
public static final int DOWNLOADING = 0x1;
|
||||
public static final int FINISHED = 0x2;
|
||||
|
||||
public GalleryInfo galleryInfo;
|
||||
|
||||
// For ui set progressbar
|
||||
public int picNum;
|
||||
public int downloadNum;
|
||||
|
||||
public int state;
|
||||
|
||||
public GalleryDownloadInfo(GalleryInfo galleryInfo) {
|
||||
this(galleryInfo, NONE);
|
||||
}
|
||||
|
||||
public GalleryDownloadInfo(GalleryInfo galleryInfo, int state) {
|
||||
this.galleryInfo = galleryInfo;
|
||||
this.state = state == DOWNLOADING ? NONE : FINISHED;
|
||||
}
|
||||
}
|
||||
@@ -16,66 +16,236 @@
|
||||
|
||||
package com.hippo.ehviewer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.io.File;
|
||||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import com.hippo.ehviewer.data.Data;
|
||||
import com.hippo.ehviewer.data.DownloadInfo;
|
||||
import com.hippo.ehviewer.data.GalleryInfo;
|
||||
import com.hippo.ehviewer.data.PreviewList;
|
||||
import com.hippo.ehviewer.ehclient.DetailParser;
|
||||
import com.hippo.ehviewer.ehclient.EhClient;
|
||||
import com.hippo.ehviewer.network.HttpHelper;
|
||||
import com.hippo.ehviewer.util.Config;
|
||||
import com.hippo.ehviewer.util.Util;
|
||||
|
||||
public class GallerysDownloader {
|
||||
|
||||
/**
|
||||
* Download a gallery
|
||||
*
|
||||
* @author Hippo
|
||||
*
|
||||
*/
|
||||
|
||||
// TODO For gallerys whose Resized is Originals,
|
||||
// we can get download info from hathdl
|
||||
|
||||
public class GallerysDownloader implements Runnable {
|
||||
private static final String TAG = GallerysDownloader.class.getSimpleName();
|
||||
|
||||
private static final int MAX_RETRY = 3;
|
||||
|
||||
private static final int OK = 0x0;
|
||||
private static final int FAIL = 0x1;
|
||||
private static final int STOP = 0x2;
|
||||
|
||||
private static final int MAX_DOWNLOAD_THREAD_NUM = 3;
|
||||
|
||||
private final Context mContext;
|
||||
private final GalleryInfo mGalleryInfo;
|
||||
private int mPageIndex;
|
||||
private int mPageSum;
|
||||
private int mPagePerDp;
|
||||
private PreviewList[] mPages;
|
||||
private final Thread mMainThread;
|
||||
private final Queue<Integer> mRequstDetailPage;
|
||||
private final Queue<Integer> mRequstPage;
|
||||
private int downloadThreadNum = 0;
|
||||
private final File mDownloadDir;
|
||||
|
||||
public GallerysDownloader(Context context, GalleryInfo galleryInfo) {
|
||||
this(context, galleryInfo, 0);
|
||||
}
|
||||
|
||||
public GallerysDownloader(Context context, GalleryInfo galleryInfo, int startIndex) {
|
||||
mContext = context;
|
||||
mGalleryInfo = galleryInfo;
|
||||
mPageIndex = startIndex;
|
||||
mDownloadDir = new File(Config.getDownloadPath(),
|
||||
Util.rightFileName(mGalleryInfo.gid + '-' + mGalleryInfo.title));
|
||||
mDownloadDir.mkdirs();
|
||||
// TODO What if these is a file with the same name
|
||||
|
||||
mMainThread = new Thread(this);
|
||||
mRequstDetailPage = new LinkedList<Integer>();
|
||||
mRequstPage = new LinkedList<Integer>();
|
||||
}
|
||||
|
||||
public void start() {
|
||||
mMainThread.start();
|
||||
}
|
||||
|
||||
private int getDetailPageForPageIndex(int pageIndex) {
|
||||
return pageIndex / mPagePerDp;
|
||||
}
|
||||
|
||||
private boolean parserDetailPage(HttpHelper hh, DetailParser dp, int page, int mode) {
|
||||
int times = 0;
|
||||
while(times++ < MAX_RETRY) {
|
||||
hh.reset();
|
||||
dp.reset();
|
||||
// For get more page url one time
|
||||
hh.setPreviewMode(Config.PREVIEW_MODE_NORMAL);
|
||||
String body = hh.get(EhClient.getDetailUrl(mGalleryInfo.gid, mGalleryInfo.token, page));
|
||||
if (body == null)
|
||||
continue;
|
||||
|
||||
if (dp.parser(body, mode) != mode)
|
||||
continue;
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main thread body
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
int detailPageMax = 0;
|
||||
HttpHelper hh = new HttpHelper(mContext);
|
||||
DetailParser dp = new DetailParser();
|
||||
|
||||
// Get detail info, pages, previewsum, previewPerPage
|
||||
if (parserDetailPage(hh, dp, 0, DetailParser.DETAIL &
|
||||
DetailParser.PREVIEW_INFO & DetailParser.PREVIEW)) {
|
||||
// Get Ok
|
||||
mPageSum = dp.pages;
|
||||
mPagePerDp = dp.previewPerPage;
|
||||
mPages = new PreviewList[dp.previewSum];
|
||||
mPages[0] = dp.previewList;
|
||||
detailPageMax = dp.pages / dp.previewPerPage;
|
||||
} else {
|
||||
// TODO Get error, do something
|
||||
}
|
||||
|
||||
int startPageIndex = mPageIndex;
|
||||
|
||||
// Start get
|
||||
for (downloadThreadNum = 0; downloadThreadNum < MAX_DOWNLOAD_THREAD_NUM; downloadThreadNum++) {
|
||||
new DownloadThread().start();
|
||||
}
|
||||
|
||||
// Start get other page from startindex
|
||||
int detailPage = getDetailPageForPageIndex(startPageIndex);
|
||||
// Already get page 0
|
||||
if (detailPage == 0)
|
||||
detailPage++;
|
||||
for (; detailPage <= detailPageMax; detailPage++) {
|
||||
if (parserDetailPage(hh, dp, detailPage, DetailParser.PREVIEW)) {
|
||||
mPages[detailPage] = dp.previewList;
|
||||
} else {
|
||||
// TODO Get error, do something
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
class DownloadThread extends Thread {
|
||||
|
||||
private final HttpHelper mHttpHelper;
|
||||
|
||||
public DownloadThread() {
|
||||
mHttpHelper = new HttpHelper(mContext);
|
||||
}
|
||||
|
||||
private int getTargetPageIndex() {
|
||||
synchronized(mRequstPage) {
|
||||
if (mRequstPage.isEmpty()) {
|
||||
return mPageIndex++;
|
||||
} else {
|
||||
return mRequstPage.poll();
|
||||
}
|
||||
}
|
||||
}
|
||||
/*
|
||||
private String getImageUrlForPage() {
|
||||
int times = 0;
|
||||
while(times++ < MAX_RETRY) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public int downloadImage(String pageUrl, int index) {
|
||||
String body = mHttpHelper.get(pageUrl);
|
||||
|
||||
|
||||
}
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
downloadThreadNum--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
private AppContext mAppContext;
|
||||
|
||||
|
||||
private Data mData;
|
||||
private List<DownloadInfo> mDownloadList;
|
||||
private String[] mPageTokes;
|
||||
private DownloadInfo curDownloadInfo;
|
||||
private OnGalleryDownloadListener mListener;
|
||||
|
||||
|
||||
private static DownloadInfo emptyDownloadInfo = new DownloadInfo(null);
|
||||
|
||||
|
||||
public GallerysDownloader(AppContext appContext) {
|
||||
mAppContext = appContext;
|
||||
mPageTokes = null;
|
||||
mData = mAppContext.getData();
|
||||
mDownloadList = mData.getAllDownloads();
|
||||
}
|
||||
|
||||
|
||||
public void setOnGalleryDownloadListener(OnGalleryDownloadListener l) {
|
||||
mListener = l;
|
||||
}
|
||||
|
||||
|
||||
public synchronized void add(GalleryInfo galleryInfo) {
|
||||
DownloadInfo downloadInfo = new DownloadInfo(galleryInfo);
|
||||
mData.addDownload(downloadInfo);
|
||||
downloadInfo.setDownloadState(DownloadInfo.WAITING);
|
||||
|
||||
|
||||
checkDownloadThread();
|
||||
}
|
||||
|
||||
|
||||
public synchronized boolean start(int index) {
|
||||
DownloadInfo downloadInfo = mDownloadList.get(index);
|
||||
if (downloadInfo.getDownloadState() == DownloadInfo.NONE
|
||||
&& downloadInfo.getState() != DownloadInfo.COMPLETED) {
|
||||
downloadInfo.setDownloadState(DownloadInfo.WAITING);
|
||||
|
||||
|
||||
checkDownloadThread();
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private synchronized void checkDownloadThread() {
|
||||
if (curDownloadInfo == null) {
|
||||
curDownloadInfo = emptyDownloadInfo;
|
||||
new Thread(new DownloadGallery()).start();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private synchronized DownloadInfo getFirstWaiting() {
|
||||
for (DownloadInfo downloadInfo : mDownloadList) {
|
||||
if (downloadInfo.getDownloadState() == DownloadInfo.WAITING)
|
||||
@@ -83,7 +253,7 @@ public class GallerysDownloader {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private String getUrlContext(HttpHelper hp, String url) {
|
||||
int times = 3;
|
||||
String pageContent;
|
||||
@@ -94,7 +264,7 @@ public class GallerysDownloader {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private class DownloadGallery implements Runnable {
|
||||
@Override
|
||||
public void run() {
|
||||
@@ -102,10 +272,10 @@ public class GallerysDownloader {
|
||||
curDownloadInfo.setDownloadState(DownloadInfo.DOWNLOADING);
|
||||
if (mListener != null)
|
||||
mListener.onGalleryDownloadStart(curDownloadInfo);
|
||||
|
||||
|
||||
// get
|
||||
GalleryInfo galleryInfo = curDownloadInfo.getGalleryInfo();
|
||||
|
||||
|
||||
HttpHelper hp = new HttpHelper(mAppContext);
|
||||
String url = EhClient.getDetailUrl(galleryInfo.gid, galleryInfo.token,
|
||||
curDownloadInfo.getMode());
|
||||
@@ -116,19 +286,20 @@ public class GallerysDownloader {
|
||||
// New turn
|
||||
new Thread(new DownloadGallery()).start();
|
||||
} else {
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
interface OnGalleryDownloadListener {
|
||||
void onGalleryDownloadStart(DownloadInfo downloadInfo);
|
||||
void onGalleryDownloadStop(DownloadInfo downloadInfo);
|
||||
void onGalleryDownloadFailed(DownloadInfo downloadInfo, String eMsg);
|
||||
void onGalleryDownloadCompleted(DownloadInfo downloadInfo);
|
||||
}
|
||||
*/
|
||||
}
|
||||
@@ -63,6 +63,13 @@ public class LargePreviewList extends PreviewList {
|
||||
mItemList.add(new Item(imageUrl, pageUrl));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPageUrl(int index) {
|
||||
if (index >= 0 && index < mItemList.size())
|
||||
return mItemList.get(index).mPageUrl;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addPreview(AutoWrapLayout viewGroup) {
|
||||
if (mTargetPage != mHolder.getCurPreviewPage())
|
||||
|
||||
@@ -92,6 +92,15 @@ public class NormalPreviewList extends PreviewList{
|
||||
return sum;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getPageUrl(int index) {
|
||||
for (Row row : rowArray) {
|
||||
if (index < row.startIndex + row.itemArray.size() && index >= row.startIndex)
|
||||
return row.itemArray.get(index - row.startIndex).url;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// TODO reuse the TextView in AutoWrapLayout
|
||||
@Override
|
||||
public void addPreview(AutoWrapLayout viewGroup) {
|
||||
|
||||
@@ -54,6 +54,13 @@ public abstract class PreviewList {
|
||||
mTargetPage = targetPage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return page url at target index, null for invalid index
|
||||
* @param index
|
||||
* @return
|
||||
*/
|
||||
public abstract String getPageUrl(int index);
|
||||
|
||||
protected class TextViewWithUrl extends TextView {
|
||||
public String url;
|
||||
|
||||
|
||||
@@ -48,8 +48,6 @@ public class DetailParser {
|
||||
|
||||
private static final CommentSort cs = new CommentSort();
|
||||
|
||||
private int mMode;
|
||||
|
||||
public String eMesg;
|
||||
public String thumb;
|
||||
public String title;
|
||||
@@ -72,11 +70,31 @@ public class DetailParser {
|
||||
public PreviewList previewList;
|
||||
public LinkedList<Comment> comments;
|
||||
|
||||
public void setMode(int mode) {
|
||||
mMode = mode;
|
||||
public void reset() {
|
||||
eMesg = null;
|
||||
thumb = null;
|
||||
title = null;
|
||||
title_jpn = null;
|
||||
category = 0;
|
||||
uploader = null;
|
||||
posted = null;
|
||||
pages = 0;
|
||||
size = null;
|
||||
resized = null;
|
||||
parent = null;
|
||||
visible = null;
|
||||
language = null;
|
||||
people = 0;
|
||||
rating = 0;
|
||||
firstPage = null;
|
||||
previewPerPage = 0;
|
||||
previewSum = 0;
|
||||
tags = null;
|
||||
previewList = null;
|
||||
comments = null;
|
||||
}
|
||||
|
||||
public int parser(String body) {
|
||||
public int parser(String body, int mode) {
|
||||
int re = 0;
|
||||
Pattern p;
|
||||
Matcher m;
|
||||
@@ -95,7 +113,7 @@ public class DetailParser {
|
||||
}
|
||||
|
||||
// Get detail
|
||||
if ((mMode & DETAIL) != 0) {
|
||||
if ((mode & DETAIL) != 0) {
|
||||
p = Pattern
|
||||
.compile("<div id=\"gd1\"><img src=\"([^\"]+)\"[^<>]+/></div>" // thumb
|
||||
+ "</div>"
|
||||
@@ -148,7 +166,7 @@ public class DetailParser {
|
||||
}
|
||||
}
|
||||
// Get tag
|
||||
if ((mMode & TAG) != 0) {
|
||||
if ((mode & TAG) != 0) {
|
||||
tags = new LinkedHashMap<String, LinkedList<SimpleEntry<String, Integer>>>();
|
||||
p = Pattern
|
||||
.compile("<tr><td[^<>]*>([^<>]+):</td><td>(?:<div[^<>]*><a[^<>]*>[^<>]*</a>[^<>]*<span[^<>]*>\\d+</span>[^<>]*</div>)+</td></tr>");
|
||||
@@ -164,7 +182,7 @@ public class DetailParser {
|
||||
}
|
||||
|
||||
// Get preview info
|
||||
if ((mMode & PREVIEW_INFO) != 0) {
|
||||
if ((mode & PREVIEW_INFO) != 0) {
|
||||
p = Pattern.compile("<p class=\"ip\">Showing ([\\d|,]+) - ([\\d|,]+) of ([\\d|,]+) images</p>");
|
||||
m = p.matcher(body);
|
||||
if (m.find()) {
|
||||
@@ -178,7 +196,7 @@ public class DetailParser {
|
||||
}
|
||||
}
|
||||
// Get preview
|
||||
if ((mMode & PREVIEW) != 0) {
|
||||
if ((mode & PREVIEW) != 0) {
|
||||
boolean isLargePreview = false;
|
||||
if (body.contains("<div class=\"gdtl\""))
|
||||
isLargePreview = true;
|
||||
@@ -207,7 +225,7 @@ public class DetailParser {
|
||||
}
|
||||
}
|
||||
// Get comment
|
||||
if ((mMode & COMMENT) != 0) {
|
||||
if ((mode & COMMENT) != 0) {
|
||||
p = Pattern
|
||||
.compile("<div class=\"c3\">Posted on ([^<>]+) by <a[^<>]+>([^<>]+)</a>.*?<div class=\"c6\">(.*?)</div>");
|
||||
m = p.matcher(body);
|
||||
|
||||
@@ -403,11 +403,9 @@ public class EhClient {
|
||||
public void onSuccess(Object obj) {
|
||||
String body = (String)obj;
|
||||
DetailParser parser = new DetailParser();
|
||||
int mode = DetailParser.DETAIL | DetailParser.TAG
|
||||
int result = parser.parser(body, DetailParser.DETAIL | DetailParser.TAG
|
||||
| DetailParser.PREVIEW_INFO | DetailParser.PREVIEW
|
||||
| DetailParser.COMMENT;
|
||||
parser.setMode(mode);
|
||||
int result = parser.parser(body);
|
||||
| DetailParser.COMMENT);
|
||||
if (result == DetailParser.OFFENSIVE) {
|
||||
md.firstPage = "offensive";
|
||||
listener.onSuccess(md);
|
||||
@@ -471,8 +469,8 @@ public class EhClient {
|
||||
public void onSuccess(Object obj) {
|
||||
String body = (String)obj;
|
||||
DetailParser parser = new DetailParser();
|
||||
parser.setMode(DetailParser.PREVIEW);
|
||||
if (parser.parser(body) == DetailParser.PREVIEW) {
|
||||
if (parser.parser(body, DetailParser.PREVIEW) ==
|
||||
DetailParser.PREVIEW) {
|
||||
listener.onSuccess(checkFlag, parser.previewList);
|
||||
} else {
|
||||
listener.onFailure(checkFlag, "Parser error");
|
||||
@@ -914,8 +912,8 @@ public class EhClient {
|
||||
public void onSuccess(Object obj) {
|
||||
String body = (String)obj;
|
||||
DetailParser parser = new DetailParser();
|
||||
parser.setMode(DetailParser.COMMENT);
|
||||
if (parser.parser(body) == DetailParser.COMMENT) {
|
||||
if (parser.parser(body, DetailParser.COMMENT) ==
|
||||
DetailParser.COMMENT) {
|
||||
listener.onSuccess(parser.comments);
|
||||
} else {
|
||||
listener.onFailure("parser error"); // TODO
|
||||
|
||||
@@ -111,14 +111,18 @@ public class EhInfo {
|
||||
updateUconfig();
|
||||
};
|
||||
|
||||
private void updateUconfig() {
|
||||
mUconfig = "cats_" + mDefaultCat
|
||||
+ "-ts_" + mPreviewMode
|
||||
private String getUconfigString(String previewMode) {
|
||||
return "cats_" + mDefaultCat
|
||||
+ "-ts_" + (previewMode == null ? mPreviewMode : previewMode)
|
||||
+ "-xns_" + mExculdeTagGroup
|
||||
+ "-xl_" + mExculdeLanguage
|
||||
+ "-tl_m-uh_y-tr_2-prn_n-dm_l-ar_0-rc_0-rx_0-ry_0-sa_y-oi_n-qb_n-tf_n-hp_-hk_-ms_n-mt_n";
|
||||
}
|
||||
|
||||
private void updateUconfig() {
|
||||
mUconfig = getUconfigString(null);
|
||||
}
|
||||
|
||||
public final static EhInfo getInstance(final Context context) {
|
||||
if (sInstance == null)
|
||||
sInstance = new EhInfo(context.getApplicationContext());
|
||||
@@ -161,12 +165,13 @@ public class EhInfo {
|
||||
}
|
||||
|
||||
public void setCookie(HttpURLConnection conn) {
|
||||
setCookie(conn, null);
|
||||
}
|
||||
|
||||
public void setCookie(HttpURLConnection conn, String previewMode) {
|
||||
String cookie = "ipb_member_id=" + mInfoPref.getString(KEY_MEMBER_ID, DEFAULT_MEMBER_ID) +
|
||||
"; ipb_pass_hash=" + mInfoPref.getString(KEY_PASS_HASH, DEFAULT_PASS_HASH) +
|
||||
"; uconfig="+ mUconfig;
|
||||
|
||||
android.util.Log.d(TAG, cookie);
|
||||
|
||||
"; uconfig=" + (previewMode == null ? mUconfig : getUconfigString(previewMode));
|
||||
conn.setRequestProperty("Cookie", cookie);
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2014 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.ehclient;
|
||||
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class ImagePageParser {
|
||||
|
||||
public String imageUrl;
|
||||
public String fullImageUrl;
|
||||
public int gid;
|
||||
public String token;
|
||||
|
||||
public void reset() {
|
||||
imageUrl = null;
|
||||
fullImageUrl = null;
|
||||
gid = 0;
|
||||
token = null;
|
||||
}
|
||||
|
||||
public boolean parser(String body) {
|
||||
Pattern p = Pattern.compile("<div id=\"i3\">.+?<img id=\"img\" src=\"(.+?)\""
|
||||
+ ".+?"
|
||||
+ "<div id=\"i5\"><div class=\"sb\"><a href=\"(?:http|https)://.+?/g/(\\d+)/(\\w+)"
|
||||
+ "(?:.+?<div id=\"i7\" class=\"if\">.+?<a href=\"(.+?)\">)?");
|
||||
Matcher m = p.matcher(body);
|
||||
if (m.matches()) {
|
||||
imageUrl = m.group(1);
|
||||
gid = Integer.parseInt(m.group(2));
|
||||
token = m.group(3);
|
||||
fullImageUrl = m.group(4);
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -20,7 +20,6 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.DataOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
@@ -30,6 +29,7 @@ import java.net.SocketTimeoutException;
|
||||
import java.net.URL;
|
||||
import java.net.URLEncoder;
|
||||
import java.net.UnknownHostException;
|
||||
import java.util.Random;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
|
||||
import org.apache.http.conn.ConnectTimeoutException;
|
||||
@@ -61,10 +61,25 @@ public class HttpHelper {
|
||||
private static final String TAG = "HttpHelper";
|
||||
public static final String SAD_PANDA_ERROR = "Sad Panda";
|
||||
public static final String HAPPY_PANDA_BODY = "Happy Panda";
|
||||
public static final String DOWNLOAD_STOP = "Stop";
|
||||
public static final String DOWNLOAD_OK = "Download";
|
||||
private static String DEFAULT_CHARSET = "utf-8";
|
||||
private static String CHARSET_KEY = "charset=";
|
||||
|
||||
public static final String DOWNLOAD_OK_STR = "OK";
|
||||
|
||||
public static final int DOWNLOAD_OK_CODE = 0x0;
|
||||
public static final int DOWNLOAD_FAIL_CODE = 0x1;
|
||||
public static final int DOWNLOAD_STOP_CODE = 0x2;
|
||||
|
||||
private static final String DEFAULT_CHARSET = "utf-8";
|
||||
private static final String CHARSET_KEY = "charset=";
|
||||
private static int sProxyIndex;
|
||||
private static Object sProxyIndexLock;
|
||||
|
||||
static {
|
||||
// from 1 to 8
|
||||
Random rdm = new Random(System.currentTimeMillis());
|
||||
sProxyIndex = rdm.nextInt(7) + 1;
|
||||
|
||||
sProxyIndexLock = new Object();
|
||||
}
|
||||
|
||||
class Package {
|
||||
Object obj;
|
||||
@@ -80,6 +95,7 @@ public class HttpHelper {
|
||||
private Context mContext;
|
||||
private Exception mException;
|
||||
private OnRespondListener mListener;
|
||||
private String mPreviewMode;
|
||||
|
||||
public static final void createHandler() {
|
||||
if (mHandler != null)
|
||||
@@ -107,6 +123,12 @@ public class HttpHelper {
|
||||
void onFailure(String eMsg);
|
||||
}
|
||||
|
||||
public void reset() {
|
||||
mListener = null;
|
||||
mException = null;
|
||||
mPreviewMode = null;
|
||||
}
|
||||
|
||||
public void setOnRespondListener(OnRespondListener l) {
|
||||
mListener = l;
|
||||
}
|
||||
@@ -167,7 +189,11 @@ public class HttpHelper {
|
||||
return false;
|
||||
}
|
||||
|
||||
private Object requst(RequestHelper rh, String urlStr) {
|
||||
public void setPreviewMode(String previewMode) {
|
||||
mPreviewMode = previewMode;
|
||||
}
|
||||
|
||||
private Object requst(RequestHelper rh) {
|
||||
mException = null;
|
||||
int redirectionCount = 0;
|
||||
URL url = null;
|
||||
@@ -177,8 +203,8 @@ public class HttpHelper {
|
||||
if (mListener != null)
|
||||
msg = new Message();
|
||||
try {
|
||||
Log.d(TAG, "Requst " + urlStr);
|
||||
url = new URL(urlStr);
|
||||
url = rh.getUrl();
|
||||
Log.d(TAG, "Requst " + url.toString());
|
||||
boolean isCookiable = isUrlCookiable(url);
|
||||
while (redirectionCount++ < Constant.MAX_REDIRECTS) {
|
||||
conn = (HttpURLConnection) url.openConnection();
|
||||
@@ -188,7 +214,7 @@ public class HttpHelper {
|
||||
conn.setReadTimeout(Constant.DEFAULT_TIMEOUT);
|
||||
// Set cookie if necessary
|
||||
if (isCookiable)
|
||||
EhInfo.getInstance(mContext).setCookie(conn);
|
||||
EhInfo.getInstance(mContext).setCookie(conn, mPreviewMode);
|
||||
// Do custom staff
|
||||
rh.onBeforeConnect(conn);
|
||||
|
||||
@@ -239,6 +265,8 @@ public class HttpHelper {
|
||||
msg.what = Constants.FALSE;
|
||||
mHandler.sendMessage(msg);
|
||||
}
|
||||
// Send exception to helper
|
||||
rh.onGetException(e);
|
||||
return null;
|
||||
} finally {
|
||||
if (conn != null)
|
||||
@@ -247,12 +275,21 @@ public class HttpHelper {
|
||||
}
|
||||
|
||||
private interface RequestHelper {
|
||||
|
||||
/**
|
||||
* Get the URL to connect
|
||||
* @return
|
||||
*/
|
||||
public URL getUrl() throws MalformedURLException;
|
||||
|
||||
/**
|
||||
* Add header or do something else for HttpURLConnection before connect
|
||||
* @param conn
|
||||
* @throws Exception
|
||||
*/
|
||||
|
||||
public void onBeforeConnect(HttpURLConnection conn) throws Exception;
|
||||
|
||||
/**
|
||||
* Get what do you need from HttpURLConnection after connect
|
||||
* Return null means get error
|
||||
@@ -261,12 +298,23 @@ public class HttpHelper {
|
||||
* @throws Exception
|
||||
*/
|
||||
public Object onAfterConnect(HttpURLConnection conn) throws Exception;
|
||||
|
||||
/**
|
||||
* Handle exception
|
||||
* @param e
|
||||
*/
|
||||
public void onGetException(Exception e);
|
||||
}
|
||||
|
||||
/**
|
||||
* RequstHelper for check sad panda, use HEAD method
|
||||
*/
|
||||
private class CheckSpHelper implements RequestHelper {
|
||||
@Override
|
||||
public URL getUrl() throws MalformedURLException {
|
||||
return new URL(EhClient.EX_HEADER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBeforeConnect(HttpURLConnection conn)
|
||||
throws Exception {
|
||||
@@ -278,9 +326,23 @@ public class HttpHelper {
|
||||
throws Exception {
|
||||
return HAPPY_PANDA_BODY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGetException(Exception e) {}
|
||||
}
|
||||
|
||||
private abstract class GetStringHelper implements RequestHelper {
|
||||
private String mUrl;
|
||||
|
||||
public GetStringHelper(String url) {
|
||||
mUrl = url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getUrl() throws MalformedURLException {
|
||||
return new URL(mUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBeforeConnect(HttpURLConnection conn)
|
||||
throws Exception {
|
||||
@@ -333,12 +395,20 @@ public class HttpHelper {
|
||||
throws Exception {
|
||||
return getBody(conn);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGetException(Exception e) {}
|
||||
}
|
||||
|
||||
/**
|
||||
* RequstHelper for GET method
|
||||
*/
|
||||
private class GetHelper extends GetStringHelper {
|
||||
|
||||
public GetHelper(String url) {
|
||||
super(url);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBeforeConnect(HttpURLConnection conn)
|
||||
throws Exception {
|
||||
@@ -353,7 +423,8 @@ public class HttpHelper {
|
||||
private class PostFormHelper extends GetStringHelper {
|
||||
private String[][] mArgs;
|
||||
|
||||
public PostFormHelper(String[][] args) {
|
||||
public PostFormHelper(String url, String[][] args) {
|
||||
super(url);
|
||||
mArgs = args;
|
||||
}
|
||||
|
||||
@@ -392,7 +463,8 @@ public class HttpHelper {
|
||||
private class PostJsonHelper extends GetStringHelper {
|
||||
private JSONObject mJo;
|
||||
|
||||
public PostJsonHelper(JSONObject jo) {
|
||||
public PostJsonHelper(String url, JSONObject jo) {
|
||||
super(url);
|
||||
mJo = jo;
|
||||
}
|
||||
|
||||
@@ -413,6 +485,17 @@ public class HttpHelper {
|
||||
}
|
||||
|
||||
private class GetImageHelper implements RequestHelper {
|
||||
private String mUrl;
|
||||
|
||||
public GetImageHelper(String url) {
|
||||
mUrl = url;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getUrl() throws MalformedURLException {
|
||||
return new URL(mUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBeforeConnect(HttpURLConnection conn)
|
||||
throws Exception {
|
||||
@@ -427,6 +510,9 @@ public class HttpHelper {
|
||||
throw new GetBodyException();
|
||||
return bmp;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGetException(Exception e) {}
|
||||
}
|
||||
|
||||
public interface OnDownloadListener {
|
||||
@@ -437,14 +523,10 @@ public class HttpHelper {
|
||||
*/
|
||||
public void onDownloadStartDownload(int totalSize);
|
||||
public void onDownloadStatusUpdate(int downloadSize, int totalSize);
|
||||
/**
|
||||
* FAILED or COMPLETED or STOPED
|
||||
* @param status
|
||||
*/
|
||||
public void onDownloadOver(int status, String eMsg);
|
||||
}
|
||||
|
||||
public class DownloadControlor {
|
||||
public static class DownloadControlor {
|
||||
private boolean mStop = false;
|
||||
|
||||
public void stop() {
|
||||
@@ -461,24 +543,57 @@ public class HttpHelper {
|
||||
}
|
||||
|
||||
private class DownloadHelper implements RequestHelper {
|
||||
private String mUrl;
|
||||
private File mDir;
|
||||
private String mFileName;
|
||||
private File mFile;
|
||||
private boolean mIsProxy;
|
||||
private DownloadControlor mControlor;
|
||||
private OnDownloadListener mListener;
|
||||
private int mContentLength;
|
||||
private int mReceivedSize;
|
||||
|
||||
public DownloadHelper(File dir, String fileName, DownloadControlor controlor, OnDownloadListener listener) {
|
||||
public DownloadHelper(String url, File dir, String fileName, boolean isProxy,
|
||||
DownloadControlor controlor, OnDownloadListener listener) {
|
||||
mUrl = url;
|
||||
mDir = dir;
|
||||
mFileName = fileName;
|
||||
mIsProxy = isProxy;
|
||||
mControlor = controlor;
|
||||
mListener = listener;
|
||||
}
|
||||
|
||||
public String getProxyUrl() {
|
||||
String proxyUrl = null;
|
||||
synchronized(sProxyIndexLock) {
|
||||
proxyUrl = "http://proxy000" + sProxyIndex + ".herokuapp.com/proxy";
|
||||
if (++sProxyIndex > 8)
|
||||
sProxyIndex = 1;
|
||||
}
|
||||
return proxyUrl;
|
||||
}
|
||||
|
||||
@Override
|
||||
public URL getUrl() throws MalformedURLException {
|
||||
return new URL(mIsProxy? getProxyUrl() : mUrl);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBeforeConnect(HttpURLConnection conn) throws Exception {
|
||||
conn.setRequestMethod("GET");
|
||||
conn.addRequestProperty("Range", "bytes=0-");
|
||||
if (mIsProxy) {
|
||||
conn.setDoOutput(true);
|
||||
conn.setDoInput(true);
|
||||
conn.setUseCaches(false);
|
||||
conn.setRequestMethod("POST");
|
||||
|
||||
DataOutputStream out = new DataOutputStream(conn.getOutputStream());
|
||||
out.writeBytes("{\"url\":\"" + mUrl + "\"}");
|
||||
out.flush();
|
||||
out.close();
|
||||
} else {
|
||||
conn.setRequestMethod("GET");
|
||||
conn.setRequestProperty("Range", "bytes=0-");
|
||||
}
|
||||
mListener.onDownloadStartConnect();
|
||||
}
|
||||
|
||||
@@ -516,15 +631,24 @@ public class HttpHelper {
|
||||
|
||||
// Make sure parent exist
|
||||
mDir.mkdirs();
|
||||
File file = new File(mDir, mFileName);
|
||||
try {
|
||||
transferData(conn.getInputStream(), new FileOutputStream(file));
|
||||
return DOWNLOAD_OK;
|
||||
} catch (StopRequestException e) {
|
||||
return DOWNLOAD_STOP;
|
||||
} catch (Exception e) {
|
||||
throw e;
|
||||
}
|
||||
mFile = new File(mDir, mFileName);
|
||||
// Transfer
|
||||
transferData(conn.getInputStream(), new FileOutputStream(mFile));
|
||||
// Callback
|
||||
mListener.onDownloadOver(DOWNLOAD_OK_CODE, null);
|
||||
return DOWNLOAD_OK_STR;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onGetException(Exception e) {
|
||||
// Delete unfinished file
|
||||
if (mFile != null)
|
||||
mFile.delete();
|
||||
// Callback
|
||||
if (e instanceof StopRequestException)
|
||||
mListener.onDownloadOver(DOWNLOAD_STOP_CODE, getEMsg());
|
||||
else
|
||||
mListener.onDownloadOver(DOWNLOAD_STOP_CODE, getEMsg());
|
||||
}
|
||||
|
||||
private void transferData(InputStream in, OutputStream out)
|
||||
@@ -558,7 +682,7 @@ public class HttpHelper {
|
||||
* @return
|
||||
*/
|
||||
public String checkSadPanda() {
|
||||
return (String)requst(new CheckSpHelper(), EhClient.EX_HEADER);
|
||||
return (String)requst(new CheckSpHelper());
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -567,7 +691,7 @@ public class HttpHelper {
|
||||
* @return
|
||||
*/
|
||||
public String get(String url) {
|
||||
return (String)requst(new GetHelper(), url);
|
||||
return (String)requst(new GetHelper(url));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -577,7 +701,7 @@ public class HttpHelper {
|
||||
* @return
|
||||
*/
|
||||
public String postForm(String url, String[][] args) {
|
||||
return (String)requst(new PostFormHelper(args), url);
|
||||
return (String)requst(new PostFormHelper(url, args));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -587,7 +711,7 @@ public class HttpHelper {
|
||||
* @return
|
||||
*/
|
||||
public String postJson(String url, JSONObject json) {
|
||||
return (String)requst(new PostJsonHelper(json), url);
|
||||
return (String)requst(new PostJsonHelper(url, json));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -596,13 +720,13 @@ public class HttpHelper {
|
||||
* @return
|
||||
*/
|
||||
public Bitmap getImage(String url) {
|
||||
return (Bitmap)requst(new GetImageHelper(), url);
|
||||
return (Bitmap)requst(new GetImageHelper(url));
|
||||
}
|
||||
|
||||
public String download(String url, File dir, String file,
|
||||
public String download(String url, File dir, String file, boolean isProxy,
|
||||
DownloadControlor controlor, OnDownloadListener listener) {
|
||||
return (String)requst(new DownloadHelper(dir, file,
|
||||
controlor, listener), url);
|
||||
return (String)requst(new DownloadHelper(url, dir, file, isProxy,
|
||||
controlor, listener));
|
||||
}
|
||||
|
||||
/** Exceptions **/
|
||||
|
||||
@@ -811,8 +811,8 @@ public class DetailSectionFragment extends Fragment
|
||||
new SuperToast(mActivity).setMessage(R.string.vote_succeeded).show();
|
||||
|
||||
DetailParser parser = new DetailParser();
|
||||
parser.setMode(DetailParser.TAG);
|
||||
if (parser.parser(tagPane) == DetailParser.TAG) {
|
||||
if (parser.parser(tagPane, DetailParser.TAG) ==
|
||||
DetailParser.TAG) {
|
||||
mGalleryDetail.tags = parser.tags;
|
||||
addTags();
|
||||
} else {
|
||||
|
||||
@@ -328,7 +328,7 @@ public class Config {
|
||||
private static final int DEFAULT_DEFAULT_CAT = 0;
|
||||
|
||||
// m for normal, l for large
|
||||
private static final String KEY_PREVIEW_MODE = "preview_mode";
|
||||
public static final String KEY_PREVIEW_MODE = "preview_mode";
|
||||
public static final String PREVIEW_MODE_NORMAL = "m";
|
||||
public static final String PREVIEW_MODE_LARGE = "l";
|
||||
private static final String DEFAULT_PREVIEW_MODE = PREVIEW_MODE_LARGE;
|
||||
|
||||
Reference in new issue
Block a user