Skip to content

Commit

Permalink
Handle file not found errors
Browse files Browse the repository at this point in the history
  • Loading branch information
paulikauro committed Jun 14, 2020
1 parent e1ab653 commit 4a11520
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 16 deletions.
2 changes: 1 addition & 1 deletion src/main/kotlin/Commands.kt
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ class Commands(private val worldEdit: WorldEdit) : BaseCommand() {
@CommandAlias("/save")
@CommandCompletion("@schematics")
fun save(player: Player, schems: PlayerSchematics, filename: String) {
val file = schems.file(filename)
val file = schems.file(filename, mustExist = false)
val clipboard = try {
player.weSession.clipboard.clipboard
} catch (e: EmptyClipboardException) {
Expand Down
20 changes: 14 additions & 6 deletions src/main/kotlin/Schemati.kt
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
package schemati

import co.aikar.commands.*
import co.aikar.commands.BaseCommand
import co.aikar.commands.CommandIssuer
import co.aikar.commands.PaperCommandManager
import co.aikar.commands.RegisteredCommand
import com.sk89q.worldedit.bukkit.WorldEditPlugin
import io.ktor.server.engine.ApplicationEngine
import org.bukkit.plugin.java.JavaPlugin
import schemati.connector.Database
import schemati.connector.NetworkDatabase
import schemati.web.AuthConfig
import schemati.web.startWeb
import java.io.File
import java.util.logging.Level
import kotlin.concurrent.thread

class Schemati : JavaPlugin() {
private var web: ApplicationEngine? = null
private var networkDatabase: NetworkDatabase? = null
private var networkDatabase: Database? = null

private fun handleCommandException(
command: BaseCommand,
Expand All @@ -20,9 +26,11 @@ class Schemati : JavaPlugin() {
args: List<String>,
throwable: Throwable
): Boolean {
val message = (throwable as? SchematicsException)?.message ?: return false
logger.log(Level.SEVERE, "Error while executing command", throwable)
val exception = throwable as? SchematicsException ?: return false
// TODO: figure out what to do with sendError
sender.sendMessage(message)
val message = exception.message ?: "Something went wrong!"
sender.sendMessage("[Schemati] $message")
return true
}

Expand All @@ -37,8 +45,9 @@ class Schemati : JavaPlugin() {
}
commandCompletions.registerCompletion("schematics", SchematicCompletionHandler(schems))
registerCommand(Commands(wePlugin.worldEdit))
setDefaultExceptionHandler(::handleCommandException, true)
setDefaultExceptionHandler(::handleCommandException, false)
}

networkDatabase = config.getConfigurationSection("network_database")!!.run {
NetworkDatabase(
database = getString("database")!!,
Expand All @@ -59,7 +68,6 @@ class Schemati : JavaPlugin() {
)
}


if (config.contains("web.port")) {
web = startWeb(
config.getConfigurationSection("web")!!.getInt("port"),
Expand Down
14 changes: 11 additions & 3 deletions src/main/kotlin/Schematics.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ package schemati
import com.sk89q.worldedit.extent.clipboard.io.ClipboardFormats
import java.io.File
import java.io.IOException
import java.nio.file.Files
import java.nio.file.Path
import java.util.*

// TODO: catch exception somewhere during instantiation
Expand All @@ -19,10 +21,16 @@ class PlayerSchematics(schematicsDir: File, uuid: UUID) {
private val playerDir = File(schematicsDir, uuid.toString())
.also(File::ensureDirectoryExists)

fun file(filename: String): File {
// TODO: get rid of bool
// also the whole validation business is weird
// this only checks name and existence,
// while others check name and validity but not existence directly
fun file(filename: String, mustExist: Boolean = true): File {
if (!filename.isValidName())
throw SchematicsException("Filename is invalid")
return File(playerDir, filename)
return File(playerDir, filename).apply {
if (mustExist && !exists()) throw SchematicsException("File does not exist")
}
}

fun list(): List<String> = playerDir
Expand All @@ -31,7 +39,7 @@ class PlayerSchematics(schematicsDir: File, uuid: UUID) {

fun rename(filename: String, newName: String) {
val file = file(filename)
val new = file(newName)
val new = file(newName, mustExist = false)
if (file.extension != new.extension)
throw SchematicsException("You cannot change the file extension")
if (!file.renameTo(new))
Expand Down
3 changes: 2 additions & 1 deletion src/main/kotlin/connector/Database.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ data class User(val mojangId: UUID, val discordId: String, val ign: String)

interface Database {
fun findUserByDiscordId(discordId: String): User?
fun unload()
}

class NetworkDatabase(port: Int = 3306, host: String = "localhost", database: String, username: String, password: String): Database {
Expand All @@ -28,7 +29,7 @@ class NetworkDatabase(port: Int = 3306, host: String = "localhost", database: St
return connection.first(selectUserFromDiscordId, toUser)
}

fun unload() {
override fun unload() {
connection.close()
}
}
5 changes: 3 additions & 2 deletions src/main/kotlin/web/Page.kt
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ suspend fun pageSchemsUpload(call: ApplicationCall, schems: PlayerSchematics) {
.filterIsInstance<PartData.FileItem>()
if (parts.isEmpty()) showErrorPage("Did not receive file")
val filename = parts.first().originalFileName ?: showLoggedInErrorPage("File does not have a name")
val file = schems.file(filename)
val file = schems.file(filename, mustExist = false)
file.outputStream().buffered().use { destination ->
parts.forEach { part ->
part.streamProvider().use { it.copyTo(destination) }
Expand All @@ -106,9 +106,10 @@ suspend fun pageSchemsUpload(call: ApplicationCall, schems: PlayerSchematics) {

suspend fun pageSchemsDownload(call: ApplicationCall, schems: PlayerSchematics) {
val filename = call.parameters["file"] ?: showLoggedInErrorPage("Did not receive parameter file")
val file = schems.file(filename)
call.response.header(
HttpHeaders.ContentDisposition,
ContentDisposition.Attachment.withParameter(ContentDisposition.Parameters.FileName, filename).toString()
)
call.respondFile(schems.file(filename))
call.respondFile(file)
}
4 changes: 4 additions & 0 deletions src/main/kotlin/web/Templates.kt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ class LoggedInErrorTemplate : Template<HTML> {
insert(base) {
content {
insert(errorContent)
// TODO: install design
a("/schems") { +"Back to start" }
}
}
}
Expand All @@ -37,6 +39,8 @@ class ErrorTemplate : Template<HTML> {
insert(base) {
mainContent {
insert(errorContent)
// TODO: install design
a("/schems") { +"Back to start" }
}
}
}
Expand Down
4 changes: 1 addition & 3 deletions src/main/kotlin/web/Web.kt
Original file line number Diff line number Diff line change
Expand Up @@ -74,12 +74,10 @@ fun makeSchemsApp(networkDatabase: Database, authConfig: AuthConfig, schems: Sch

install(DefaultHeaders)

// Registers session management
install(Sessions) {
cookie<LoggedSession>("sessionId", storage = SessionStorageMemory())
}

// Registers authentication
install(Authentication) {
oauth("discordOauth") {
client = HttpClient(Apache)
Expand All @@ -90,7 +88,6 @@ fun makeSchemsApp(networkDatabase: Database, authConfig: AuthConfig, schems: Sch
}
}

// Registers routes
install(Routing) {
get("/") {
pageLanding(call)
Expand All @@ -115,6 +112,7 @@ fun makeSchemsApp(networkDatabase: Database, authConfig: AuthConfig, schems: Sch
pageSchemsDelete(call, schems.forPlayer(user().userId))
}
}

authenticate("discordOauth") {
route("/login") {
param("error") {
Expand Down

0 comments on commit 4a11520

Please sign in to comment.