mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-03 23:58:55 +01:00 
			
		
		
		
	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:
		@@ -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,33 +187,26 @@ 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();
 | 
			
		||||
                }
 | 
			
		||||
                sink.close();
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        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;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user