Files
suwayomi-material-you-webui/server/src/main/kotlin/suwayomi/tachidesk/impl/download/Downloader.kt

75 lines
3.0 KiB
Kotlin
Raw Normal View History

2021-05-27 01:55:21 +04:30
package suwayomi.tachidesk.impl.download
2021-05-20 19:21:30 +04:30
/*
* Copyright (C) Contributors to the Suwayomi project
2021-05-29 23:05:51 +04:30
*
2021-05-20 19:21:30 +04:30
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
2021-05-29 23:05:51 +04:30
import kotlinx.coroutines.runBlocking
import org.jetbrains.exposed.sql.and
import org.jetbrains.exposed.sql.transactions.transaction
import org.jetbrains.exposed.sql.update
2021-05-29 23:05:51 +04:30
import suwayomi.tachidesk.impl.Chapter.getChapter
import suwayomi.tachidesk.impl.Page.getPageImage
import suwayomi.tachidesk.impl.download.model.DownloadChapter
import suwayomi.tachidesk.impl.download.model.DownloadState.Downloading
import suwayomi.tachidesk.impl.download.model.DownloadState.Error
import suwayomi.tachidesk.impl.download.model.DownloadState.Finished
import suwayomi.tachidesk.impl.download.model.DownloadState.Queued
import suwayomi.tachidesk.model.table.ChapterTable
2021-05-29 23:05:51 +04:30
import java.util.concurrent.CopyOnWriteArrayList
2021-05-20 19:21:30 +04:30
2021-05-29 23:05:51 +04:30
class Downloader(private val downloadQueue: CopyOnWriteArrayList<DownloadChapter>, val notifier: () -> Unit) : Thread() {
var shouldStop: Boolean = false
2021-05-20 19:21:30 +04:30
2021-05-29 23:05:51 +04:30
class DownloadShouldStopException : Exception()
2021-05-20 19:21:30 +04:30
2021-05-29 23:05:51 +04:30
fun step() {
notifier()
synchronized(shouldStop) {
if (shouldStop) throw DownloadShouldStopException()
}
2021-05-20 19:21:30 +04:30
}
2021-05-29 23:05:51 +04:30
override fun run() {
do {
val download = downloadQueue.firstOrNull { it.state == Queued } ?: break
try {
download.state = Downloading
step()
download.chapter = runBlocking { getChapter(download.chapterIndex, download.mangaId) }
step()
val pageCount = download.chapter!!.pageCount!!
for (pageNum in 0 until pageCount) {
runBlocking { getPageImage(download.mangaId, download.chapterIndex, pageNum) }
// TODO: retry on error with 2,4,8 seconds of wait
// TODO: download multiple pages at once, possible solution: rx observer's strategy is used in Tachiyomi
download.progress = (pageNum + 1).toFloat() / pageCount
step()
}
download.state = Finished
transaction {
ChapterTable.update({ (ChapterTable.manga eq download.mangaId) and (ChapterTable.chapterIndex eq download.chapterIndex) }) {
it[isDownloaded] = true
}
}
2021-05-29 23:05:51 +04:30
step()
} catch (e: DownloadShouldStopException) {
println("Downloader was stopped")
downloadQueue.filter { it.state == Downloading }.forEach { it.state = Queued }
} catch (e: Exception) {
println("Downloader faced an exception")
downloadQueue.filter { it.state == Downloading }.forEach { it.state = Error }
e.printStackTrace()
} finally {
notifier()
}
} while (!shouldStop)
2021-05-20 19:21:30 +04:30
}
}