/** @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;