完善阅读下载策略

This commit is contained in:
seven332 committed 2014-08-19 16:24:36 +08:00
1 parent 374ed3a515
commit a2bbe855e8
38 files changed
+1297 -2142

No files matched your search

@@ -17,7 +17,6 @@
package com.hippo.ehviewer.ehclient;
import java.io.File;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
@@ -45,16 +44,10 @@ import com.hippo.ehviewer.data.GalleryPopular;
import com.hippo.ehviewer.data.ListUrls;
import com.hippo.ehviewer.data.LofiGalleryDetail;
import com.hippo.ehviewer.data.PreviewList;
import com.hippo.ehviewer.gallery.data.ImageSet;
import com.hippo.ehviewer.network.Downloader;
import com.hippo.ehviewer.network.HttpHelper;
import com.hippo.ehviewer.service.DownloadService;
import com.hippo.ehviewer.ui.DownloadInfo;
import com.hippo.ehviewer.util.Config;
import com.hippo.ehviewer.util.Download;
import com.hippo.ehviewer.util.Future;
import com.hippo.ehviewer.util.FutureListener;
import com.hippo.ehviewer.util.Log;
import com.hippo.ehviewer.util.ThreadPool;
import com.hippo.ehviewer.util.ThreadPool.Job;
import com.hippo.ehviewer.util.ThreadPool.JobContext;
@@ -982,341 +975,6 @@ public class EhClient {
});
}
public interface OnDownloadMangaListener {
public void onDownloadMangaStart(String id);
public void onDownloadMangaStart(String id, int pageSum, int startIndex);
public void onDownloadMangaStop(String id);
public void onDownloadMangaOver(String id, boolean ok);
public void onDownloadPage(String id, int pageSum, int index);
public void onDownloadPageProgress(String id, int pageSum,
int index, float totalSize, float downloadSize);
public void onDownloadMangaAllStart();
public void onDownloadMangaAllOver();
}
// TODO 下载前检查文件是否已存在
/****** DownloadMangaManager ******/
public class DownloadMangaManager {
private DownloadInfo curDownloadInfo = null;
private Downloader.Controlor curControlor = null;
private final ArrayList<DownloadInfo> mDownloadQueue = new ArrayList<DownloadInfo>();
private final Object taskLock = new Object();
private OnDownloadMangaListener listener;
private DownloadService mService;
private final boolean mStop = false;
public void init() {
}
public void setOnDownloadMangaListener(OnDownloadMangaListener listener) {
this.listener = listener;
}
public void setDownloadService(DownloadService service) {
this.mService = service;
}
/**
* Add a download task to task queue
*
* @param detailUrlStr
* @param foldName
* @return
*/
public void add(DownloadInfo di) {
synchronized (taskLock) {
mDownloadQueue.add(di);
if (curDownloadInfo == null && mDownloadQueue.size() != 0)
start();
}
}
public void cancel(String id) {
synchronized (taskLock) {
DownloadInfo di = Download.get(id);
if (di != null) {
di.status = DownloadInfo.STOP;
mDownloadQueue.remove(di);
if (!id.equals(getCurDownloadId())) {
if (curControlor != null)
curControlor.stop();
mService.notifyUpdate();
Download.notify(id);
}
}
}
}
public String getCurDownloadId() {
synchronized (taskLock) {
if (curDownloadInfo == null)
return null;
else
return curDownloadInfo.gid;
}
}
public boolean isWaiting(String str) {
synchronized (taskLock) {
for (DownloadInfo di : mDownloadQueue) {
if (di.gid.equals(str))
return true;
}
}
return false;
}
private void start(){
if(curDownloadInfo != null){
return;
}
new Thread(new Runnable(){
@Override
public void run() {
listener.onDownloadMangaAllStart();
Parser parser = new Parser();
Downloader imageDownloader = new Downloader(mAppContext);
imageDownloader.setOnDownloadListener(new Downloader.OnDownloadListener() {
@Override
public void onDownloadStartConnect() {
}
@Override
public void onDownloadStartDownload(int totalSize) {
if (curDownloadInfo != null) {
curDownloadInfo.downloadSize = 0;
curDownloadInfo.totalSize = totalSize/1024.0f;
mService.notifyUpdate(curDownloadInfo.gid, curDownloadInfo.lastStartIndex, ImageSet.STATE_LOADING);
}
}
@Override
public void onDownloadStatusUpdate(int downloadSize,
int totalSize) {
curDownloadInfo.downloadSize = downloadSize/1024.0f;
curDownloadInfo.totalSize = totalSize/1024.0f;
mService.notifyUpdate();
}
@Override
public void onDownloadOver(int status, String eMsg) {
if (status == Downloader.COMPLETED)
mService.notifyUpdate(curDownloadInfo.gid, curDownloadInfo.lastStartIndex, ImageSet.STATE_LOADED);
else
mService.notifyUpdate(curDownloadInfo.gid, curDownloadInfo.lastStartIndex, ImageSet.STATE_FAIL);
}
});
while(mDownloadQueue.size() > 0){
synchronized (taskLock) {
curDownloadInfo = mDownloadQueue.get(0);
curDownloadInfo.status = DownloadInfo.DOWNLOADING;
mDownloadQueue.remove(0);
}
Download.notify(String.valueOf(curDownloadInfo.gid));
if (curDownloadInfo.type == DownloadInfo.DETAIL_URL) {
listener.onDownloadMangaStart(curDownloadInfo.gid);
mService.notifyUpdate();
if (parser.getFirstPagePageSumForDetail(curDownloadInfo.detailUrlStr)) { // Get page info
curDownloadInfo.type = DownloadInfo.PAGE_URL;
curDownloadInfo.lastStartIndex = 0;
curDownloadInfo.pageSum = parser.getPageSum();
curDownloadInfo.pageUrlStr = parser.getFirstPage();
Download.notify(curDownloadInfo.gid);
} else { // If get info error
listener.onDownloadMangaOver(curDownloadInfo.gid, false);
curDownloadInfo.status = DownloadInfo.FAILED;
mService.notifyUpdate();
Download.notify(String.valueOf(curDownloadInfo.gid));
continue;
}
}
//Create folder
File folder = new File(Config.getDownloadPath() + File.separatorChar + Utils.standardizeFilename(curDownloadInfo.title)); // TODO For title contain invailed char
if (!folder.mkdirs() && !folder.isDirectory()) {
listener.onDownloadMangaOver(curDownloadInfo.gid, false);
curDownloadInfo.status = DownloadInfo.FAILED;
mService.notifyUpdate();
Download.notify(String.valueOf(curDownloadInfo.gid));
continue;
}
String nextPage = curDownloadInfo.pageUrlStr;
curDownloadInfo.pageUrlStr = null;
String imageUrlStr = null;
boolean mComplete = true;
boolean mStop = false;
// Get page
while (!nextPage.equals(curDownloadInfo.pageUrlStr)) {
curDownloadInfo.pageUrlStr = nextPage;
Download.notify(String.valueOf(curDownloadInfo.gid));
listener.onDownloadPage(curDownloadInfo.gid, curDownloadInfo.pageSum, curDownloadInfo.lastStartIndex);
mService.notifyUpdate();
if (parser.getPageInfoSumForPage(curDownloadInfo.pageUrlStr)) {
nextPage = parser.getNextPage();
imageUrlStr = parser.getImageUrlStr();
// Check stop
if (curDownloadInfo.status == DownloadInfo.STOP) {
listener.onDownloadMangaStop(curDownloadInfo.gid);
mService.notifyUpdate();
Download.notify(String.valueOf(curDownloadInfo.gid));
mComplete = false;
mStop = true;
break;
}
try {
// TODO
Log.d(TAG, folder.getPath());
curControlor = imageDownloader.resetData(folder.getPath(),
String.format("%05d", curDownloadInfo.lastStartIndex + 1) + "." + Utils.getExtension(imageUrlStr),
imageUrlStr);
imageDownloader.run();
curDownloadInfo.downloadSize = 0;
curDownloadInfo.totalSize = 0;
int downloadStatus = imageDownloader.getStatus();
if (downloadStatus == Downloader.STOPED) { // If stop by user
listener.onDownloadMangaStop(curDownloadInfo.gid);
mService.notifyUpdate();
Download.notify(String.valueOf(curDownloadInfo.gid));
mComplete = false;
mStop = true;
break;
} else if (downloadStatus != Downloader.COMPLETED) { // If get image error
Log.e(TAG, "Download image error, downloadStatus is " + downloadStatus);
mComplete = false;
break;
}
} catch (MalformedURLException e) {
e.printStackTrace();
mComplete = false;
break;
}
} else {
mComplete = false;
break;
}
curDownloadInfo.lastStartIndex++;
}
if (mComplete) {
listener.onDownloadMangaOver(curDownloadInfo.gid, true);
curDownloadInfo.status = DownloadInfo.COMPLETED;
mService.notifyUpdate();
Download.notify(String.valueOf(curDownloadInfo.gid));
} else if (!mStop) {
listener.onDownloadMangaOver(curDownloadInfo.gid, false);
curDownloadInfo.status = DownloadInfo.FAILED;
mService.notifyUpdate();
Download.notify(String.valueOf(curDownloadInfo.gid));
}
}
synchronized (taskLock) {
curDownloadInfo = null;
listener.onDownloadMangaAllOver();
}
}
}).start();
}
public boolean isEmpty() {
synchronized (taskLock) {
return curDownloadInfo == null;
}
}
}
private class Parser {
private int errorMegId;
private int pageSum;
private String firstPage;
private String prePage;
private String nextPage;
private String imageUrlStr;
public int getPageSum() {
return pageSum;
}
public String getFirstPage() {
return firstPage;
}
public String getPrePage() {
return prePage;
}
public String getNextPage() {
return nextPage;
}
public String getImageUrlStr() {
return imageUrlStr;
}
public boolean getFirstPagePageSumForDetail(String detailUrlStr) {
HttpHelper hp = new HttpHelper(mAppContext);
String pageContent = hp.get(detailUrlStr);
if (pageContent == null)
return false;
Pattern p = Pattern.compile("<p class=\"ip\">Showing [\\d|,]+ - [\\d|,]+ of ([\\d|,]+) images</p>.+<div id=\"gdt\"><div[^<>]*>(?:<div[^<>]*>)?<a[^<>]*href=\"([^<>\"]+)\"[^<>]*>");
Matcher m = p.matcher(pageContent);
if (m.find()) {
pageSum = Integer.parseInt(m.group(1).replace(",", ""));
firstPage = m.group(2);
return true;
}
return false;
}
/**
* Get page info, previous page, next page, image url
*
* @param pageUrlStr
* @return True if get
*/
public boolean getPageInfoSumForPage(String pageUrlStr) {
HttpHelper hp = new HttpHelper(mAppContext);
String pageContent = hp.get(pageUrlStr);
if (pageContent == null)
return false;
Pattern p = Pattern.compile("<a[^<>]*id=\"prev\"[^<>]*href=\"([^<>\"]+)\"><img[^<>]*/></a>.+<a[^<>]id=\"next\"[^<>]*href=\"([^<>\"]+)\"><img[^<>]*/></a>.+<img[^<>]*src=\"([^<>\"]+?)\"[^<>]*style=\"[^<>\"]*\"[^<>]*/>");
Matcher m = p.matcher(pageContent);
if (m.find()) {
prePage = m.group(1);
nextPage = m.group(2);
imageUrlStr = Utils.unescapeXml(m.group(3));
return true;
}
return false;
}
}
// Post comment
public interface OnCommentListener {
void onSuccess(List<Comment> comments);