From 82bc97ea3fabcd1f270d09ef2f0c75f33d0e08ca Mon Sep 17 00:00:00 2001 From: fatchan Date: Thu, 18 Apr 2019 05:40:22 +0000 Subject: [PATCH] way to delete banners --- controllers/forms.js | 37 +++++++++++++++++++++++++++++++++++ db/boards.js | 26 ++++++++++++------------ models/forms/deletebanners.js | 28 ++++++++++++++++++++++++++ models/forms/make-post.js | 2 +- models/forms/uploadbanners.js | 9 ++++++--- server.js | 2 -- static/css/style.css | 6 ++++++ views/includes/bannerform.pug | 18 +++++++++++------ 8 files changed, 104 insertions(+), 24 deletions(-) create mode 100644 models/forms/deletebanners.js diff --git a/controllers/forms.js b/controllers/forms.js index 842a5cbe..b9674815 100644 --- a/controllers/forms.js +++ b/controllers/forms.js @@ -10,6 +10,7 @@ const express = require('express') , removeBans = require(__dirname+'/../models/forms/removebans.js') , makePost = require(__dirname+'/../models/forms/make-post.js') , uploadBanners = require(__dirname+'/../models/forms/uploadbanners.js') + , deleteBanners = require(__dirname+'/../models/forms/deletebanners.js') , deletePosts = require(__dirname+'/../models/forms/delete-post.js') , spoilerPosts = require(__dirname+'/../models/forms/spoiler-post.js') , reportPosts = require(__dirname+'/../models/forms/report-post.js') @@ -182,6 +183,42 @@ router.post('/board/:board/addbanners', Boards.exists, banCheck, hasPerms, numbe }); +//delete banners +router.post('/board/:board/deletebanners', Boards.exists, banCheck, hasPerms, numberConverter, async (req, res, next) => { + + const errors = []; + + if (!req.body.checkedbanners || req.body.checkedbanners.length === 0 || req.body.checkedbanners.length > 10) { + errors.push('Must select 1-10 banners to delete'); + } + + if (errors.length > 0) { + return res.status(400).render('message', { + 'title': 'Bad request', + 'errors': errors, + 'redirect': `/${req.params.board}/manage` + }) + } + + for (let i = 0; i < req.body.checkedbanners.length; i++) { + if (!res.locals.board.banners.includes(req.body.checkedbanners[i])) { + return res.status(400).render('message', { + 'title': 'Bad request', + 'errors': 'Invalid banners selected', + 'redirect': `/${req.params.board}/manage` + }) + } + } + + try { + await deleteBanners(req, res, next); + } catch (err) { + console.error(err); + return next(err); + } + +}); + //report/delete/spoiler/ban router.post('/board/:board/actions', Boards.exists, banCheck, numberConverter, async (req, res, next) => { diff --git a/db/boards.js b/db/boards.js index ce0fd6e9..4157a550 100644 --- a/db/boards.js +++ b/db/boards.js @@ -1,8 +1,7 @@ 'use strict'; const Mongo = require(__dirname+'/db.js') - , db = Mongo.client.db('jschan') - , boardCache = new Map(); + , db = Mongo.client.db('jschan'); module.exports = { @@ -32,6 +31,18 @@ module.exports = { return db.collection('boards').deleteMany({}); }, + removeBanners: (board, filenames) => { + return db.collection('boards').updateOne( + { + '_id': board, + }, { + '$pullAll': { + 'banners': filenames + } + } + ); + }, + addBanners: (board, filenames) => { return db.collection('boards').updateOne( { @@ -46,18 +57,9 @@ module.exports = { ); }, - cache: async () => { - const boards = await module.exports.find(); - for (let i = 0; i < boards.length; i++) { - const board = boards[i]; - boardCache.set(board._id, board); - } - }, - exists: async (req, res, next) => { - //const board = await module.exports.findOne(req.params.board); - const board = boardCache.get(req.params.board); + const board = await module.exports.findOne(req.params.board); if (!board) { return res.status(404).render('404'); } diff --git a/models/forms/deletebanners.js b/models/forms/deletebanners.js new file mode 100644 index 00000000..d3717be8 --- /dev/null +++ b/models/forms/deletebanners.js @@ -0,0 +1,28 @@ +'use strict'; + +const uuidv4 = require('uuid/v4') + , path = require('path') + , util = require('util') + , fs = require('fs') + , unlink = util.promisify(fs.unlink) + , uploadDirectory = require(__dirname+'/../../helpers/uploadDirectory.js') + , Boards = require(__dirname+'/../../db/boards.js'); + +module.exports = async (req, res, next) => { + + const redirect = `/${req.params.board}/manage` + + await Promise.all(req.body.checkedbanners.map(async filename => { + unlink(uploadDirectory + filename); + })); + + // i dont think there is a way to get the number of array items removed with $pullAll + // so i cant return how many banners were deleted + await Boards.removeBanners(req.params.board, req.body.checkedbanners); + + return res.render('message', { + 'title': 'Success', + 'message': `Deleted banners.`, + 'redirect': redirect + }); +} diff --git a/models/forms/make-post.js b/models/forms/make-post.js index 0f06052d..3fcfdef0 100644 --- a/models/forms/make-post.js +++ b/models/forms/make-post.js @@ -152,7 +152,7 @@ console.log(file); //tripcode if (groups.tripcode) { const tripcode = await getTripCode(groups.tripcode); - name += `!!${tripcode}`; + name += `##${tripcode}`; } //capcode if (groups.capcode && hasPerms(req, res)) { diff --git a/models/forms/uploadbanners.js b/models/forms/uploadbanners.js index 9cc336ff..36f0ebc7 100644 --- a/models/forms/uploadbanners.js +++ b/models/forms/uploadbanners.js @@ -11,8 +11,7 @@ const uuidv4 = require('uuid/v4') module.exports = async (req, res, next, numFiles) => { - // check if this is responding to an existing thread - let redirect = `/${req.params.board}/manage` + const redirect = `/${req.params.board}/manage` // check all mime types befoer we try saving anything for (let i = 0; i < numFiles; i++) { @@ -57,6 +56,10 @@ module.exports = async (req, res, next, numFiles) => { await Boards.addBanners(req.params.board, filenames); - return res.redirect(redirect); + return res.render('message', { + 'title': 'Success', + 'message': `Uploaded ${filenames.length} banners.`, + 'redirect': redirect + }); } diff --git a/server.js b/server.js index a91533fc..0bf0192d 100644 --- a/server.js +++ b/server.js @@ -20,8 +20,6 @@ const express = require('express') // let db connect await Mongo.connect(); - const Boards = require(__dirname+'/db/boards.js'); - await Boards.cache(); // parse forms and allow file uploads app.use(bodyParser.urlencoded({extended: true})); diff --git a/static/css/style.css b/static/css/style.css index 25d4fa3e..544bddea 100644 --- a/static/css/style.css +++ b/static/css/style.css @@ -256,8 +256,14 @@ input textarea { color: white; } +.banner-check { + display: flex; + align-items: center; +} + .board-banner { margin: 10px; + max-width: 100%; } .board-description { diff --git a/views/includes/bannerform.pug b/views/includes/bannerform.pug index dca50ede..bd7b0e26 100644 --- a/views/includes/bannerform.pug +++ b/views/includes/bannerform.pug @@ -1,14 +1,20 @@ section.form-wrapper - label.toggle-label Upload Banners + label.toggle-label Add Banners input.toggle(type='checkbox') form.form-post.togglable(action=`/forms/board/${board._id}/addbanners`, enctype='multipart/form-data', method='POST') - input(type='hidden' name='_csrf' value=csrf) - span input#file(type='file', name='file' multiple) - input(type='submit', value='submit') - - + +section.form-wrapper + label.toggle-label Delete Banners + input.toggle(type='checkbox') + form.form-post.togglable(action=`/forms/board/${board._id}/deletebanners`, enctype='application/x-www-form-urlencoded', method='POST') + input(type='hidden' name='_csrf' value=csrf) + each banner in board.banners + label.banner-check + input(type='checkbox' name='checkedbanners[]' value=banner) + object.board-banner(data=`/img/${banner}` width='300' height='100') + input(type='submit', value='submit')