Avoid filename conflicts (not sure if it will be totally fixed). Check if a chapter is properly downloaded after download finishes.
This commit is contained in:
parent
260fa59799
commit
c52c567eae
@ -179,7 +179,7 @@ public class CacheManager {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean putImageToDiskCache(final String imageUrl, final Response response) {
|
||||
public void putImageToDiskCache(final String imageUrl, final Response response) throws IOException {
|
||||
DiskLruCache.Editor editor = null;
|
||||
BufferedSink sink = null;
|
||||
|
||||
@ -187,34 +187,27 @@ public class CacheManager {
|
||||
String key = DiskUtils.hashKeyForDisk(imageUrl);
|
||||
editor = mDiskCache.edit(key);
|
||||
if (editor == null) {
|
||||
return false;
|
||||
throw new IOException("Unable to edit key");
|
||||
}
|
||||
|
||||
OutputStream outputStream = new BufferedOutputStream(editor.newOutputStream(0));
|
||||
sink = Okio.buffer(Okio.sink(outputStream));
|
||||
sink.writeAll(response.body().source());
|
||||
sink.flush();
|
||||
|
||||
mDiskCache.flush();
|
||||
editor.commit();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
return false;
|
||||
} catch (Exception e) {
|
||||
throw new IOException("Unable to save image");
|
||||
} finally {
|
||||
if (editor != null) {
|
||||
editor.abortUnlessCommitted();
|
||||
}
|
||||
if (sink != null) {
|
||||
try {
|
||||
sink.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
@ -12,8 +12,6 @@ import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.util.List;
|
||||
|
||||
import eu.kanade.mangafeed.data.database.models.Chapter;
|
||||
@ -27,6 +25,7 @@ import eu.kanade.mangafeed.data.source.model.Page;
|
||||
import eu.kanade.mangafeed.event.DownloadChaptersEvent;
|
||||
import eu.kanade.mangafeed.util.DiskUtils;
|
||||
import eu.kanade.mangafeed.util.DynamicConcurrentMergeOperator;
|
||||
import eu.kanade.mangafeed.util.UrlUtil;
|
||||
import rx.Observable;
|
||||
import rx.Subscription;
|
||||
import rx.android.schedulers.AndroidSchedulers;
|
||||
@ -81,6 +80,7 @@ public class DownloadManager {
|
||||
.lift(new DynamicConcurrentMergeOperator<>(this::downloadChapter, threadsNumber))
|
||||
.onBackpressureBuffer()
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.map(download -> areAllDownloadsFinished())
|
||||
.subscribe(finished -> {
|
||||
if (finished) {
|
||||
DownloadService.stop(context);
|
||||
@ -164,7 +164,7 @@ public class DownloadManager {
|
||||
}
|
||||
|
||||
// Download the entire chapter
|
||||
private Observable<Boolean> downloadChapter(Download download) {
|
||||
private Observable<Download> downloadChapter(Download download) {
|
||||
try {
|
||||
DiskUtils.createDirectory(download.directory);
|
||||
} catch (IOException e) {
|
||||
@ -182,7 +182,6 @@ public class DownloadManager {
|
||||
|
||||
return pageListObservable
|
||||
.subscribeOn(Schedulers.io())
|
||||
.doOnError(error -> download.setStatus(Download.ERROR))
|
||||
.doOnNext(pages -> download.setStatus(Download.DOWNLOADING))
|
||||
.doOnNext(pages -> download.downloadedImages = 0)
|
||||
// Get all the URLs to the source images, fetch pages if necessary
|
||||
@ -194,8 +193,10 @@ public class DownloadManager {
|
||||
.toList()
|
||||
.flatMap(pages -> Observable.just(download))
|
||||
// If the page list threw, it will resume here
|
||||
.onErrorResumeNext(error -> Observable.just(download))
|
||||
.map(d -> areAllDownloadsFinished());
|
||||
.onErrorResumeNext(error -> {
|
||||
download.setStatus(Download.ERROR);
|
||||
return Observable.just(download);
|
||||
});
|
||||
}
|
||||
|
||||
// Get the image from the filesystem if it exists or download from network
|
||||
@ -215,9 +216,9 @@ public class DownloadManager {
|
||||
return pageObservable
|
||||
// When the image is ready, set image path, progress (just in case) and status
|
||||
.doOnNext(p -> {
|
||||
p.setImagePath(imagePath.getAbsolutePath());
|
||||
p.setProgress(100);
|
||||
p.setStatus(Page.READY);
|
||||
page.setImagePath(imagePath.getAbsolutePath());
|
||||
page.setProgress(100);
|
||||
page.setStatus(Page.READY);
|
||||
download.downloadedImages++;
|
||||
})
|
||||
// If the download fails, mark this page as error
|
||||
@ -226,6 +227,7 @@ public class DownloadManager {
|
||||
.onErrorResumeNext(e -> Observable.just(page));
|
||||
}
|
||||
|
||||
// Save image on disk
|
||||
private Observable<Page> downloadImage(Page page, Source source, File directory, String filename) {
|
||||
page.setStatus(Page.DOWNLOAD_IMAGE);
|
||||
return source.getImageProgressResponse(page)
|
||||
@ -261,12 +263,7 @@ public class DownloadManager {
|
||||
|
||||
// Get the filename for an image given the page
|
||||
private String getImageFilename(Page page) {
|
||||
String url;
|
||||
try {
|
||||
url = new URL(page.getImageUrl()).getPath();
|
||||
} catch (MalformedURLException e) {
|
||||
url = page.getImageUrl();
|
||||
}
|
||||
String url = UrlUtil.getPath(page.getImageUrl());
|
||||
return url.substring(
|
||||
url.lastIndexOf("/") + 1,
|
||||
url.length());
|
||||
@ -288,7 +285,11 @@ public class DownloadManager {
|
||||
// If any page has an error, the download result will be error
|
||||
for (Page page : download.pages) {
|
||||
actualProgress += page.getProgress();
|
||||
if (page.getStatus() == Page.ERROR) status = Download.ERROR;
|
||||
if (page.getStatus() != Page.READY) status = Download.ERROR;
|
||||
}
|
||||
// Ensure that the chapter folder has all the images
|
||||
if (!isChapterDownloaded(download.directory, download.pages)) {
|
||||
status = Download.ERROR;
|
||||
}
|
||||
download.totalProgress = actualProgress;
|
||||
download.setStatus(status);
|
||||
|
@ -42,7 +42,7 @@ public final class NetworkHelper {
|
||||
} catch (Throwable e) {
|
||||
return Observable.error(e);
|
||||
}
|
||||
}).retry(3);
|
||||
}).retry(2);
|
||||
}
|
||||
|
||||
public Observable<String> mapResponseToString(final Response response) {
|
||||
@ -72,7 +72,7 @@ public final class NetworkHelper {
|
||||
} catch (Throwable e) {
|
||||
return Observable.error(e);
|
||||
}
|
||||
}).retry(3);
|
||||
}).retry(2);
|
||||
}
|
||||
|
||||
public Observable<Response> getProgressResponse(final String url, final Headers headers, final ProgressListener listener) {
|
||||
@ -96,7 +96,7 @@ public final class NetworkHelper {
|
||||
} catch (Throwable e) {
|
||||
return Observable.error(e);
|
||||
}
|
||||
}).retry(3);
|
||||
}).retry(2);
|
||||
}
|
||||
|
||||
public CookieStore getCookies() {
|
||||
|
@ -8,6 +8,7 @@ import com.squareup.okhttp.Response;
|
||||
|
||||
import org.jsoup.Jsoup;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
@ -153,8 +154,10 @@ public abstract class Source extends BaseSource {
|
||||
page.setStatus(Page.DOWNLOAD_IMAGE);
|
||||
return getImageProgressResponse(page)
|
||||
.flatMap(resp -> {
|
||||
if (!cacheManager.putImageToDiskCache(page.getImageUrl(), resp)) {
|
||||
throw new IllegalStateException("Unable to save image");
|
||||
try {
|
||||
cacheManager.putImageToDiskCache(page.getImageUrl(), resp);
|
||||
} catch (IOException e) {
|
||||
return Observable.error(e);
|
||||
}
|
||||
return Observable.just(page);
|
||||
});
|
||||
|
@ -8,7 +8,7 @@ public class Page implements ProgressListener {
|
||||
private int pageNumber;
|
||||
private String url;
|
||||
private String imageUrl;
|
||||
private String imagePath;
|
||||
private transient String imagePath;
|
||||
private transient volatile int status;
|
||||
private transient volatile int progress;
|
||||
|
||||
|
@ -130,13 +130,13 @@ public final class DiskUtils {
|
||||
try {
|
||||
bufferedSink = Okio.buffer(Okio.sink(writeFile));
|
||||
bufferedSink.writeAll(bufferedSource);
|
||||
bufferedSink.close();
|
||||
} catch (Exception e) {
|
||||
writeFile.delete();
|
||||
throw new IOException("Unable to save image");
|
||||
} finally {
|
||||
if (bufferedSink != null) {
|
||||
bufferedSink.close();
|
||||
}
|
||||
writeFile.delete();
|
||||
throw new IOException("Failed saving image");
|
||||
}
|
||||
|
||||
return writeFile;
|
||||
|
Loading…
Reference in New Issue
Block a user