diff options
author | Marvin Borner | 2019-04-14 17:55:38 +0200 |
---|---|---|
committer | Marvin Borner | 2019-04-14 17:55:38 +0200 |
commit | 8c6905d0553b88b1257cab13355873d5438704fa (patch) | |
tree | 7e80cc38d7dcff6841c673ba716bd3c742fd7694 | |
parent | a12e7139a8df8303c9fef79f3f20a170ea0af278 (diff) |
Added table for file list view
-rw-r--r-- | src/main/kotlin/App.kt | 38 | ||||
-rw-r--r-- | src/main/resources/css/files.css | 16 | ||||
-rw-r--r-- | src/main/resources/js/files.js | 16 | ||||
-rw-r--r-- | src/main/resources/views/files.rocker.html | 32 |
4 files changed, 84 insertions, 18 deletions
diff --git a/src/main/kotlin/App.kt b/src/main/kotlin/App.kt index 16b9fff..8b1de6d 100644 --- a/src/main/kotlin/App.kt +++ b/src/main/kotlin/App.kt @@ -14,6 +14,7 @@ import org.joda.time.* import java.io.* import java.nio.charset.* import java.nio.file.* +import java.text.* import java.util.* import java.util.logging.* import kotlin.math.* @@ -55,11 +56,13 @@ fun main() { /** * Renders the login page */ - get( - "/login", - { ctx -> ctx.render("login.rocker.html", model("message", "", "counter", 0)) }, - roles(Roles.GUEST) - ) + get("/login", { ctx -> + if (getVerifiedUserId(ctx) > 0) ctx.redirect("/") + else ctx.render( + "login.rocker.html", + model("message", "", "counter", 0) + ) + }, roles(Roles.GUEST)) /** * Endpoint for user authentication @@ -132,14 +135,20 @@ fun crawlFiles(ctx: Context) { File(usersFileHome).mkdirs() when { File("$usersFileHome/${ctx.splats()[0]}").isDirectory -> { - val files = ArrayList<String>() + val files = ArrayList<Array<String>>() Files.list(Paths.get("$usersFileHome/${ctx.splats()[0]}/")).forEach { val fileName = it.toString() .drop(usersFileHome.length + (if (ctx.splats()[0].isNotEmpty()) ctx.splats()[0].length + 2 else 1)) val filePath = "$usersFileHome${it.toString().drop(usersFileHome.length)}" - files.add(if (File(filePath).isDirectory) "$fileName/" else fileName) + files.add( + arrayOf( + if (File(filePath).isDirectory) "$fileName/" else fileName, + humanReadableBytes(File(filePath).length()), + SimpleDateFormat("MM/dd/yyyy HH:mm:ss").format(File(filePath).lastModified()).toString() + ) + ) } - files.sortWith(String.CASE_INSENSITIVE_ORDER) + //files.sortWith(String.CASE_INSENSITIVE_ORDER) ctx.render( "files.rocker.html", model( "files", files, @@ -169,11 +178,10 @@ fun crawlFiles(ctx: Context) { * Saves multipart media data into requested directory */ fun upload(ctx: Context) { - ctx.uploadedFiles("file").forEach { (contentType, content, name, extension) -> + ctx.uploadedFiles("file").forEach { (_, content, name, _) -> val path = "$fileHome/${getVerifiedUserId(ctx)}/${ctx.splats()[0]}/$name" FileUtil.streamToFile(content, path) databaseController.addFile(path, getVerifiedUserId(ctx)) - ctx.redirect("/upload") } } @@ -197,10 +205,20 @@ private fun isHumanReadable(filePath: String): Boolean { return d > 0.95 } +fun humanReadableBytes(bytes: Long): String { + val unit = 1024 + if (bytes < unit) return "$bytes B" + val exp = (Math.log(bytes.toDouble()) / Math.log(unit.toDouble())).toInt() + val pre = "KMGTPE"[exp - 1] + "i" + return String.format("%.1f %sB", bytes / Math.pow(unit.toDouble(), exp.toDouble()), pre) +} + /** * Checks and verifies users credentials and logs the user in */ fun login(ctx: Context) { + if (getVerifiedUserId(ctx) > 0) ctx.redirect("/") + val username = ctx.formParam("username").toString() val password = ctx.formParam("password").toString() val requestIp = ctx.ip() diff --git a/src/main/resources/css/files.css b/src/main/resources/css/files.css index 798e3ec..3ca6792 100644 --- a/src/main/resources/css/files.css +++ b/src/main/resources/css/files.css @@ -1,3 +1,19 @@ +table { + width: 100%; +} + +table, td, th { + vertical-align: middle; + border-spacing: 0; + white-space: nowrap; +} + +table th, table td { + padding: 10px; + border-bottom: 1px solid gray; + text-align: center; +} + a.filename { color: black; text-decoration: none; diff --git a/src/main/resources/js/files.js b/src/main/resources/js/files.js index 24140b0..3cdf4fd 100644 --- a/src/main/resources/js/files.js +++ b/src/main/resources/js/files.js @@ -22,10 +22,24 @@ drop.addEventListener('drop', e => { let request = new XMLHttpRequest(); let formData = new FormData(); - drop.insertAdjacentHTML('beforeend', `<a class="filename" href="${files[i].name}">${files[i].name}</a><br><hr>`); + // TODO: Consider using current date due to updated lastModified state at upload + const date = new Date(files[i].lastModified); + const lastModified = `${date.getMonth() + 1}/${date.getDate()}/${date.getFullYear()} ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()}`; + + const row = document.getElementById("table").insertRow(-1); + row.insertCell(0).innerHTML = `<a class="filename" href="${files[i].name}">${files[i].name}</a>`; + row.insertCell(1).innerHTML = `<a class="filename" href="${files[i].name}">${bytesToSize(files[i].size)}</a>`; + row.insertCell(2).innerHTML = `<a class="filename" href="${files[i].name}">${lastModified}</a>`; formData.append("file", files[i]); request.open("POST", "/upload/" + path); request.send(formData); } + + function bytesToSize(bytes) { + const sizes = ['B', 'KiB', 'MiB', 'GiB', 'TiB']; + if (bytes === 0) return '0 Byte'; + const i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024))); + return Math.round(bytes / Math.pow(1024, i), 2) + ' ' + sizes[i]; + } }); diff --git a/src/main/resources/views/files.rocker.html b/src/main/resources/views/files.rocker.html index f9852f8..2c4a7ff 100644 --- a/src/main/resources/views/files.rocker.html +++ b/src/main/resources/views/files.rocker.html @@ -12,12 +12,30 @@ @layout.template(files.size() + " Files", css, js) -> { <div class="drop" id="drop"> - <h1>/@path</h1> - <a class="filename" href="../">../</a><br> - <hr> - @for (String file : files) { - <a class="filename" href="@file">@file</a><br> - <hr> - } + <h2>/@path</h2> + <table id="table"> + <thead> + <tr> + <th>Name</th> + <th>Size</th> + <th>Last modified</th> + </tr> + </thead> + + <tbody> + <tr> + <td><a class="filename" href="../">../</a></td> + <td><a class="filename" href="../"></a></td> + <td><a class="filename" href="../"></a></td> + </tr> + @for (String[] fileArray : files) { + <tr> + <td><a class="filename" href="@fileArray[0]">@fileArray[0]</a></td> + <td><a class="filename" href="@fileArray[0]">@fileArray[1]</a></td> + <td><a class="filename" href="@fileArray[0]">@fileArray[2]</a></td> + </tr> + } + </tbody> + </table> </div> } |