This repository has been archived on 2021-10-31. You can view files and clone it, but cannot push or open issues or pull requests.
SA3/hw5/Claudio_Maggioni/routes/favourites/router.js

172 lines
4.1 KiB
JavaScript

/** @module root/router */
'use strict';
// vim: set ts=2 sw=2 et tw=80:
const fs = require('fs');
const express = require('express');
const router = express.Router();
let id = 1;
function nextId(favs) {
while (favs.some((newId => e => e._id == newId)(++id)));
return id;
}
function createFav(req, res) {
if (!req.body.name || !req.body.dataURL) {
res.writeHead(400, { 'Content-Type': 'text/plain' });
res.end('Bad create form parameters');
return;
}
const favourite = {
_id: req.body._id ? req.body._id : nextId(req.app.locals.favourites),
name: req.body.name,
dataURL: req.body.dataURL,
bookmarked: req.body.bookmarked,
};
req.app.locals.favourites.push(favourite);
req.app.locals.writeFavs(() => {
res.status = 201;
renderFav(req, res, favourite, false);
});
}
router.post('/', createFav);
function renderFav(req, res, favs, list = true) {
if (req.accepts('html')) {
let ctx;
if (list) {
const f = [];
for (const e of favs) {
f.push(Object.assign({
b: e.bookmarked === 'true' || e.bookmarked === true
}, e));
}
ctx = {favs: f};
} else {
ctx = Object.assign({
b: favs.bookmarked === 'true' || favs.bookmarked === true
}, favs);
}
res.render(list ? 'favourites.dust' : 'favourite.dust', ctx);
} else if (req.accepts('json')) {
res.json(favs);
} else {
res.writeHead(406);
res.end();
}
}
router.get('/', (req, res) => {
renderFav(req, res, req.app.locals.favourites);
});
router.get('/search', (req, res) => {
const filtered = req.app.locals.favourites.filter(e => {
for (const k in req.query) {
if (k != 'dataURL' && k != '_method' && req.query[k] != e[k]) {
return false;
}
}
return true;
});
renderFav(req, res, filtered);
});
router.get('/:id', (req, res) => {
const fav = req.app.locals.favourites
.filter(e => e._id == req.params.id)[0];
if (fav) {
renderFav(req, res, fav, false);
} else {
res.writeHead(404, {'Content-Type': 'text/plain'});
res.end('Not found');
}
});
function handleUpdate(partial = false) {
return (req, res) => {
const edit = req.app.locals.favourites
.find(e => e._id == req.params.id);
if (!edit) {
createFav(req, res);
} else {
for (const key of ['dataURL', 'name']) {
if (req.body[key]) {
edit[key] = req.body[key];
} else if (!partial) {
res.writeHead(400, { 'Content-Type': 'text/plain' });
res.end('Bad PUT form parameters');
return;
}
}
if (req.body.bookmarked !== undefined) {
edit.bookmarked = req.body.bookmarked;
}
req.app.locals.writeFavs(() => {
res.status = 200;
renderFav(req, res, edit, false);
});
}
};
}
router.put('/:id', handleUpdate());
router.patch('/:id', handleUpdate(true));
router.delete('/:id', (req, res) => {
let idx = -1;
for (let i = 0; i < req.app.locals.favourites.length; i++) {
if (req.app.locals.favourites[i]._id == req.params.id) {
idx = i;
break;
}
}
if (idx == -1) {
res.writeHead(404, { 'Content-Type': 'text/plain' });
res.end('Favourite not found');
return;
} else {
req.app.locals.favourites.splice(idx, 1);
req.app.locals.writeFavs(() => {
res.format({
json: () => res.writeHead(204),
html: () => res.writeHead(302, { 'Location': '/favorites' })
});
res.end();
});
}
});
router.put('/:id/bookmarked', (req, res) => {
const edit = req.app.locals.favourites
.find(e => e._id == req.params.id);
if (!edit) {
res.writeHead(404, { 'Content-Type': 'text/plain' });
res.end('Favourite to bookmark not found');
} else if (!req.body.bookmarked) {
res.writeHead(400, { 'Content-Type': 'text/plain' });
res.end('Bad PUT bookmark form parameters');
} else {
edit.bookmarked = req.body.bookmarked;
req.app.locals.writeFavs(() => {
res.status = 200;
renderFav(req, res, edit, false);
});
}
});
/** router for /root */
module.exports = router;