mirror of
https://github.com/mihonapp/mihon.git
synced 2025-11-18 15:07:30 +01:00
Change the download event. Fix some bugs in download manager. Other minor changes.
This commit is contained in:
@@ -12,6 +12,7 @@ import java.io.FileOutputStream;
|
||||
import java.io.FileReader;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import eu.kanade.mangafeed.data.models.Chapter;
|
||||
@@ -19,7 +20,7 @@ import eu.kanade.mangafeed.data.models.Download;
|
||||
import eu.kanade.mangafeed.data.models.DownloadQueue;
|
||||
import eu.kanade.mangafeed.data.models.Manga;
|
||||
import eu.kanade.mangafeed.data.models.Page;
|
||||
import eu.kanade.mangafeed.events.DownloadChapterEvent;
|
||||
import eu.kanade.mangafeed.events.DownloadChaptersEvent;
|
||||
import eu.kanade.mangafeed.sources.base.Source;
|
||||
import eu.kanade.mangafeed.util.DiskUtils;
|
||||
import eu.kanade.mangafeed.util.DynamicConcurrentMergeOperator;
|
||||
@@ -28,10 +29,11 @@ import rx.Subscription;
|
||||
import rx.schedulers.Schedulers;
|
||||
import rx.subjects.BehaviorSubject;
|
||||
import rx.subjects.PublishSubject;
|
||||
import timber.log.Timber;
|
||||
|
||||
public class DownloadManager {
|
||||
|
||||
private PublishSubject<DownloadChapterEvent> downloadsSubject;
|
||||
private PublishSubject<DownloadChaptersEvent> downloadsSubject;
|
||||
private Subscription downloadSubscription;
|
||||
private Subscription threadNumberSubscription;
|
||||
|
||||
@@ -55,7 +57,7 @@ public class DownloadManager {
|
||||
initializeDownloadSubscription();
|
||||
}
|
||||
|
||||
public PublishSubject<DownloadChapterEvent> getDownloadsSubject() {
|
||||
public PublishSubject<DownloadChaptersEvent> getDownloadsSubject() {
|
||||
return downloadsSubject;
|
||||
}
|
||||
|
||||
@@ -76,62 +78,82 @@ public class DownloadManager {
|
||||
// Listen for download events, add them to queue and download
|
||||
downloadSubscription = downloadsSubject
|
||||
.subscribeOn(Schedulers.io())
|
||||
.filter(event -> !isChapterDownloaded(event))
|
||||
.flatMap(this::prepareDownload)
|
||||
.flatMap(this::prepareDownloads)
|
||||
.lift(new DynamicConcurrentMergeOperator<>(this::downloadChapter, threads))
|
||||
.onBackpressureBuffer()
|
||||
.subscribe();
|
||||
.subscribe(page -> {},
|
||||
e -> Timber.e(e.fillInStackTrace(), e.getMessage()));
|
||||
}
|
||||
|
||||
// Create a download object for every chapter and add it to the downloads queue
|
||||
private Observable<Download> prepareDownloads(DownloadChaptersEvent event) {
|
||||
final Manga manga = event.getManga();
|
||||
final Source source = sourceManager.get(manga.source);
|
||||
List<Download> downloads = new ArrayList<>();
|
||||
|
||||
for (Chapter chapter : event.getChapters()) {
|
||||
Download download = new Download(source, manga, chapter);
|
||||
|
||||
if (!isChapterDownloaded(download)) {
|
||||
queue.add(download);
|
||||
downloads.add(download);
|
||||
}
|
||||
}
|
||||
|
||||
return Observable.from(downloads);
|
||||
}
|
||||
|
||||
// Check if a chapter is already downloaded
|
||||
private boolean isChapterDownloaded(DownloadChapterEvent event) {
|
||||
final Source source = sourceManager.get(event.getManga().source);
|
||||
|
||||
private boolean isChapterDownloaded(Download download) {
|
||||
// If the chapter is already queued, don't add it again
|
||||
for (Download download : queue.get()) {
|
||||
if (download.chapter.id == event.getChapter().id)
|
||||
for (Download queuedDownload : queue.get()) {
|
||||
if (download.chapter.id == queuedDownload.chapter.id)
|
||||
return true;
|
||||
}
|
||||
|
||||
// If the directory doesn't exist, the chapter isn't downloaded
|
||||
File dir = getAbsoluteChapterDirectory(source, event.getManga(), event.getChapter());
|
||||
if (!dir.exists())
|
||||
// Add the directory to the download object for future access
|
||||
download.directory = getAbsoluteChapterDirectory(download);
|
||||
|
||||
// If the directory doesn't exist, the chapter isn't downloaded. Create it in this case
|
||||
if (!download.directory.exists()) {
|
||||
// FIXME Sometimes it's failing to create the directory... My fault?
|
||||
try {
|
||||
DiskUtils.createDirectory(download.directory);
|
||||
} catch (IOException e) {
|
||||
Timber.e("Unable to create directory for chapter");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// If the page list doesn't exist, the chapter isn't download (or maybe it's,
|
||||
// but we consider it's not)
|
||||
List<Page> savedPages = getSavedPageList(source, event.getManga(), event.getChapter());
|
||||
List<Page> savedPages = getSavedPageList(download);
|
||||
if (savedPages == null)
|
||||
return false;
|
||||
|
||||
// Add the page list to the download object for future access
|
||||
download.pages = savedPages;
|
||||
|
||||
// If the number of files matches the number of pages, the chapter is downloaded.
|
||||
// We have the index file, so we check one file less
|
||||
return (dir.listFiles().length - 1) == savedPages.size();
|
||||
}
|
||||
|
||||
// Create a download object and add it to the downloads queue
|
||||
private Observable<Download> prepareDownload(DownloadChapterEvent event) {
|
||||
Download download = new Download(
|
||||
sourceManager.get(event.getManga().source),
|
||||
event.getManga(),
|
||||
event.getChapter());
|
||||
|
||||
download.directory = getAbsoluteChapterDirectory(
|
||||
download.source, download.manga, download.chapter);
|
||||
|
||||
queue.add(download);
|
||||
return Observable.just(download);
|
||||
// We have the index file, so we check one file more
|
||||
return savedPages.size() + 1 == download.directory.listFiles().length;
|
||||
}
|
||||
|
||||
// Download the entire chapter
|
||||
private Observable<Page> downloadChapter(Download download) {
|
||||
return download.source
|
||||
.pullPageListFromNetwork(download.chapter.url)
|
||||
// Add resulting pages to download object
|
||||
.doOnNext(pages -> {
|
||||
download.pages = pages;
|
||||
download.setStatus(Download.DOWNLOADING);
|
||||
})
|
||||
Observable<List<Page>> pageListObservable = download.pages == null ?
|
||||
// Pull page list from network and add them to download object
|
||||
download.source
|
||||
.pullPageListFromNetwork(download.chapter.url)
|
||||
.doOnNext(pages -> download.pages = pages)
|
||||
.doOnNext(pages -> savePageList(download)) :
|
||||
// Or if the file exists, start from here
|
||||
Observable.just(download.pages);
|
||||
|
||||
return pageListObservable
|
||||
.subscribeOn(Schedulers.io())
|
||||
.doOnNext(pages -> download.setStatus(Download.DOWNLOADING))
|
||||
// Get all the URLs to the source images, fetch pages if necessary
|
||||
.flatMap(pageList -> Observable.merge(
|
||||
Observable.from(pageList).filter(page -> page.getImageUrl() != null),
|
||||
@@ -173,7 +195,7 @@ public class DownloadManager {
|
||||
try {
|
||||
DiskUtils.saveBufferedSourceToDirectory(resp.body().source(), chapterDir, imageFilename);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
Timber.e(e.fillInStackTrace(), e.getMessage());
|
||||
throw new IllegalStateException("Unable to save image");
|
||||
}
|
||||
return Observable.just(page);
|
||||
@@ -193,6 +215,7 @@ public class DownloadManager {
|
||||
|
||||
private void onChapterDownloaded(final Download download) {
|
||||
download.setStatus(Download.DOWNLOADED);
|
||||
download.totalProgress = download.pages.size() * 100;
|
||||
savePageList(download.source, download.manga, download.chapter, download.pages);
|
||||
}
|
||||
|
||||
@@ -202,13 +225,21 @@ public class DownloadManager {
|
||||
File pagesFile = new File(chapterDir, PAGE_LIST_FILE);
|
||||
|
||||
try {
|
||||
JsonReader reader = new JsonReader(new FileReader(pagesFile.getAbsolutePath()));
|
||||
if (pagesFile.exists()) {
|
||||
JsonReader reader = new JsonReader(new FileReader(pagesFile.getAbsolutePath()));
|
||||
|
||||
Type collectionType = new TypeToken<List<Page>>() {}.getType();
|
||||
return gson.fromJson(reader, collectionType);
|
||||
Type collectionType = new TypeToken<List<Page>>() {}.getType();
|
||||
return gson.fromJson(reader, collectionType);
|
||||
}
|
||||
} catch (FileNotFoundException e) {
|
||||
return null;
|
||||
Timber.e(e.fillInStackTrace(), e.getMessage());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Shortcut for the method above
|
||||
private List<Page> getSavedPageList(Download download) {
|
||||
return getSavedPageList(download.source, download.manga, download.chapter);
|
||||
}
|
||||
|
||||
// Save the page list to the chapter's directory
|
||||
@@ -223,10 +254,15 @@ public class DownloadManager {
|
||||
out.flush();
|
||||
out.close();
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Timber.e(e.fillInStackTrace(), e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// Shortcut for the method above
|
||||
private void savePageList(Download download) {
|
||||
savePageList(download.source, download.manga, download.chapter, download.pages);
|
||||
}
|
||||
|
||||
// Get the absolute path to the chapter directory
|
||||
public File getAbsoluteChapterDirectory(Source source, Manga manga, Chapter chapter) {
|
||||
String chapterRelativePath = source.getName() +
|
||||
@@ -238,6 +274,11 @@ public class DownloadManager {
|
||||
return new File(preferences.getDownloadsDirectory(), chapterRelativePath);
|
||||
}
|
||||
|
||||
// Shortcut for the method above
|
||||
private File getAbsoluteChapterDirectory(Download download) {
|
||||
return getAbsoluteChapterDirectory(download.source, download.manga, download.chapter);
|
||||
}
|
||||
|
||||
public void deleteChapter(Source source, Manga manga, Chapter chapter) {
|
||||
File path = getAbsoluteChapterDirectory(source, manga, chapter);
|
||||
DiskUtils.deleteFiles(path);
|
||||
|
||||
@@ -10,7 +10,7 @@ import javax.inject.Inject;
|
||||
import de.greenrobot.event.EventBus;
|
||||
import eu.kanade.mangafeed.App;
|
||||
import eu.kanade.mangafeed.data.helpers.DownloadManager;
|
||||
import eu.kanade.mangafeed.events.DownloadChapterEvent;
|
||||
import eu.kanade.mangafeed.events.DownloadChaptersEvent;
|
||||
import eu.kanade.mangafeed.util.AndroidComponentUtil;
|
||||
import eu.kanade.mangafeed.util.EventBusHook;
|
||||
|
||||
@@ -31,7 +31,7 @@ public class DownloadService extends Service {
|
||||
super.onCreate();
|
||||
App.get(this).getComponent().inject(this);
|
||||
|
||||
EventBus.getDefault().register(this);
|
||||
EventBus.getDefault().registerSticky(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -45,8 +45,9 @@ public class DownloadService extends Service {
|
||||
}
|
||||
|
||||
@EventBusHook
|
||||
public void onEvent(DownloadChapterEvent event) {
|
||||
public void onEvent(DownloadChaptersEvent event) {
|
||||
downloadManager.getDownloadsSubject().onNext(event);
|
||||
EventBus.getDefault().removeStickyEvent(event);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user