Fix problems with server; add index.html

Confirm that file upload works as intended
This commit is contained in:
Robbie Antenesse 2018-12-26 15:03:21 -07:00
parent 01d972dc5f
commit 464535b6ad
4 changed files with 116 additions and 17 deletions

View File

@ -2,16 +2,21 @@
"name": "little-library",
"version": "0.0.0",
"description": "A digital give-a-book, take-a-book library for ebooks",
"main": "src/index.js",
"main": "server.js",
"scripts": {
"start": "node server.js"
},
"repository": "https://github.com/Alamantus/little-library.git",
"author": "Robbie Antenesse <dev@alamantus.com>",
"license": "MIT",
"dependencies": {
"body-parser": "^1.18.3",
"bulma": "^0.7.2",
"express": "^4.16.4",
"express-fileupload": "^1.0.0",
"filenamify": "^2.1.0",
"helmet": "^3.15.0",
"jquery": "^3.3.1",
"slugify": "^1.3.4",
"socket.io": "^2.2.0",
"socket.io-client": "^2.2.0",

47
public/index.html Normal file
View File

@ -0,0 +1,47 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Little Library</title>
<meta name="description" content="The HTML5 Herald">
<link rel="stylesheet" href="./css/bulma.min.css?v=1.0">
<link rel="stylesheet" href="./css/styles.css?v=1.0">
<script src="./js/jquery.min.js"></script>
<script src="./js/socket.io.js"></script>
</head>
<body>
<form action="./give" method="post" enctype="multipart/form-data">
<label class="label">Book Title:
<input type="text" class="input" name="title" id="title">
</label>
<label class="label">Book Author:
<input type="text" class="input" name="author" id="author">
</label>
<label class="label">Why you're sharing it:<br>
<textarea class="textarea" name="summary" id="summary"></textarea>
</label>
<div class="file is-boxed">
<label class="file-label">
<input class="file-input" type="file" name="book" id="book" accept="{{allowedFormats}}">
<span class="file-cta">
<span class="file-icon">
<i class="fas fa-upload"></i>
</span>
<span class="file-label">
Choose a Book File <code>{{allowedFormats}}</code> ({{maxFileSize}} maximum)
</span>
</span>
</label>
</div>
<input class="button" type="submit" value="Give Book" name="submit">
</form>
<script src="./js/little-library.js"></script>
</body>
</html>

View File

@ -33,21 +33,36 @@ function Server () {
},
}));
this.server.use(express.static(path.join(__dirname, './public/')));
this.server.use(express.static(path.join(__dirname, './public/files/')));
this.server.use(express.static(path.join(__dirname, './public/history/')));
this.server.use('/js', express.static(path.join(__dirname, './public/js/')));
this.server.use('/js', express.static(path.resolve('./node_modules/jquery/dist/')));
this.server.use('/js', express.static(path.resolve('./node_modules/socket.io-client/dist/')));
this.server.use('/css', express.static(path.resolve('./node_modules/bulma/css/')));
this.server.use('/css', express.static(path.join(__dirname, './public/css/')));
this.server.get('/', (req, res) => {
const page = path.join(__dirname, './public/index.html');
res.sendFile(page);
const html = this.fillTemplate('./public/index.html');
if (html) {
res.send(html);
} else {
res.send('Something went wrong!');
}
});
this.server.post('/give', (req, res) => {
console.log(req.body);
console.log(req.files);
let success = false;
if (Object.keys(req.files).length > 0 && req.body.hasOwnProperty('title') && req.body.hasOwnProperty('summary')) {
const { book } = req.files;
const { title, author, summary } = req.body;
const fileType = book.name.substr(book.name.lastIndexOf('.'));
success = this.addBook({ book, title, author, summary, fileType });
success = this.addBook({ book, title, author, summary, fileType }, () => {
res.send()
});
}
res.send(success);
@ -72,6 +87,24 @@ function Server () {
});
}
Server.prototype.fillTemplate = function (file, templateVars = {}) {
const page = path.join(__dirname, file);
const data = fs.readFileSync(page, 'utf8');
if (data) {
let filledTemplate = data.replace(/\{\{allowedFormats\}\}/g, settings.allowedFormats.join(','))
.replace(/\{\{maxFileSize\}\}/g, (settings.maxFileSize > 0 ? settings.maxFileSize + 'MB' : 'no'));
for (let templateVar in templateVars) {
const regExp = new RegExp('\{\{' + templateVar + '\}\}', 'g')
filledTemplate = filledTemplate.replace(regexp, templateVars[templateVar]);
}
return filledTemplate;
}
return data;
}
Server.prototype.broadcastVisitors = function () {
const numberConnected = this.io.of('/').clients().connected.length;
this.io.emit('connected', numberConnected);
@ -95,23 +128,24 @@ Server.prototype.addBook = function (uploadData = {}) {
fileType: book.name.substr(book.name.lastIndexOf('.')),
}
let success = false;
book.mv(unusedFilename.sync(path.resolve(bookPath, bookData.fileType)), function (err) {
if (!err) {
fs.writeFileSync(unusedFilename.sync(path.resolve(bookPath, '.json')), JSON.stringify(bookData));
success = true;
} else {
console.log('moving the book');
const bookFilePath = unusedFilename.sync(path.resolve(bookPath + bookData.fileType));
return book.mv(bookFilePath, function (err) {
if (err) {
success = err;
console.log(err);
} else {
const bookDataPath = unusedFilename.sync(path.resolve(bookPath + '.json'));
fs.writeFileSync(bookDataPath, JSON.stringify(bookData));
console.log('uploaded ' + bookData.title + ' to ' + bookFilePath + ', and saved metadata to ' + bookDataPath);
}
});
return success;
}
Server.prototype.takeBook = function (bookId, socketId) {
return this.checkId(bookId, (bookPath, bookDataPath, bookData) => {
const bookName = filenamify(bookData.title);
const newFileName = unusedFilename.sync(path.resolve(this.fileLocation, bookName, bookData.fileType));
const newFileName = unusedFilename.sync(path.resolve(this.fileLocation, bookName + bookData.fileType));
bookData.fileName = newFileName;
fs.renameSync(bookPath, newFileName);
fs.writeFileSync(bookDataPath, JSON.stringify(bookData));
@ -121,12 +155,12 @@ Server.prototype.takeBook = function (bookId, socketId) {
}
Server.prototype.checkId = function (bookId, callback = () => {}) {
const bookDataPath = path.resolve(this.fileLocation, bookId, '.json');
const bookDataPath = path.resolve(this.fileLocation, bookId + '.json');
if (fs.existsSync(bookDataPath)) {
const bookDataRaw = fs.readFileSync(bookDataPath);
if (bookDataRaw) {
const bookData = JSON.parse(bookDataRaw);
const bookPath = path.resolve(this.fileLocation, bookId, bookData.fileType);
const bookPath = path.resolve(this.fileLocation, bookId + bookData.fileType);
if (fs.existsSync(bookPath)) {
return callback(bookPath, bookDataPath, bookData);
}
@ -141,7 +175,7 @@ Server.prototype.deleteBooks = function (socketId) {
if (data.socketId === socketId) {
this.checkId(data.bookId, (bookPath, bookDataPath) => {
fs.unlinkSync(bookPath);
fs.renameSync(bookDataPath, path.resolve(this.historyLocation, data.bookId, '.json'));
fs.renameSync(bookDataPath, path.resolve(this.historyLocation, data.bookId + '.json'));
});
}
});
@ -155,3 +189,6 @@ Server.prototype.uuid4 = function () {
return v.toString(16);
});
}
const server = new Server();
server.start();

View File

@ -73,6 +73,11 @@ body-parser@1.18.3, body-parser@^1.18.3:
raw-body "2.3.3"
type-is "~1.6.16"
bulma@^0.7.2:
version "0.7.2"
resolved "https://registry.yarnpkg.com/bulma/-/bulma-0.7.2.tgz#8e944377b74c7926558830d38d8e19eaf49f5fb6"
integrity sha512-6JHEu8U/1xsyOst/El5ImLcZIiE2JFXgvrz8GGWbnDLwTNRPJzdAM0aoUM1Ns0avALcVb6KZz9NhzmU53dGDcQ==
busboy@^0.2.14:
version "0.2.14"
resolved "https://registry.yarnpkg.com/busboy/-/busboy-0.2.14.tgz#6c2a622efcf47c57bbbe1e2a9c37ad36c7925453"
@ -481,6 +486,11 @@ isarray@2.0.1:
resolved "https://registry.yarnpkg.com/isarray/-/isarray-2.0.1.tgz#a37d94ed9cda2d59865c9f76fe596ee1f338741e"
integrity sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4=
jquery@^3.3.1:
version "3.3.1"
resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.3.1.tgz#958ce29e81c9790f31be7792df5d4d95fc57fbca"
integrity sha512-Ubldcmxp5np52/ENotGxlLe6aGMvmF4R8S6tZjsP6Knsaxd/xp3Zrh50cG93lR6nPXyUFwzN3ZSOQI0wRJNdGg==
md5@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9"