mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-11-03 23:58:55 +01:00 
			
		
		
		
	Remove simultaneous downloads
This commit is contained in:
		@@ -36,7 +36,6 @@ internal class DownloadNotifier(private val context: Context) {
 | 
			
		||||
     * The size of queue on start download.
 | 
			
		||||
     */
 | 
			
		||||
    var initialQueueSize = 0
 | 
			
		||||
        get() = field
 | 
			
		||||
        set(value) {
 | 
			
		||||
            if (value != 0){
 | 
			
		||||
                isSingleChapter = (value == 1)
 | 
			
		||||
@@ -44,11 +43,6 @@ internal class DownloadNotifier(private val context: Context) {
 | 
			
		||||
            field = value
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Simultaneous download setting > 1.
 | 
			
		||||
     */
 | 
			
		||||
    var multipleDownloadThreads = false
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Updated when error is thrown
 | 
			
		||||
     */
 | 
			
		||||
@@ -91,36 +85,10 @@ internal class DownloadNotifier(private val context: Context) {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Called when download progress changes.
 | 
			
		||||
     * Note: Only accepted when multi download active.
 | 
			
		||||
     *
 | 
			
		||||
     * @param queue the queue containing downloads.
 | 
			
		||||
     */
 | 
			
		||||
    fun onProgressChange(queue: DownloadQueue) {
 | 
			
		||||
        if (multipleDownloadThreads) {
 | 
			
		||||
            doOnProgressChange(null, queue)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Called when download progress changes.
 | 
			
		||||
     * Note: Only accepted when single download active.
 | 
			
		||||
     *
 | 
			
		||||
     * @param download download object containing download information.
 | 
			
		||||
     * @param queue the queue containing downloads.
 | 
			
		||||
     */
 | 
			
		||||
    fun onProgressChange(download: Download, queue: DownloadQueue) {
 | 
			
		||||
        if (!multipleDownloadThreads) {
 | 
			
		||||
            doOnProgressChange(download, queue)
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Show notification progress of chapter.
 | 
			
		||||
     *
 | 
			
		||||
     * @param download download object containing download information.
 | 
			
		||||
     * @param queue the queue containing downloads.
 | 
			
		||||
     */
 | 
			
		||||
    private fun doOnProgressChange(download: Download?, queue: DownloadQueue) {
 | 
			
		||||
    fun onProgressChange(download: Download) {
 | 
			
		||||
        // Create notification
 | 
			
		||||
        with(notification) {
 | 
			
		||||
            // Check if first call.
 | 
			
		||||
@@ -133,28 +101,13 @@ internal class DownloadNotifier(private val context: Context) {
 | 
			
		||||
                isDownloading = true
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (multipleDownloadThreads) {
 | 
			
		||||
                setContentTitle(context.getString(R.string.app_name))
 | 
			
		||||
 | 
			
		||||
                // Reset the queue size if the download progress is negative
 | 
			
		||||
                if ((initialQueueSize - queue.size) < 0)
 | 
			
		||||
                    initialQueueSize = queue.size
 | 
			
		||||
 | 
			
		||||
                setContentText(context.getString(R.string.chapter_downloading_progress)
 | 
			
		||||
                        .format(initialQueueSize - queue.size, initialQueueSize))
 | 
			
		||||
                setProgress(initialQueueSize, initialQueueSize - queue.size, false)
 | 
			
		||||
            } else {
 | 
			
		||||
                download?.let {
 | 
			
		||||
                    val title = it.manga.title.chop(15)
 | 
			
		||||
                    val quotedTitle = Pattern.quote(title)
 | 
			
		||||
                    val chapter = download.chapter.name.replaceFirst("$quotedTitle[\\s]*[-]*[\\s]*".toRegex(RegexOption.IGNORE_CASE), "")
 | 
			
		||||
                    setContentTitle("$title - $chapter".chop(30))
 | 
			
		||||
                    setContentText(context.getString(R.string.chapter_downloading_progress)
 | 
			
		||||
                            .format(it.downloadedImages, it.pages!!.size))
 | 
			
		||||
                    setProgress(it.pages!!.size, it.downloadedImages, false)
 | 
			
		||||
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
            val title = download.manga.title.chop(15)
 | 
			
		||||
            val quotedTitle = Pattern.quote(title)
 | 
			
		||||
            val chapter = download.chapter.name.replaceFirst("$quotedTitle[\\s]*[-]*[\\s]*".toRegex(RegexOption.IGNORE_CASE), "")
 | 
			
		||||
            setContentTitle("$title - $chapter".chop(30))
 | 
			
		||||
            setContentText(context.getString(R.string.chapter_downloading_progress)
 | 
			
		||||
                    .format(download.downloadedImages, download.pages!!.size))
 | 
			
		||||
            setProgress(download.pages!!.size, download.downloadedImages, false)
 | 
			
		||||
        }
 | 
			
		||||
        // Displays the progress bar on notification
 | 
			
		||||
        notification.show()
 | 
			
		||||
 
 | 
			
		||||
@@ -9,8 +9,6 @@ import eu.kanade.tachiyomi.data.database.models.Chapter
 | 
			
		||||
import eu.kanade.tachiyomi.data.database.models.Manga
 | 
			
		||||
import eu.kanade.tachiyomi.data.download.model.Download
 | 
			
		||||
import eu.kanade.tachiyomi.data.download.model.DownloadQueue
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
 | 
			
		||||
import eu.kanade.tachiyomi.data.preference.getOrDefault
 | 
			
		||||
import eu.kanade.tachiyomi.source.SourceManager
 | 
			
		||||
import eu.kanade.tachiyomi.source.model.Page
 | 
			
		||||
import eu.kanade.tachiyomi.source.online.HttpSource
 | 
			
		||||
@@ -21,7 +19,6 @@ import okhttp3.Response
 | 
			
		||||
import rx.Observable
 | 
			
		||||
import rx.android.schedulers.AndroidSchedulers
 | 
			
		||||
import rx.schedulers.Schedulers
 | 
			
		||||
import rx.subjects.BehaviorSubject
 | 
			
		||||
import rx.subscriptions.CompositeSubscription
 | 
			
		||||
import timber.log.Timber
 | 
			
		||||
import uy.kohesive.injekt.injectLazy
 | 
			
		||||
@@ -39,9 +36,11 @@ import uy.kohesive.injekt.injectLazy
 | 
			
		||||
 * @param provider the downloads directory provider.
 | 
			
		||||
 * @param cache the downloads cache, used to add the downloads to the cache after their completion.
 | 
			
		||||
 */
 | 
			
		||||
class Downloader(private val context: Context,
 | 
			
		||||
                 private val provider: DownloadProvider,
 | 
			
		||||
                 private val cache: DownloadCache) {
 | 
			
		||||
class Downloader(
 | 
			
		||||
        private val context: Context,
 | 
			
		||||
        private val provider: DownloadProvider,
 | 
			
		||||
        private val cache: DownloadCache
 | 
			
		||||
) {
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Store for persisting downloads across restarts.
 | 
			
		||||
@@ -58,11 +57,6 @@ class Downloader(private val context: Context,
 | 
			
		||||
     */
 | 
			
		||||
    private val sourceManager: SourceManager by injectLazy()
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Preferences.
 | 
			
		||||
     */
 | 
			
		||||
    private val preferences: PreferencesHelper by injectLazy()
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Notifier for the downloader state and progress.
 | 
			
		||||
     */
 | 
			
		||||
@@ -73,11 +67,6 @@ class Downloader(private val context: Context,
 | 
			
		||||
     */
 | 
			
		||||
    private val subscriptions = CompositeSubscription()
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Subject to do a live update of the number of simultaneous downloads.
 | 
			
		||||
     */
 | 
			
		||||
    private val threadsSubject = BehaviorSubject.create<Int>()
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Relay to send a list of downloads to the downloader.
 | 
			
		||||
     */
 | 
			
		||||
@@ -116,9 +105,6 @@ class Downloader(private val context: Context,
 | 
			
		||||
        val pending = queue.filter { it.status != Download.DOWNLOADED }
 | 
			
		||||
        pending.forEach { if (it.status != Download.QUEUE) it.status = Download.QUEUE }
 | 
			
		||||
 | 
			
		||||
        // Show download notification when simultaneous download > 1.
 | 
			
		||||
        notifier.onProgressChange(queue)
 | 
			
		||||
 | 
			
		||||
        downloadsRelay.call(pending)
 | 
			
		||||
        return !pending.isEmpty()
 | 
			
		||||
    }
 | 
			
		||||
@@ -185,14 +171,8 @@ class Downloader(private val context: Context,
 | 
			
		||||
 | 
			
		||||
        subscriptions.clear()
 | 
			
		||||
 | 
			
		||||
        subscriptions += preferences.downloadThreads().asObservable()
 | 
			
		||||
                .subscribe {
 | 
			
		||||
                    threadsSubject.onNext(it)
 | 
			
		||||
                    notifier.multipleDownloadThreads = it > 1
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
        subscriptions += downloadsRelay.flatMap { Observable.from(it) }
 | 
			
		||||
                .lift(DynamicConcurrentMergeOperator<Download, Download>({ downloadChapter(it) }, threadsSubject))
 | 
			
		||||
        subscriptions += downloadsRelay.concatMapIterable { it }
 | 
			
		||||
                .concatMap { downloadChapter(it).subscribeOn(Schedulers.io()) }
 | 
			
		||||
                .onBackpressureBuffer()
 | 
			
		||||
                .observeOn(AndroidSchedulers.mainThread())
 | 
			
		||||
                .subscribe({ completeDownload(it)
 | 
			
		||||
@@ -250,15 +230,9 @@ class Downloader(private val context: Context,
 | 
			
		||||
            // Initialize queue size.
 | 
			
		||||
            notifier.initialQueueSize = queue.size
 | 
			
		||||
 | 
			
		||||
            // Initial multi-thread
 | 
			
		||||
            notifier.multipleDownloadThreads = preferences.downloadThreads().getOrDefault() > 1
 | 
			
		||||
 | 
			
		||||
            if (isRunning) {
 | 
			
		||||
                // Send the list of downloads to the downloader.
 | 
			
		||||
                downloadsRelay.call(chaptersToQueue)
 | 
			
		||||
            } else {
 | 
			
		||||
                // Show initial notification.
 | 
			
		||||
                notifier.onProgressChange(queue)
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Start downloader if needed
 | 
			
		||||
@@ -273,7 +247,8 @@ class Downloader(private val context: Context,
 | 
			
		||||
     *
 | 
			
		||||
     * @param download the chapter to be downloaded.
 | 
			
		||||
     */
 | 
			
		||||
    private fun downloadChapter(download: Download): Observable<Download> {
 | 
			
		||||
    private fun downloadChapter(download: Download): Observable<Download> = Observable.defer {
 | 
			
		||||
        Timber.e("Thread: ${Thread.currentThread()}")
 | 
			
		||||
        val chapterDirname = provider.getChapterDirName(download.chapter)
 | 
			
		||||
        val mangaDir = provider.getMangaDir(download.manga, download.source)
 | 
			
		||||
        val tmpDir = mangaDir.createDirectory("${chapterDirname}_tmp")
 | 
			
		||||
@@ -292,7 +267,7 @@ class Downloader(private val context: Context,
 | 
			
		||||
            Observable.just(download.pages!!)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return pageListObservable
 | 
			
		||||
        pageListObservable
 | 
			
		||||
                .doOnNext { _ ->
 | 
			
		||||
                    // Delete all temporary (unfinished) files
 | 
			
		||||
                    tmpDir.listFiles()
 | 
			
		||||
@@ -307,7 +282,7 @@ class Downloader(private val context: Context,
 | 
			
		||||
                // Start downloading images, consider we can have downloaded images already
 | 
			
		||||
                .concatMap { page -> getOrDownloadImage(page, download, tmpDir) }
 | 
			
		||||
                // Do when page is downloaded.
 | 
			
		||||
                .doOnNext { notifier.onProgressChange(download, queue) }
 | 
			
		||||
                .doOnNext { notifier.onProgressChange(download) }
 | 
			
		||||
                .toList()
 | 
			
		||||
                .map { _ -> download }
 | 
			
		||||
                // Do after download completes
 | 
			
		||||
@@ -318,7 +293,7 @@ class Downloader(private val context: Context,
 | 
			
		||||
                    notifier.onError(error.message, download.chapter.name)
 | 
			
		||||
                    download
 | 
			
		||||
                }
 | 
			
		||||
                .subscribeOn(Schedulers.io())
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
@@ -448,7 +423,6 @@ class Downloader(private val context: Context,
 | 
			
		||||
        if (download.status == Download.DOWNLOADED) {
 | 
			
		||||
            // remove downloaded chapter from queue
 | 
			
		||||
            queue.remove(download)
 | 
			
		||||
            notifier.onProgressChange(queue)
 | 
			
		||||
        }
 | 
			
		||||
        if (areAllDownloadsFinished()) {
 | 
			
		||||
            if (notifier.isSingleChapter && !notifier.errorThrown) {
 | 
			
		||||
@@ -465,4 +439,4 @@ class Downloader(private val context: Context,
 | 
			
		||||
        return queue.none { it.status <= Download.DOWNLOADING }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -67,8 +67,6 @@ object PreferenceKeys {
 | 
			
		||||
 | 
			
		||||
    const val downloadsDirectory = "download_directory"
 | 
			
		||||
 | 
			
		||||
    const val downloadThreads = "pref_download_slots_key"
 | 
			
		||||
 | 
			
		||||
    const val downloadOnlyOverWifi = "pref_download_only_over_wifi_key"
 | 
			
		||||
 | 
			
		||||
    const val numberOfBackups = "backup_slots"
 | 
			
		||||
 
 | 
			
		||||
@@ -123,8 +123,6 @@ class PreferencesHelper(val context: Context) {
 | 
			
		||||
 | 
			
		||||
    fun downloadsDirectory() = rxPrefs.getString(Keys.downloadsDirectory, defaultDownloadsDir.toString())
 | 
			
		||||
 | 
			
		||||
    fun downloadThreads() = rxPrefs.getInteger(Keys.downloadThreads, 1)
 | 
			
		||||
 | 
			
		||||
    fun downloadOnlyOverWifi() = prefs.getBoolean(Keys.downloadOnlyOverWifi, true)
 | 
			
		||||
 | 
			
		||||
    fun numberOfBackups() = rxPrefs.getInteger(Keys.numberOfBackups, 1)
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user