mirror of
https://github.com/tachiyomiorg/tachiyomi-extensions-inspector.git
synced 2024-12-26 00:31:49 +01:00
finishing touches of download backend, done @jipfr's requests
This commit is contained in:
parent
b56045e984
commit
d249867c4c
@ -0,0 +1,24 @@
|
||||
package suwayomi.server.database.migration
|
||||
|
||||
/*
|
||||
* Copyright (C) Contributors to the Suwayomi project
|
||||
*
|
||||
* 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/. */
|
||||
|
||||
import org.jetbrains.exposed.sql.transactions.TransactionManager
|
||||
import org.jetbrains.exposed.sql.vendors.currentDialect
|
||||
import suwayomi.server.database.migration.lib.Migration
|
||||
|
||||
@Suppress("ClassName", "unused")
|
||||
class M0007_ChapterIsDownloaded : Migration() {
|
||||
/** this migration added IS_DOWNLOADED to CHAPTER */
|
||||
override fun run() {
|
||||
with(TransactionManager.current()) {
|
||||
exec("ALTER TABLE CHAPTER ADD COLUMN IS_DOWNLOADED BOOLEAN DEFAULT FALSE")
|
||||
commit()
|
||||
currentDialect.resetCaches()
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package suwayomi.server.database.migration
|
||||
|
||||
/*
|
||||
* Copyright (C) Contributors to the Suwayomi project
|
||||
*
|
||||
* 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/. */
|
||||
|
||||
import org.jetbrains.exposed.sql.transactions.TransactionManager
|
||||
import org.jetbrains.exposed.sql.vendors.currentDialect
|
||||
import suwayomi.server.database.migration.lib.Migration
|
||||
|
||||
@Suppress("ClassName", "unused")
|
||||
class M0008_ChapterPageCount : Migration() {
|
||||
/** this migration added PAGE_COUNT to CHAPTER */
|
||||
override fun run() {
|
||||
with(TransactionManager.current()) {
|
||||
exec("ALTER TABLE CHAPTER ADD COLUMN PAGE_COUNT INT DEFAULT -1")
|
||||
commit()
|
||||
currentDialect.resetCaches()
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
package suwayomi.server.database.migration
|
||||
|
||||
/*
|
||||
* Copyright (C) Contributors to the Suwayomi project
|
||||
*
|
||||
* 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/. */
|
||||
|
||||
import org.jetbrains.exposed.sql.transactions.TransactionManager
|
||||
import org.jetbrains.exposed.sql.vendors.currentDialect
|
||||
import suwayomi.server.database.migration.lib.Migration
|
||||
|
||||
@Suppress("ClassName", "unused")
|
||||
class M0009_ChapterLastReadAt : Migration() {
|
||||
/** this migration added PAGE_COUNT to CHAPTER */
|
||||
override fun run() {
|
||||
with(TransactionManager.current()) {
|
||||
// BIGINT == Long
|
||||
exec("ALTER TABLE CHAPTER ADD COLUMN LAST_READ_AT BIGINT DEFAULT 0")
|
||||
commit()
|
||||
currentDialect.resetCaches()
|
||||
}
|
||||
}
|
||||
}
|
@ -24,6 +24,7 @@ import suwayomi.tachidesk.model.table.ChapterTable
|
||||
import suwayomi.tachidesk.model.table.MangaTable
|
||||
import suwayomi.tachidesk.model.table.PageTable
|
||||
import suwayomi.tachidesk.model.table.toDataClass
|
||||
import java.time.Instant
|
||||
|
||||
object Chapter {
|
||||
/** get chapter list when showing a manga */
|
||||
@ -122,9 +123,14 @@ object Chapter {
|
||||
dbChapter[ChapterTable.isRead],
|
||||
dbChapter[ChapterTable.isBookmarked],
|
||||
dbChapter[ChapterTable.lastPageRead],
|
||||
dbChapter[ChapterTable.lastReadAt],
|
||||
|
||||
chapterCount - index,
|
||||
chapterList.size
|
||||
dbChapter[ChapterTable.isDownloaded],
|
||||
|
||||
dbChapter[ChapterTable.pageCount],
|
||||
|
||||
chapterList.size,
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -136,54 +142,68 @@ object Chapter {
|
||||
(ChapterTable.chapterIndex eq chapterIndex) and (ChapterTable.manga eq mangaId)
|
||||
}.first()
|
||||
}
|
||||
val mangaEntry = transaction { MangaTable.select { MangaTable.id eq mangaId }.first() }
|
||||
val source = getHttpSource(mangaEntry[MangaTable.sourceReference])
|
||||
|
||||
val pageList = source.fetchPageList(
|
||||
SChapter.create().apply {
|
||||
url = chapterEntry[ChapterTable.url]
|
||||
name = chapterEntry[ChapterTable.name]
|
||||
}
|
||||
).awaitSingle()
|
||||
return if (!chapterEntry[ChapterTable.isDownloaded]) {
|
||||
val mangaEntry = transaction { MangaTable.select { MangaTable.id eq mangaId }.first() }
|
||||
val source = getHttpSource(mangaEntry[MangaTable.sourceReference])
|
||||
|
||||
val chapterId = chapterEntry[ChapterTable.id].value
|
||||
val chapterCount = transaction { ChapterTable.select { ChapterTable.manga eq mangaId }.count() }
|
||||
val pageList = source.fetchPageList(
|
||||
SChapter.create().apply {
|
||||
url = chapterEntry[ChapterTable.url]
|
||||
name = chapterEntry[ChapterTable.name]
|
||||
}
|
||||
).awaitSingle()
|
||||
|
||||
// update page list for this chapter
|
||||
transaction {
|
||||
pageList.forEach { page ->
|
||||
val pageEntry = transaction { PageTable.select { (PageTable.chapter eq chapterId) and (PageTable.index eq page.index) }.firstOrNull() }
|
||||
if (pageEntry == null) {
|
||||
PageTable.insert {
|
||||
it[index] = page.index
|
||||
it[url] = page.url
|
||||
it[imageUrl] = page.imageUrl
|
||||
it[chapter] = chapterId
|
||||
}
|
||||
} else {
|
||||
PageTable.update({ (PageTable.chapter eq chapterId) and (PageTable.index eq page.index) }) {
|
||||
it[url] = page.url
|
||||
it[imageUrl] = page.imageUrl
|
||||
val chapterId = chapterEntry[ChapterTable.id].value
|
||||
val chapterCount = transaction { ChapterTable.select { ChapterTable.manga eq mangaId }.count() }
|
||||
|
||||
// update page list for this chapter
|
||||
transaction {
|
||||
pageList.forEach { page ->
|
||||
val pageEntry = transaction { PageTable.select { (PageTable.chapter eq chapterId) and (PageTable.index eq page.index) }.firstOrNull() }
|
||||
if (pageEntry == null) {
|
||||
PageTable.insert {
|
||||
it[index] = page.index
|
||||
it[url] = page.url
|
||||
it[imageUrl] = page.imageUrl
|
||||
it[chapter] = chapterId
|
||||
}
|
||||
} else {
|
||||
PageTable.update({ (PageTable.chapter eq chapterId) and (PageTable.index eq page.index) }) {
|
||||
it[url] = page.url
|
||||
it[imageUrl] = page.imageUrl
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val pageCount = pageList.count()
|
||||
|
||||
transaction {
|
||||
ChapterTable.update({ (ChapterTable.manga eq mangaId) and (ChapterTable.chapterIndex eq chapterIndex) }) {
|
||||
it[ChapterTable.pageCount] = pageCount
|
||||
}
|
||||
}
|
||||
return ChapterDataClass(
|
||||
chapterEntry[ChapterTable.url],
|
||||
chapterEntry[ChapterTable.name],
|
||||
chapterEntry[ChapterTable.date_upload],
|
||||
chapterEntry[ChapterTable.chapter_number],
|
||||
chapterEntry[ChapterTable.scanlator],
|
||||
mangaId,
|
||||
chapterEntry[ChapterTable.isRead],
|
||||
chapterEntry[ChapterTable.isBookmarked],
|
||||
chapterEntry[ChapterTable.lastPageRead],
|
||||
chapterEntry[ChapterTable.lastReadAt],
|
||||
|
||||
chapterEntry[ChapterTable.chapterIndex],
|
||||
chapterEntry[ChapterTable.isDownloaded],
|
||||
pageCount,
|
||||
chapterCount.toInt()
|
||||
)
|
||||
} else {
|
||||
ChapterTable.toDataClass(chapterEntry)
|
||||
}
|
||||
|
||||
return ChapterDataClass(
|
||||
chapterEntry[ChapterTable.url],
|
||||
chapterEntry[ChapterTable.name],
|
||||
chapterEntry[ChapterTable.date_upload],
|
||||
chapterEntry[ChapterTable.chapter_number],
|
||||
chapterEntry[ChapterTable.scanlator],
|
||||
mangaId,
|
||||
chapterEntry[ChapterTable.isRead],
|
||||
chapterEntry[ChapterTable.isBookmarked],
|
||||
chapterEntry[ChapterTable.lastPageRead],
|
||||
|
||||
chapterEntry[ChapterTable.chapterIndex],
|
||||
chapterCount.toInt(),
|
||||
pageList.count()
|
||||
)
|
||||
}
|
||||
|
||||
fun modifyChapter(mangaId: Int, chapterIndex: Int, isRead: Boolean?, isBookmarked: Boolean?, markPrevRead: Boolean?, lastPageRead: Int?) {
|
||||
@ -198,6 +218,7 @@ object Chapter {
|
||||
}
|
||||
lastPageRead?.also {
|
||||
update[ChapterTable.lastPageRead] = it
|
||||
update[ChapterTable.lastReadAt] = Instant.now().epochSecond
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,9 @@ package suwayomi.tachidesk.impl.download
|
||||
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
||||
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import org.jetbrains.exposed.sql.and
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
import org.jetbrains.exposed.sql.update
|
||||
import suwayomi.tachidesk.impl.Chapter.getChapter
|
||||
import suwayomi.tachidesk.impl.Page.getPageImage
|
||||
import suwayomi.tachidesk.impl.download.model.DownloadChapter
|
||||
@ -15,6 +18,7 @@ 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
|
||||
import java.util.concurrent.CopyOnWriteArrayList
|
||||
|
||||
class Downloader(private val downloadQueue: CopyOnWriteArrayList<DownloadChapter>, val notifier: () -> Unit) : Thread() {
|
||||
@ -49,6 +53,11 @@ class Downloader(private val downloadQueue: CopyOnWriteArrayList<DownloadChapter
|
||||
step()
|
||||
}
|
||||
download.state = Finished
|
||||
transaction {
|
||||
ChapterTable.update({ (ChapterTable.manga eq download.mangaId) and (ChapterTable.chapterIndex eq download.chapterIndex) }) {
|
||||
it[isDownloaded] = true
|
||||
}
|
||||
}
|
||||
step()
|
||||
} catch (e: DownloadShouldStopException) {
|
||||
println("Downloader was stopped")
|
||||
|
@ -24,12 +24,19 @@ data class ChapterDataClass(
|
||||
/** last read page, zero means not read/no data */
|
||||
val lastPageRead: Int,
|
||||
|
||||
/** last read page, zero means not read/no data */
|
||||
val lastReadAt: Long,
|
||||
|
||||
/** this chapter's index, starts with 1 */
|
||||
val index: Int,
|
||||
|
||||
/** is chapter downloaded */
|
||||
val downloaded: Boolean,
|
||||
|
||||
/** used to construct pages in the front-end */
|
||||
val pageCount: Int = -1,
|
||||
|
||||
/** total chapter count, used to calculate if there's a next and prev chapter */
|
||||
val chapterCount: Int? = null,
|
||||
|
||||
/** used to construct pages in the front-end */
|
||||
val pageCount: Int? = null,
|
||||
)
|
||||
|
@ -9,6 +9,8 @@ package suwayomi.tachidesk.model.table
|
||||
|
||||
import org.jetbrains.exposed.dao.id.IntIdTable
|
||||
import org.jetbrains.exposed.sql.ResultRow
|
||||
import org.jetbrains.exposed.sql.select
|
||||
import org.jetbrains.exposed.sql.transactions.transaction
|
||||
import suwayomi.tachidesk.model.dataclass.ChapterDataClass
|
||||
|
||||
object ChapterTable : IntIdTable() {
|
||||
@ -21,10 +23,15 @@ object ChapterTable : IntIdTable() {
|
||||
val isRead = bool("read").default(false)
|
||||
val isBookmarked = bool("bookmark").default(false)
|
||||
val lastPageRead = integer("last_page_read").default(0)
|
||||
val lastReadAt = long("last_read_at").default(0)
|
||||
|
||||
// index is reserved by a function
|
||||
val chapterIndex = integer("index")
|
||||
|
||||
val isDownloaded = bool("is_downloaded").default(false)
|
||||
|
||||
val pageCount = integer("page_count").default(-1)
|
||||
|
||||
val manga = reference("manga", MangaTable)
|
||||
}
|
||||
|
||||
@ -39,5 +46,9 @@ fun ChapterTable.toDataClass(chapterEntry: ResultRow) =
|
||||
chapterEntry[isRead],
|
||||
chapterEntry[isBookmarked],
|
||||
chapterEntry[lastPageRead],
|
||||
chapterEntry[lastReadAt],
|
||||
chapterEntry[chapterIndex],
|
||||
chapterEntry[isDownloaded],
|
||||
chapterEntry[pageCount],
|
||||
transaction { ChapterTable.select { ChapterTable.manga eq chapterEntry[manga].value }.count().toInt() },
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user