Merge branch '491-more-public-json' into develop

indiachan-spamvector
Thomas Lynch 2 years ago
commit 3fe783cf3b
  1. 12
      controllers/pages.js
  2. 4
      db/modlogs.js
  3. 31
      lib/build/render.js
  4. 94
      lib/build/tasks.js
  5. 8
      models/forms/changeboardsettings.js
  6. 5
      models/forms/changeglobalsettings.js
  7. 5
      models/forms/deletecustompage.js
  8. 10
      models/pages/banners.js
  9. 16
      models/pages/boardsettings.js
  10. 12
      models/pages/custompage.js
  11. 16
      models/pages/globalsettings.js
  12. 2
      models/pages/index.js
  13. 12
      models/pages/modlog.js
  14. 10
      models/pages/modloglist.js

@ -22,7 +22,7 @@ const express = require('express')
, { globalManageSettings, globalManageReports, globalManageBans, globalManageBoards, editNews, editAccount, editRole,
globalManageRecent, globalManageAccounts, globalManageNews, globalManageLogs, globalManageRoles } = require(__dirname+'/../models/pages/globalmanage/')
, { changePassword, blockBypass, home, register, login, create, myPermissions, sessions,
board, catalog, banners, randombanner, news, captchaPage, overboard, overboardCatalog,
board, catalog, banners, boardSettings, globalSettings, randombanner, news, captchaPage, overboard, overboardCatalog,
captcha, thread, modlog, modloglist, account, boardlist, customPage, csrfPage } = require(__dirname+'/../models/pages/')
, threadParamConverter = paramConverter({ processThreadIdParam: true })
, logParamConverter = paramConverter({ processDateParam: true })
@ -47,10 +47,12 @@ router.get('/catalog.(html|json)', overboardCatalog); //overboard catalog view
router.get('/:board/:page(1[0-9]{1,}|[2-9][0-9]{0,}|index).(html|json)', Boards.exists, board); //index
router.get('/:board/thread/:id([1-9][0-9]{0,}).(html|json)', Boards.exists, threadParamConverter, Posts.exists, thread); //thread view
router.get('/:board/catalog.(html|json)', Boards.exists, catalog); //catalog
router.get('/:board/logs.html', Boards.exists, modloglist);//modlog list
router.get('/:board/logs/:date(\\d{2}-\\d{2}-\\d{4}).html', Boards.exists, logParamConverter, modlog); //daily log
router.get('/:board/custompage/:page.html', Boards.exists, customPage); //board custom page
router.get('/:board/banners.html', Boards.exists, banners); //banners
router.get('/:board/logs.(html|json)', Boards.exists, modloglist);//modlog list
router.get('/:board/logs/:date(\\d{2}-\\d{2}-\\d{4}).(html|json)', Boards.exists, logParamConverter, modlog); //daily log
router.get('/:board/custompage/:page.(html|json)', Boards.exists, customPage); //board custom page
router.get('/:board/banners.(html|json)', Boards.exists, banners); //banners
router.get('/:board/settings.json', Boards.exists, boardSettings); //public board settings
router.get('/settings.json', globalSettings); //public global settings
router.get('/randombanner', randombanner); //random banner
//board manage pages

@ -79,6 +79,10 @@ module.exports = {
'$lte': endDate
},
'board': board._id
}, {
projection: {
'ip': 0,
}
}).sort({
'_id': -1
}).toArray();

@ -44,18 +44,33 @@ const updateLocals = () => {
updateLocals();
addCallback('config', updateLocals);
module.exports = async (htmlName, templateName, options, json=null) => {
const html = pug.renderFile(`${templateDirectory}${templateName}`, {
...options,
...renderLocals,
});
const lock = await redlock.lock(`locks:${htmlName}`, lockWait);
const htmlPromise = outputFile(`${uploadDirectory}/html/${htmlName}`, html);
let jsonPromise;
module.exports = async (htmlName=null, templateName=null, options=null, json=null) => {
//generate html if applicable
let html = null;
if (templateName !== null) {
html = pug.renderFile(`${templateDirectory}${templateName}`, {
...options,
...renderLocals,
});
}
//lock to prevent concurrent disk write
const lock = await redlock.lock(`locks:${htmlName || json.name}`, lockWait);
//write html/jsons
let htmlPromise, jsonPromise;
if (html !== null) {
htmlPromise= outputFile(`${uploadDirectory}/html/${htmlName}`, html);
}
if (json !== null) {
jsonPromise = outputFile(`${uploadDirectory}/json/${json.name}`, JSON.stringify(json.data));
}
await Promise.all([htmlPromise, jsonPromise]);
//unlock after finishing
await lock.unlock();
return { html, json: json ? json.data : null };
};

@ -28,13 +28,68 @@ module.exports = {
const label = `/${options.board._id}/banners.html`;
const start = process.hrtime();
options.managePage = 'assets.html';
const { html } = await render(label, 'banners.pug', options, {
const { html, json } = await render(label, 'banners.pug', options, {
'name': `/${options.board._id}/banners.json`,
'data': options.board.banners
});
const end = process.hrtime(start);
debugLogs && console.log(timeDiffString(label, end));
return html;
return { html, json };
},
buildBoardSettings: async (options) => {
const label = `/${options.board._id}/settings.json`;
const start = process.hrtime();
const customPages = await CustomPages.find(options.board._id);
const bs = options.board.settings;
const projectedSettings = {
customPages: customPages.map(p => p.page), //list of custompage names
announcement: bs.announcement,
allowedFileTypes: bs.allowedFileTypes,
maxFiles: bs.maxFiles,
captchaMode: bs.captchaMode,
forceAnon: bs.forceAnon,
sageOnlyEmail: bs.sageOnlyEmail,
customFlags: bs.customFlags,
forceThreadMessage: bs.forceThreadMessage,
forceThreadFile: bs.forceThreadFile,
forceThreadSubject: bs.forceThreadSubject,
disableReplySubject: bs.disableReplySubject,
minThreadMessageLength: bs.minThreadMessageLength,
minReplyMessageLength: bs.minReplyMessageLength,
maxThreadMessageLength: bs.maxThreadMessageLength,
maxReplyMessageLength: bs.maxReplyMessageLength,
defaultName: bs.defaultName,
};
const { json } = await render(null, null, null, {
'name': `/${options.board._id}/settings.json`,
'data': projectedSettings
});
const end = process.hrtime(start);
debugLogs && console.log(timeDiffString(label, end));
return json;
},
buildGlobalSettings: async () => {
const label = '/settings.json';
const start = process.hrtime();
const { captchaOptions: co } = config.get;
const projectedSettings = {
captchaOptions: {
type: co.type,
grid: {
size: co.grid.size,
question: co.grid.question,
}
}
};
const { json } = await render(null, null, null, {
name: '/settings.json',
data: projectedSettings
});
const end = process.hrtime(start);
debugLogs && console.log(timeDiffString(label, end));
return json;
},
buildCatalog: async (options) => {
@ -162,7 +217,7 @@ module.exports = {
if (!options.customPage) {
const customPage = await CustomPages.findOne(options.board._id || options.board, options.page);
if (!customPage) {
return;
return {};
}
options.customPage = customPage;
}
@ -170,12 +225,15 @@ module.exports = {
options.board = await Boards.findOne(options.board);
}
options.managePage = 'custompages.html';
const { html } = await render(label, 'custompage.pug', {
const { html, json } = await render(label, 'custompage.pug', {
...options,
}, {
name: `/${options.board._id}/custompage/${options.page}.json`,
data: options.customPage
});
const end = process.hrtime(start);
debugLogs && console.log(timeDiffString(label, end));
return html;
return { html, json };
},
buildModLog: async (options) => {
@ -196,12 +254,22 @@ module.exports = {
options.logs = await Modlogs.findBetweenDate(options.board, options.startDate, options.endDate);
}
options.managePage = 'logs.html';
const { html } = await render(label, 'modlog.pug', {
const projectedLogs = options.logs.map(l => {
const pl = l;
if (pl.showUser === false) {
pl.user = null;
}
return pl;
});
const { html, json } = await render(label, 'modlog.pug', {
...options
}, {
'name': `/${options.board._id}/logs/${month}-${day}-${year}.json`,
'data': projectedLogs,
});
const end = process.hrtime(start);
debugLogs && console.log(timeDiffString(label, end));
return html;
return { html, json };
},
buildModLogList: async (options) => {
@ -224,19 +292,25 @@ module.exports = {
});
if (pruneLogs.length > 0) {
await Promise.all(pruneLogs.map(log => {
remove(`${uploadDirectory}/html/${options.board._id}/logs/${log}.html`);
return Promise.all([
remove(`${uploadDirectory}/html/${options.board._id}/logs/${log}.html`),
remove(`${uploadDirectory}/json/${options.board._id}/logs/${log}.json`),
]);
}));
await Modlogs.deleteOld(options.board._id, pruneAfter);
}
}
const { html } = await render(label, 'modloglist.pug', {
const { html, json } = await render(label, 'modloglist.pug', {
board: options.board,
dates,
managePage: 'logs.html',
}, {
'name': `/${options.board._id}/logs.json`,
'data': dates,
});
const end = process.hrtime(start);
debugLogs && console.log(timeDiffString(label, end));
return html;
return { html, json };
},
buildHomepage: async () => {

@ -213,6 +213,14 @@ module.exports = async (req, res) => {
});
}
//updates board/settings.json
buildQueue.push({
'task': 'buildBoardSettings',
'options': {
'board': res.locals.board,
}
});
//finish the promises in parallel e.g. removing files
if (promises.length > 0) {
await Promise.all(promises);

@ -363,7 +363,10 @@ module.exports = async (req, res) => {
});
}
debugLogs && console.log('global settings changed');
//updates /settings.json
buildQueue.push({
'task': 'buildGlobalSettings',
});
return dynamicResponse(req, res, 200, 'message', {
'title': 'Success',

@ -18,7 +18,10 @@ module.exports = async (req, res) => {
}
await Promise.all(req.body.checkedcustompages.map(page => {
remove(`${uploadDirectory}/html/${req.params.board}/custompage/${page}.html`);
return Promise.all([
remove(`${uploadDirectory}/html/${req.params.board}/custompage/${page}.html`),
remove(`${uploadDirectory}/json/${req.params.board}/custompage/${page}.json`),
]);
}));
return dynamicResponse(req, res, 200, 'message', {

@ -4,13 +4,17 @@ const { buildBanners } = require(__dirname+'/../../lib/build/tasks.js');
module.exports = async (req, res, next) => {
let html;
let html, json;
try {
html = await buildBanners({ board: res.locals.board });
({ html, json } = await buildBanners({ board: res.locals.board }));
} catch (err) {
return next(err);
}
return res.send(html);
if (req.path.endsWith('.json')) {
return res.json(json);
} else {
return res.send(html);
}
};

@ -0,0 +1,16 @@
'use strict';
const { buildBoardSettings } = require(__dirname+'/../../lib/build/tasks.js');
module.exports = async (req, res, next) => {
let json;
try {
json = await buildBoardSettings({ board: res.locals.board });
} catch (err) {
return next(err);
}
return res.json(json);
};

@ -4,17 +4,21 @@ const { buildCustomPage } = require(__dirname+'/../../lib/build/tasks.js');
module.exports = async (req, res, next) => {
let html;
let html, json;
try {
html = await buildCustomPage({ ...req.params, board: res.locals.board });
({ html, json } = await buildCustomPage({ ...req.params, board: res.locals.board }));
} catch (err) {
return next(err);
}
if (!html) {
return res.status(404).render('404');
return next();
}
return res.send(html);
if (req.path.endsWith('.json')) {
return res.json(json);
} else {
return res.send(html);
}
};

@ -0,0 +1,16 @@
'use strict';
const { buildGlobalSettings } = require(__dirname+'/../../lib/build/tasks.js');
module.exports = async (req, res, next) => {
let json;
try {
json = await buildGlobalSettings();
} catch (err) {
return next(err);
}
return res.json(json);
};

@ -13,6 +13,8 @@ module.exports = {
board: require(__dirname+'/board.js'),
catalog: require(__dirname+'/catalog.js'),
banners: require(__dirname+'/banners.js'),
boardSettings: require(__dirname+'/boardsettings.js'),
globalSettings: require(__dirname+'/globalsettings.js'),
customPage: require(__dirname+'/custompage.js'),
csrfPage: require(__dirname+'/csrf.js'),
randombanner: require(__dirname+'/randombanner.js'),

@ -13,22 +13,26 @@ module.exports = async (req, res, next) => {
const { year, month, day } = res.locals.date;
const endDate = new Date(Date.UTC(year, month, day, 23, 59, 59, 999));
let html;
let html, json;
try {
const logs = await Modlogs.findBetweenDate(res.locals.board, startDate, endDate);
if (!logs || logs.length === 0) {
return next();
}
html = await buildModLog({
({ html, json } = await buildModLog({
board: res.locals.board,
startDate,
endDate,
logs
});
}));
} catch (err) {
return next(err);
}
return res.send(html);
if (req.path.endsWith('.json')) {
return res.json(json);
} else {
return res.send(html);
}
};

@ -4,13 +4,17 @@ const { buildModLogList } = require(__dirname+'/../../lib/build/tasks.js');
module.exports = async (req, res, next) => {
let html;
let html, json;
try {
html = await buildModLogList({ board: res.locals.board });
({ html, json } = await buildModLogList({ board: res.locals.board }));
} catch (err) {
return next(err);
}
return res.send(html);
if (req.path.endsWith('.json')) {
return res.json(json);
} else {
return res.send(html);
}
};

Loading…
Cancel
Save