aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarvin Borner2019-04-14 17:55:38 +0200
committerMarvin Borner2019-04-14 17:55:38 +0200
commit8c6905d0553b88b1257cab13355873d5438704fa (patch)
tree7e80cc38d7dcff6841c673ba716bd3c742fd7694
parenta12e7139a8df8303c9fef79f3f20a170ea0af278 (diff)
Added table for file list view
-rw-r--r--src/main/kotlin/App.kt38
-rw-r--r--src/main/resources/css/files.css16
-rw-r--r--src/main/resources/js/files.js16
-rw-r--r--src/main/resources/views/files.rocker.html32
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>
}