* added upload, download, and delete functionality
* added error handling * added CSS stylesheet * bumped version to 0.3
This commit is contained in:
parent
7179d3cc89
commit
bffe457e13
13
css/updown.css
Normal file
13
css/updown.css
Normal file
@ -0,0 +1,13 @@
|
||||
.table {
|
||||
display: table;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.tr {
|
||||
display: table-row;
|
||||
}
|
||||
|
||||
.td {
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "updown",
|
||||
"version": "0.2.0",
|
||||
"version": "0.3.0",
|
||||
"description": "a simple file uploader/downloader",
|
||||
"main": "updown.js",
|
||||
"scripts": {
|
||||
@ -21,6 +21,7 @@
|
||||
"buffer": "^6.0.3",
|
||||
"crypto-browserify": "^3.12.0",
|
||||
"events": "^3.3.0",
|
||||
"express-fileupload": "^1.4.1",
|
||||
"parcel": "^2.9.3",
|
||||
"path-browserify": "^1.0.1",
|
||||
"process": "^0.11.10",
|
||||
|
||||
102
updown.js
102
updown.js
@ -1,35 +1,115 @@
|
||||
const express = require('express');
|
||||
const fileupload = require('express-fileupload');
|
||||
const app = express();
|
||||
const port = 3000;
|
||||
const path = require('path');
|
||||
const fs = require('fs');
|
||||
const staticPath = "public/";
|
||||
|
||||
app.set("view engine", "pug");
|
||||
app.use(fileupload());
|
||||
// serve static css files
|
||||
app.use(express.static(path.join(__dirname, 'css')));
|
||||
|
||||
function getFilesAndSizes(path) {
|
||||
// Return all files and their sizes
|
||||
function getFilesAndSizes(dir) {
|
||||
// check if dir exists
|
||||
try {
|
||||
fs.accessSync(dir, fs.constants.F_OK);
|
||||
} catch (error) {
|
||||
console.log("exist-check: " + error);
|
||||
return [];
|
||||
}
|
||||
// check if dir is readable
|
||||
try {
|
||||
fs.accessSync(dir, fs.constants.R_OK);
|
||||
} catch (error) {
|
||||
console.log("read-check: " + error);
|
||||
return [];
|
||||
}
|
||||
// get files and their sizes from path
|
||||
let files = [];
|
||||
fs.readdirSync(path).forEach(filename => {
|
||||
files.push({ name: filename, size: fs.statSync(path + filename, (e, s) => s).size });
|
||||
fs.readdirSync(dir).forEach(filename => {
|
||||
files.push({ name: filename, size: fs.statSync(dir + filename, (e, s) => s).size });
|
||||
})
|
||||
console.log(files);
|
||||
console.log(files);//DEBUG
|
||||
return files;
|
||||
}
|
||||
|
||||
// Handle main page request
|
||||
app.get('/', (req, res) => {
|
||||
console.log(req.query);
|
||||
res.render("updown", {
|
||||
message: "method: get",
|
||||
//TODO: handle sorting
|
||||
//TODO: keep sort parameter in variable or something
|
||||
return res.render("updown", {
|
||||
message: req.query.msg,
|
||||
files: getFilesAndSizes(staticPath)
|
||||
})
|
||||
})
|
||||
|
||||
app.post("/", (req, res) => {
|
||||
res.render("updown", {
|
||||
message: "method: post",
|
||||
files: getFilesAndSizes(staticPath)
|
||||
// Handle download request
|
||||
app.get('/download/:file', (req, res) => {
|
||||
console.log('route /download/: params are ' + req.params);//DEBUG
|
||||
res.download(staticPath + req.params['file'], error => {
|
||||
if (!error)
|
||||
return;
|
||||
if (error.status === 404)
|
||||
return res.redirect('/?msg=Download failed: file not found');
|
||||
else
|
||||
return res.redirect('/?msg=Download failed: Internal server error');
|
||||
});
|
||||
})
|
||||
|
||||
// Handle delete request
|
||||
app.get('/delete/:file', (req, res) => {
|
||||
console.log('route /delete/: params are ' + req.params);//DEBUG
|
||||
// check if path is writable
|
||||
fs.access(staticPath, fs.constants.w_OK, (error) => {
|
||||
if (error) {
|
||||
console.log("Deletion error: " + error.message);
|
||||
return res.redirect("/?msg=Deletion failed: Path is not writable");
|
||||
}
|
||||
})
|
||||
// delete file
|
||||
try {
|
||||
fs.rmSync(staticPath + req.params['file']);
|
||||
return res.redirect("/?msg=File deleted");
|
||||
} catch (error) {
|
||||
if (error.message.startsWith("ENOENT")) {
|
||||
return res.redirect("/?msg=Deletion failed: File doesn't exist");
|
||||
} else {
|
||||
console.log("Deletion error: " + error.message);
|
||||
return res.redirect("/?msg=Deletion failed: Internal server error");
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
// Handle upload request
|
||||
app.post("/upload/", (req, res) => {
|
||||
// check if request contains a file
|
||||
if (!req.files || Object.keys(req.files).length === 0) {
|
||||
console.log("Upload error: " + error.message);
|
||||
return res.redirect("/?msg=Upload failed: no file selected");
|
||||
}
|
||||
// check if path is writable
|
||||
fs.access(staticPath, fs.constants.w_OK, (error) => {
|
||||
if (error) {
|
||||
console.log("Upload error: " + error.message);
|
||||
return res.redirect("/?msg=Upload failed: Path is not writable");
|
||||
}
|
||||
})
|
||||
// upload file
|
||||
let upFile = req.files.up;
|
||||
upFile.mv(staticPath + upFile.name, (error) => {
|
||||
if (!error)
|
||||
return res.redirect("/?msg=File uploaded");
|
||||
else {
|
||||
console.log("Upload error: " + error.message);
|
||||
return res.redirect("/?msg=Upload failed: Internal server error");
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`updown listening on port ${port}`)
|
||||
})
|
||||
|
||||
@ -2,23 +2,26 @@ doctype html
|
||||
html
|
||||
head(lang="en")
|
||||
title Updown
|
||||
link(rel='stylesheet', href='/updown.css', type='text/css')
|
||||
body
|
||||
div(align='center')
|
||||
p= message
|
||||
table(align='center')
|
||||
form(method='get', action='')
|
||||
tr
|
||||
th
|
||||
a(href='?sort=name') Uploaded File(s)
|
||||
th
|
||||
a(href='?sort=size') Size
|
||||
th
|
||||
th
|
||||
div#message.table
|
||||
div= message
|
||||
div#f-upload.table
|
||||
form#upload-form(method='post', enctype='multipart/form-data', action='/upload/')
|
||||
label(for='up') Upload File
|
||||
input#up(type='file', name='up')
|
||||
button(type='submit') Submit
|
||||
div#flist.table
|
||||
div.tr#flist-heading
|
||||
div.td
|
||||
a(href='?sort=name') Uploaded File(s)
|
||||
div.td
|
||||
a(href='?sort=size') Size
|
||||
each file in files
|
||||
tr
|
||||
td= file.name
|
||||
td= file.size
|
||||
td
|
||||
a(href='?download='+file.name alt="download") 🠳
|
||||
td
|
||||
a(href='?delete='+file.name alt="delete") 🞬
|
||||
div.tr
|
||||
div.td= file.name
|
||||
div.td= file.size
|
||||
div.td
|
||||
a(href='/download/'+file.name alt="download file") 🠳
|
||||
div.td
|
||||
a(href='/delete/'+file.name alt="delete file") 🞬
|
||||
|
||||
Loading…
Reference in New Issue
Block a user