download webUI on demand

This commit is contained in:
Aria Moradi
2021-08-08 05:31:58 +04:30
parent a04cbcd814
commit 0f88baf1c1
4 changed files with 116 additions and 13 deletions
+9
View File
@@ -66,6 +66,9 @@ dependencies {
// asm for fixing SimpleDateFormat (must match Dex2Jar version)
implementation("org.ow2.asm:asm-debug-all:5.0.3")
// extracting zip files
implementation("net.lingala.zip4j:zip4j:2.9.0")
// Source models and interfaces from Tachiyomi 1.x
// using source class from tachiyomi commit 9493577de27c40ce8b2b6122cc447d025e34c477 to not depend on tachiyomi.sourceapi
// implementation("tachiyomi.sourceapi:source-api:1.1")
@@ -99,6 +102,7 @@ sourceSets {
// should be bumped with each stable release
val tachideskVersion = System.getenv("ProductVersion") ?: "v0.4.3"
val webUIRevisionTag = System.getenv("WebUIRevision") ?: "r19"
// counts commit count on master
val tachideskRevision = runCatching {
@@ -126,6 +130,11 @@ buildConfig {
buildConfigField("String", "BUILD_TYPE", if (System.getenv("ProductBuildType") == "Stable") "Stable" else "Preview")
buildConfigField("long", "BUILD_TIME", Instant.now().epochSecond.toString())
buildConfigField("String", "WEBUI_REPO", "https://github.com/Suwayomi/Tachidesk-WebUI-preview")
buildConfigField("String", "WEBUI_TAG", webUIRevisionTag)
buildConfigField("String", "GITHUB", "https://github.com/Suwayomi/Tachidesk")
buildConfigField("String", "DISCORD", "https://discord.gg/DDZdqZWaHA")
}
@@ -8,15 +8,20 @@ package suwayomi.tachidesk.server
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
import io.javalin.Javalin
import io.javalin.http.staticfiles.Location
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.future.future
import mu.KotlinLogging
import org.kodein.di.DI
import org.kodein.di.conf.global
import org.kodein.di.instance
import suwayomi.tachidesk.anime.AnimeAPI
import suwayomi.tachidesk.global.GlobalAPI
import suwayomi.tachidesk.manga.MangaAPI
import suwayomi.tachidesk.server.util.Browser
import suwayomi.tachidesk.server.util.setupWebUI
import java.io.IOException
import java.util.concurrent.CompletableFuture
import kotlin.concurrent.thread
@@ -24,6 +29,8 @@ import kotlin.concurrent.thread
object JavalinSetup {
private val logger = KotlinLogging.logger {}
private val applicationDirs by DI.global.instance<ApplicationDirs>()
private val scope = CoroutineScope(SupervisorJob() + Dispatchers.IO)
fun <T> future(block: suspend CoroutineScope.() -> T): CompletableFuture<T> {
@@ -31,25 +38,19 @@ object JavalinSetup {
}
fun javalinSetup() {
var hasWebUiBundled = false
val app = Javalin.create { config ->
try {
// if the bellow line throws an exception then webUI is not bundled
this::class.java.getResource("/webUI/index.html")
if (serverConfig.webUIEnabled) {
setupWebUI()
// no exception so we can tell javalin to serve webUI
hasWebUiBundled = true
config.addStaticFiles("/webUI")
config.addSinglePageRoot("/", "/webUI/index.html")
} catch (e: RuntimeException) {
logger.warn("react build files are missing.")
hasWebUiBundled = false
logger.info { "Serving webUI static files" }
config.addStaticFiles(applicationDirs.webUIRoot, Location.EXTERNAL)
config.addSinglePageRoot("/", applicationDirs.webUIRoot + "/index.html", Location.EXTERNAL)
}
config.enableCorsForAllOrigins()
}.events { event ->
event.serverStarted {
if (hasWebUiBundled && serverConfig.initialOpenInBrowserEnabled) {
if (serverConfig.webUIEnabled && serverConfig.initialOpenInBrowserEnabled) {
Browser.openInBrowser()
}
}
@@ -33,6 +33,7 @@ class ApplicationDirs(
val mangaThumbnailsRoot = "$dataRoot/manga-thumbnails"
val animeThumbnailsRoot = "$dataRoot/anime-thumbnails"
val mangaRoot = "$dataRoot/manga"
val webUIRoot = "$dataRoot/webUI"
}
val serverConfig: ServerConfig by lazy { GlobalConfigManager.module() }
@@ -0,0 +1,92 @@
package suwayomi.tachidesk.server.util
/*
* 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 mu.KotlinLogging
import net.lingala.zip4j.ZipFile
import org.kodein.di.DI
import org.kodein.di.conf.global
import org.kodein.di.instance
import suwayomi.tachidesk.server.ApplicationDirs
import suwayomi.tachidesk.server.BuildConfig
import java.io.BufferedInputStream
import java.io.File
import java.net.URL
import java.nio.charset.StandardCharsets
import java.security.MessageDigest
private val logger = KotlinLogging.logger {}
private val applicationDirs by DI.global.instance<ApplicationDirs>()
private val tmpDir = System.getProperty("java.io.tmpdir")
private fun ByteArray.toHex(): String = joinToString(separator = "") { eachByte -> "%02x".format(eachByte) }
private fun directoryMD5(fileDir: String): String {
var sum = ""
File(fileDir).walk().toList().sortedBy { it.path }.forEach { file ->
if (file.isFile) {
val md5 = MessageDigest.getInstance("MD5")
md5.update(file.readBytes())
val digest = md5.digest()
sum += digest.toHex()
}
}
val md5 = MessageDigest.getInstance("MD5")
md5.update(sum.toByteArray(StandardCharsets.UTF_8))
val digest = md5.digest()
return digest.toHex()
}
fun setupWebUI() {
// check if we have webUI installed and is correct version
val webUIRevisionFile = File(applicationDirs.webUIRoot + "/revision")
if (webUIRevisionFile.exists() && webUIRevisionFile.readText().trim() == BuildConfig.WEBUI_TAG) {
logger.info { "WebUI Static files exists and is the correct revision" }
logger.info { "Verifying WebUI Static files..." }
logger.info { "md5: " + directoryMD5(applicationDirs.webUIRoot) }
} else {
File(applicationDirs.webUIRoot).deleteRecursively()
// download webUI zip
val webUIZip = "Tachidesk-WebUI-${BuildConfig.WEBUI_TAG}.zip"
val webUIZipPath = "$tmpDir/$webUIZip"
val webUIZipURL = "${BuildConfig.WEBUI_REPO}/releases/download/${BuildConfig.WEBUI_TAG}/$webUIZip"
val webUIZipFile = File(webUIZipPath)
webUIZipFile.delete()
logger.info { "Downloading WebUI zip from the Internet..." }
val data = ByteArray(1024)
webUIZipFile.outputStream().use { webUIZipFileOut ->
BufferedInputStream(URL(webUIZipURL).openStream()).use { inp ->
var totalCount = 0
var tresh = 0
while (true) {
val count = inp.read(data, 0, 1024)
totalCount += count
if (totalCount > tresh + 10 * 1024) {
tresh = totalCount
print(" *")
}
if (count == -1)
break
webUIZipFileOut.write(data, 0, count)
}
println()
logger.info { "Downloading WebUI Done." }
}
}
// extract webUI zip
logger.info { "Extracting downloaded WebUI zip..." }
File(applicationDirs.webUIRoot).mkdirs()
ZipFile(webUIZipPath).extractAll(applicationDirs.webUIRoot)
logger.info { "Extracting downloaded WebUI zip Done." }
}
}