diff --git a/backend/src/main/kotlin/Module.kt b/backend/src/main/kotlin/Module.kt index 1d81b0a..5344617 100644 --- a/backend/src/main/kotlin/Module.kt +++ b/backend/src/main/kotlin/Module.kt @@ -69,7 +69,7 @@ public fun Application.module() { routing { staticResources("/static", "static") - staticFiles("/banners", DATA_FOLDER) + staticFiles("/assets", DATA_FOLDER.resolve("core")) install(CachingHeaders) { options { _, outgoingContent -> diff --git a/backend/src/main/kotlin/api/ApiRouting.kt b/backend/src/main/kotlin/api/ApiRouting.kt index 704903e..f4c8e37 100644 --- a/backend/src/main/kotlin/api/ApiRouting.kt +++ b/backend/src/main/kotlin/api/ApiRouting.kt @@ -2,20 +2,19 @@ package dev.triumphteam.backend.api import dev.triumphteam.backend.DATA_FOLDER import dev.triumphteam.website.api.Api -import dev.triumphteam.website.project.Repository import io.ktor.http.HttpStatusCode import io.ktor.http.content.PartData import io.ktor.http.content.forEachPart import io.ktor.http.content.streamProvider import io.ktor.server.application.call import io.ktor.server.auth.authenticate -import io.ktor.server.request.receive import io.ktor.server.request.receiveMultipart import io.ktor.server.resources.post import io.ktor.server.response.respond import io.ktor.server.routing.Routing import org.slf4j.Logger import org.slf4j.LoggerFactory +import java.io.File private val logger: Logger = LoggerFactory.getLogger("api-route") @@ -32,7 +31,11 @@ public fun Routing.apiRoutes() { when (part) { is PartData.FileItem -> { val fileBytes = part.streamProvider().readBytes() - DATA_FOLDER.resolve("downloads/projects.zip").writeBytes(fileBytes) + val downloadsFolder = DATA_FOLDER.resolve("downloads").apply(File::mkdirs) + val zip = downloadsFolder.resolve("projects.zip").also { + it.writeBytes(fileBytes) + } + setupRepository(zip) } else -> {} diff --git a/backend/src/main/kotlin/api/ProjectSetup.kt b/backend/src/main/kotlin/api/ProjectSetup.kt index 45202ae..1c67893 100644 --- a/backend/src/main/kotlin/api/ProjectSetup.kt +++ b/backend/src/main/kotlin/api/ProjectSetup.kt @@ -5,16 +5,37 @@ import dev.triumphteam.backend.api.database.DocVersionEntity import dev.triumphteam.backend.api.database.PageEntity import dev.triumphteam.backend.api.database.ProjectEntity import dev.triumphteam.backend.banner.BannerMaker -import dev.triumphteam.website.project.Project +import dev.triumphteam.website.JsonSerializer +import dev.triumphteam.website.project.Repository +import net.lingala.zip4j.ZipFile import org.jetbrains.exposed.sql.transactions.transaction -import java.net.URL +import java.io.File +import java.io.FileNotFoundException +import java.nio.file.Files import javax.imageio.ImageIO private val bannerMaker = BannerMaker() -public fun setupRepository(projects: List) { +public fun setupRepository(projects: File) { + + val tempFolder = Files.createTempDirectory("zip-temp").toFile() + ZipFile(projects).extractAll(tempFolder.path) + + val json = tempFolder.resolve("repository.json") + if (!json.exists()) { + throw FileNotFoundException("Could not find temporary repository at ${tempFolder.path}") + } + + val coreDir = DATA_FOLDER.resolve("core").also(File::mkdirs) + // Copy files + tempFolder.listFiles()?.filter(File::isDirectory)?.forEach { + it.copyRecursively(coreDir.resolve(it.name), overwrite = true) + } + // Parse repos + val repo = JsonSerializer.from(json) + transaction { - projects.forEach { project -> + repo.projects.forEach { project -> // Start by deleting project if exists // This will cascade down to all other tables @@ -26,7 +47,7 @@ public fun setupRepository(projects: List) { this.github = project.projectHome } - val projectIcon = ImageIO.read(URL("")) + val projectIcon = ImageIO.read(coreDir.resolve("${project.id}/icon.png")) project.versions.forEach { version -> @@ -37,7 +58,7 @@ public fun setupRepository(projects: List) { this.recommended = version.recommended } - val versionFolder = DATA_FOLDER.resolve("${project.id}/${version.reference}").also { + val versionFolder = DATA_FOLDER.resolve("core/${project.id}/${version.reference}").also { it.mkdirs() } diff --git a/backend/src/main/kotlin/api/database/Entities.kt b/backend/src/main/kotlin/api/database/Entities.kt index d69e529..4c9f0c1 100644 --- a/backend/src/main/kotlin/api/database/Entities.kt +++ b/backend/src/main/kotlin/api/database/Entities.kt @@ -12,7 +12,6 @@ import org.jetbrains.exposed.sql.ReferenceOption public object Projects : IdTable("projects") { public override val id: Column> = varchar("project_id", 255).entityId() public val name: Column = varchar("name", 255) - public val icon: Column = varchar("icon", 1024) public val color: Column = varchar("color", 10) public val github: Column = varchar("github", 1024) @@ -46,7 +45,6 @@ public class ProjectEntity(id: EntityID) : Entity(id) { public companion object : EntityClass(Projects) public var name: String by Projects.name - public var icon: String by Projects.icon public var color: String by Projects.color public var github: String by Projects.github } diff --git a/backend/src/main/kotlin/website/pages/Common.kt b/backend/src/main/kotlin/website/pages/Common.kt index 97bf82b..584477d 100644 --- a/backend/src/main/kotlin/website/pages/Common.kt +++ b/backend/src/main/kotlin/website/pages/Common.kt @@ -1,5 +1,6 @@ package dev.triumphteam.backend.website.pages +import dev.triumphteam.backend.api.database.ProjectEntity import kotlinx.html.FlowContent import kotlinx.html.HEAD import kotlinx.html.HTML @@ -66,3 +67,7 @@ public fun FlowContent.backgroundBlob(properties: List) { ).plus(properties) } } + +public fun createIconPath(projectId: String): String { + return "/assets/${projectId}/icon.png" +} diff --git a/backend/src/main/kotlin/website/pages/docs/DocsPage.kt b/backend/src/main/kotlin/website/pages/docs/DocsPage.kt index c574d51..6e07288 100644 --- a/backend/src/main/kotlin/website/pages/docs/DocsPage.kt +++ b/backend/src/main/kotlin/website/pages/docs/DocsPage.kt @@ -7,6 +7,7 @@ import dev.triumphteam.backend.api.database.DocVersions import dev.triumphteam.backend.api.database.PageEntity import dev.triumphteam.backend.api.database.Pages import dev.triumphteam.backend.api.database.ProjectEntity +import dev.triumphteam.backend.website.pages.createIconPath import dev.triumphteam.backend.website.pages.docs.components.dropDown import dev.triumphteam.backend.website.pages.docs.components.search import dev.triumphteam.backend.website.pages.docs.components.toast @@ -395,7 +396,7 @@ private fun getProject(project: String): ProjectData? { ProjectData( id = projectEntity.id.value, name = projectEntity.name, - icon = projectEntity.icon, + icon = createIconPath(projectEntity.id.value), color = projectEntity.color, versions = versions, ).also { diff --git a/backend/src/main/kotlin/website/pages/home/HomePage.kt b/backend/src/main/kotlin/website/pages/home/HomePage.kt index 94fe536..0a1a048 100644 --- a/backend/src/main/kotlin/website/pages/home/HomePage.kt +++ b/backend/src/main/kotlin/website/pages/home/HomePage.kt @@ -4,6 +4,7 @@ import dev.triumphteam.backend.api.database.DocVersionEntity import dev.triumphteam.backend.api.database.DocVersions import dev.triumphteam.backend.api.database.ProjectEntity import dev.triumphteam.backend.website.pages.backgroundBlob +import dev.triumphteam.backend.website.pages.createIconPath import dev.triumphteam.backend.website.pages.home.resource.Home import dev.triumphteam.backend.website.pages.setupHead import io.ktor.server.application.call @@ -38,7 +39,7 @@ public fun Routing.homeRoutes(developmentMode: Boolean) { ProjectDisplay( id = project.id.value, name = project.name, - icon = project.icon, + icon = createIconPath(project.id.value), color = project.color, version = version.id.value, ) diff --git a/common/build.gradle.kts b/common/build.gradle.kts index 0369bb3..12962fc 100644 --- a/common/build.gradle.kts +++ b/common/build.gradle.kts @@ -3,5 +3,6 @@ plugins { } dependencies { + api(libs.zip) api(libs.ktor.resources) } diff --git a/docs/build.gradle.kts b/docs/build.gradle.kts index aa8b64a..56ee2ae 100644 --- a/docs/build.gradle.kts +++ b/docs/build.gradle.kts @@ -10,6 +10,4 @@ dependencies { implementation(libs.bundles.logger) implementation(libs.bundles.commonmark) implementation(libs.commons.cli) - - implementation("net.lingala.zip4j:zip4j:2.11.5") } diff --git a/docs/src/main/kotlin/Application.kt b/docs/src/main/kotlin/Application.kt index b1ca89b..81659f3 100644 --- a/docs/src/main/kotlin/Application.kt +++ b/docs/src/main/kotlin/Application.kt @@ -166,7 +166,7 @@ public suspend fun main(args: Array) { MultiPartFormDataContent( formData { append("zip", zip.file.readBytes(), Headers.build { - append(HttpHeaders.ContentType, ContentType.Application.Zip) + append(HttpHeaders.ContentType, "multipart/form-data") append(HttpHeaders.ContentDisposition, "filename=\"projects.zip\"") }) }, diff --git a/docs/src/main/kotlin/markdown/highlight/HighlightsExt.kt b/docs/src/main/kotlin/markdown/highlight/HighlightsExt.kt index 21d1116..5a3ae5b 100644 --- a/docs/src/main/kotlin/markdown/highlight/HighlightsExt.kt +++ b/docs/src/main/kotlin/markdown/highlight/HighlightsExt.kt @@ -1,7 +1,5 @@ package dev.triumphteam.website.docs.markdown.highlight -import dev.snipme.highlights.internal.isNewLine - internal val NEW_LINE_CHARS = setOf("\n", "\r", "\r\n") internal fun String.indicesOf(char: Char): Set { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 90948aa..20b86e2 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -8,7 +8,6 @@ ktor = "2.3.10" ktor-css = "1.0.0-pre.754" commonmark = "0.18.0" caffeine = "3.1.8" -highlights = "0.9.0" # Database exposed = "0.51.1" @@ -20,6 +19,7 @@ log4j = "2.20.0" # Other commons = "1.8.0" +zip = "2.11.5" [libraries] @@ -76,7 +76,7 @@ logger-impl = { module = "org.apache.logging.log4j:log4j-slf4j2-impl", version.r # Other commons-cli = { module = "commons-cli:commons-cli", version.ref = "commons" } caffeine = { module = "com.github.ben-manes.caffeine:caffeine", version.ref = "caffeine" } -highlights = { module = "dev.snipme:highlights", version.ref = "highlights" } +zip = { module = "net.lingala.zip4j:zip4j", version.ref = "zip" } # build build-kotlin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" } @@ -93,7 +93,6 @@ commonmark = [ "commonmark-strikethrough", "commonmark-tables", "commonmark-list", - "highlights", ] ktor-server = [ "ktor-server-core",