updown/updown.js
eclipse bffe457e13 * added upload, download, and delete functionality
* added error handling
* added CSS stylesheet
* bumped version to 0.3
2023-11-11 17:22:10 +01:00

116 lines
3.3 KiB
JavaScript

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')));
// 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(dir).forEach(filename => {
files.push({ name: filename, size: fs.statSync(dir + filename, (e, s) => s).size });
})
console.log(files);//DEBUG
return files;
}
// Handle main page request
app.get('/', (req, res) => {
//TODO: handle sorting
//TODO: keep sort parameter in variable or something
return res.render("updown", {
message: req.query.msg,
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}`)
})