-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feature: Guild setup and default loading
- Loading branch information
Showing
25 changed files
with
413 additions
and
115 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package dev.triumphteam.docsly.controller | ||
|
||
import dev.triumphteam.docsly.api.GuildSetupRequest | ||
import dev.triumphteam.docsly.defaults.Defaults | ||
import dev.triumphteam.docsly.project.Projects | ||
import dev.triumphteam.docsly.resource.GuildApi | ||
import io.ktor.http.HttpStatusCode | ||
import io.ktor.server.application.call | ||
import io.ktor.server.application.plugin | ||
import io.ktor.server.request.receive | ||
import io.ktor.server.resources.post | ||
import io.ktor.server.response.respond | ||
import io.ktor.server.routing.Routing | ||
|
||
public fun Routing.apiGuild() { | ||
|
||
val defaults = plugin(Defaults) | ||
val projects = plugin(Projects) | ||
|
||
post<GuildApi.Guild.Setup> { setup -> | ||
val guild = setup.parent.guild | ||
val setupDefaults = call.receive<GuildSetupRequest>().defaults | ||
|
||
val defaultProjects = defaults.defaultProjects() | ||
|
||
// Validate data | ||
setupDefaults.forEach { (project, versions) -> | ||
val defaultVersions = defaultProjects[project] ?: run { | ||
call.respond(HttpStatusCode.BadRequest, "Invalid default project '$project'.") | ||
return@post | ||
} | ||
|
||
versions.forEach { version -> | ||
// TODO: Figure better way to get version, and not use folder name | ||
val replaced = version.replace(".", "_") | ||
if (replaced !in defaultVersions) { | ||
call.respond(HttpStatusCode.BadRequest, "Invalid default project version '$version' for project '$project'.") | ||
return@post | ||
} | ||
} | ||
} | ||
|
||
// If it goes well nothing will throw and it'll work well! | ||
projects.setupProjects(guild, setupDefaults) | ||
|
||
// So we return "accepted" | ||
call.respond(HttpStatusCode.Accepted) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
package dev.triumphteam.docsly.defaults | ||
|
||
import io.ktor.server.application.Application | ||
import io.ktor.server.application.BaseApplicationPlugin | ||
import io.ktor.util.AttributeKey | ||
import java.io.File | ||
import java.io.FileNotFoundException | ||
import java.nio.file.Path | ||
import kotlin.io.path.Path | ||
import kotlin.io.path.isDirectory | ||
import kotlin.io.path.notExists | ||
|
||
public class Defaults { | ||
|
||
// Move to separate repo | ||
private val defaultsFolder: Path = Path("data/defaults") | ||
private val defaults: Map<String, Set<String>> = defaultsFolder.toFile().listFiles()?.mapNotNull { project -> | ||
if (!project.isDirectory) return@mapNotNull null | ||
|
||
val versions = project.listFiles()?.mapNotNull { version -> | ||
if (!version.isDirectory) null else version.name | ||
}?.toSet() ?: emptySet() | ||
|
||
project.name to versions | ||
}?.toMap() ?: emptyMap() | ||
|
||
public fun defaultProjects(): Map<String, Set<String>> { | ||
return defaults | ||
} | ||
|
||
public fun resolve(project: String, version: String): File { | ||
val folder = defaultsFolder.resolve("$project/$version") | ||
if (folder.notExists() || !folder.isDirectory()) { | ||
throw FileNotFoundException("Could not find file with path '${"$project/$version"}'") | ||
} | ||
|
||
return folder.toFile().listFiles()?.find { it.name.endsWith(".json") } | ||
?: throw FileNotFoundException("Could not find json file for '${"$project/$version"}'") | ||
} | ||
|
||
public companion object Plugin : BaseApplicationPlugin<Application, Defaults, Defaults> { | ||
|
||
override val key: AttributeKey<Defaults> = AttributeKey("defaults") | ||
|
||
override fun install(pipeline: Application, configure: Defaults.() -> Unit): Defaults { | ||
return Defaults() | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
package dev.triumphteam.docsly.project | ||
|
||
import dev.triumphteam.docsly.defaults.Defaults | ||
import dev.triumphteam.docsly.elements.DocElement | ||
import dev.triumphteam.docsly.meilisearch.Meili | ||
import dev.triumphteam.docsly.meilisearch.annotation.PrimaryKey | ||
import io.ktor.server.application.Application | ||
import io.ktor.server.application.BaseApplicationPlugin | ||
import io.ktor.server.application.plugin | ||
import io.ktor.util.AttributeKey | ||
import kotlinx.coroutines.runBlocking | ||
import kotlinx.serialization.Serializable | ||
import kotlinx.serialization.json.Json | ||
|
||
public class Projects(private val meili: Meili, private val defaults: Defaults) { | ||
|
||
public companion object Plugin : BaseApplicationPlugin<Application, Projects, Projects> { | ||
|
||
override val key: AttributeKey<Projects> = AttributeKey("Projects") | ||
|
||
override fun install(pipeline: Application, configure: Projects.() -> Unit): Projects { | ||
return Projects(pipeline.plugin(Meili), pipeline.plugin(Defaults)) | ||
} | ||
|
||
public fun indexKeyFor(guild: String, project: String, version: String): String { | ||
return "$guild:$project:$version" | ||
} | ||
} | ||
|
||
private val json = Json { | ||
explicitNulls = false | ||
ignoreUnknownKeys = true | ||
} | ||
|
||
public suspend fun setupProjects(guild: String, projects: Map<String, Set<String>>) { | ||
// transaction { | ||
val mapped = projects.mapValues { (project, versions) -> | ||
versions.associateWith { version -> | ||
val jsonFile = defaults.resolve(project, version.replace(".", "_")) | ||
json.decodeFromString<List<DocElement>>(jsonFile.readText()) | ||
} | ||
} | ||
|
||
runBlocking { | ||
mapped.forEach { (project, versions) -> | ||
versions.forEach { (version, docs) -> | ||
meili.client.index(indexKeyFor(guild, project, version)).addDocuments( | ||
docs.map { doc -> | ||
IndexDocument(doc.location, doc.createReferences()) | ||
} | ||
) | ||
} | ||
} | ||
} | ||
|
||
// TODO: Postgres | ||
// } | ||
} | ||
} | ||
|
||
@Serializable | ||
public data class IndexDocument( | ||
@PrimaryKey public val location: String, | ||
public val references: List<String>, | ||
) |
Oops, something went wrong.