mirror of
https://git.sr.ht/~coasteen/webui
synced 2025-11-04 11:37:34 +01:00
Merge branch 'main' into main
This commit is contained in:
commit
8e133c31fb
2 changed files with 118 additions and 110 deletions
106
index.html
106
index.html
|
|
@ -1,57 +1,57 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>File Transfer</title>
|
<title>File Transfer</title>
|
||||||
<style>
|
<style>
|
||||||
body {
|
body {
|
||||||
font-family: Arial, sans-serif;
|
font-family: Arial, sans-serif;
|
||||||
}
|
}
|
||||||
#file-tree {
|
#file-tree {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
}
|
}
|
||||||
ul {
|
ul {
|
||||||
list-style-type: none;
|
list-style-type: none;
|
||||||
}
|
}
|
||||||
.preview-modal {
|
.preview-modal {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
bottom: 0;
|
bottom: 0;
|
||||||
background: rgba(0, 0, 0, 0.8);
|
background: rgba(0, 0, 0, 0.8);
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
z-index: 1000;
|
z-index: 1000;
|
||||||
}
|
}
|
||||||
.preview-content {
|
.preview-content {
|
||||||
background: white;
|
background: white;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
max-width: 90%;
|
max-width: 90%;
|
||||||
max-height: 90%;
|
max-height: 90%;
|
||||||
overflow: auto;
|
overflow: auto;
|
||||||
}
|
}
|
||||||
img {
|
img {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
max-height: 400px;
|
max-height: 400px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>Upload Files</h1>
|
<h1>Upload Files</h1>
|
||||||
<form id="upload-form" action="/upload" method="post" enctype="multipart/form-data">
|
<form id="upload-form" action="/upload" method="post" enctype="multipart/form-data">
|
||||||
<input type="file" name="files" multiple required>
|
<input type="file" name="files" multiple required>
|
||||||
<button type="submit">Upload</button>
|
<button type="submit">Upload</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<h2>Directory Structure</h2>
|
<h2>Directory Structure</h2>
|
||||||
<div id="file-tree">
|
<div id="file-tree">
|
||||||
<ul id="file-list"></ul>
|
<ul id="file-list"></ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="script.js"></script>
|
<script src="script.js"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
122
server.js
122
server.js
|
|
@ -5,84 +5,92 @@ const fs = require('fs');
|
||||||
|
|
||||||
const app = express();
|
const app = express();
|
||||||
|
|
||||||
|
// configure storage for uploaded files
|
||||||
const storage = multer.diskStorage({
|
const storage = multer.diskStorage({
|
||||||
destination: (req, file, cb) => {
|
destination: (req, file, cb) => {
|
||||||
cb(null, 'uploads/');
|
cb(null, 'uploads/');
|
||||||
},
|
},
|
||||||
filename: (req, file, cb) => {
|
filename: (req, file, cb) => {
|
||||||
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
|
const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
|
||||||
cb(null, uniqueSuffix + '-' + file.originalname);
|
cb(null, uniqueSuffix + '-' + file.originalname);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const upload = multer({ storage: storage });
|
const upload = multer({ storage: storage });
|
||||||
|
|
||||||
|
// serve static files
|
||||||
app.use(express.static(__dirname));
|
app.use(express.static(__dirname));
|
||||||
|
|
||||||
|
// upload files
|
||||||
app.post('/upload', upload.array('files'), (req, res) => {
|
app.post('/upload', upload.array('files'), (req, res) => {
|
||||||
if (!req.files || req.files.length === 0) {
|
if (!req.files || req.files.length === 0) {
|
||||||
return res.status(400).send('No files were uploaded.');
|
return res.status(400).send('No files were uploaded.');
|
||||||
}
|
}
|
||||||
res.send(`Successfully uploaded ${req.files.length} file(s)!`);
|
res.send(`Successfully uploaded ${req.files.length} file(s)!`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// get list of uploaded files
|
||||||
app.get('/files', (req, res) => {
|
app.get('/files', (req, res) => {
|
||||||
const directoryPath = path.join(__dirname, 'uploads');
|
const directoryPath = path.join(__dirname, 'uploads');
|
||||||
fs.readdir(directoryPath, (err, files) => {
|
fs.readdir(directoryPath, (err, files) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return res.status(500).send('Unable to scan directory: ' + err);
|
return res.status(500).send('Unable to scan directory: ' + err);
|
||||||
}
|
}
|
||||||
const fileListPromises = files.map(file => {
|
const fileListPromises = files.map(file => {
|
||||||
return new Promise((resolve) => {
|
return new Promise((resolve) => {
|
||||||
const filePath = path.join(directoryPath, file);
|
const filePath = path.join(directoryPath, file);
|
||||||
fs.stat(filePath, (err, stats) => {
|
fs.stat(filePath, (err, stats) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return resolve(null);
|
return resolve(null);
|
||||||
}
|
}
|
||||||
resolve({
|
resolve({
|
||||||
name: file,
|
name: file,
|
||||||
path: `/uploads/${file}`,
|
path: `/uploads/${file}`,
|
||||||
size: stats.size,
|
size: stats.size,
|
||||||
date: stats.mtime
|
date: stats.mtime
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
Promise.all(fileListPromises).then(fileList => {
|
Promise.all(fileListPromises).then(fileList => {
|
||||||
res.json(fileList.filter(file => file !== null));
|
res.json(fileList.filter(file => file !== null));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// serve a specific file
|
||||||
app.get('/uploads/:filename', (req, res) => {
|
app.get('/uploads/:filename', (req, res) => {
|
||||||
const filePath = path.join(__dirname, 'uploads', req.params.filename);
|
const filePath = path.join(__dirname, 'uploads', req.params.filename);
|
||||||
res.sendFile(filePath, err => {
|
res.sendFile(filePath, err => {
|
||||||
if (err) {
|
if (err) {
|
||||||
res.status(404).send('File not found');
|
res.status(404).send('File not found');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// download a specific file
|
||||||
app.get('/download/:filename', (req, res) => {
|
app.get('/download/:filename', (req, res) => {
|
||||||
const filePath = path.join(__dirname, 'uploads', req.params.filename);
|
const filePath = path.join(__dirname, 'uploads', req.params.filename);
|
||||||
res.download(filePath, err => {
|
res.download(filePath, err => {
|
||||||
if (err) {
|
if (err) {
|
||||||
res.status(404).send('File not found');
|
res.status(404).send('File not found');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// delete a specific file
|
||||||
app.delete('/delete/:filename', (req, res) => {
|
app.delete('/delete/:filename', (req, res) => {
|
||||||
const filePath = path.join(__dirname, 'uploads', req.params.filename);
|
const filePath = path.join(__dirname, 'uploads', req.params.filename);
|
||||||
fs.unlink(filePath, err => {
|
fs.unlink(filePath, err => {
|
||||||
if (err) {
|
if (err) {
|
||||||
return res.status(404).send('File not found');
|
return res.status(404).send('File not found');
|
||||||
}
|
}
|
||||||
res.send('File deleted successfully');
|
res.send('File deleted successfully');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// start the server
|
||||||
app.listen(3000, () => {
|
app.listen(3000, () => {
|
||||||
console.log('Server is running on http://localhost:3000');
|
console.log('Server is running on http://localhost:3000');
|
||||||
});
|
});
|
||||||
Loading…
Add table
Reference in a new issue