diff --git a/configs/nginx/nginx.example b/configs/nginx/nginx.example index 2fca7fbd..5632492c 100644 --- a/configs/nginx/nginx.example +++ b/configs/nginx/nginx.example @@ -126,8 +126,8 @@ server { location ~* \.json$ { expires 0; root /path/to/jschan/static/json; - try_files $uri =404; - #json doesnt hit backend if it doesnt exist yet. + try_files $uri @backend; + #some json files will build pages on-demand } # CSS diff --git a/configs/nginx/nginx_no_https.example b/configs/nginx/nginx_no_https.example index f45ee90f..74481f67 100644 --- a/configs/nginx/nginx_no_https.example +++ b/configs/nginx/nginx_no_https.example @@ -126,8 +126,8 @@ server { location ~* \.json$ { expires 0; root /path/to/jschan/static/json; - try_files $uri =404; - #json doesnt hit backend if it doesnt exist yet. + try_files $uri @backend; + #some json files will build pages on-demand } # CSS diff --git a/configs/nginx/snippets/jschan_routes.conf b/configs/nginx/snippets/jschan_routes.conf index 2dcf37f6..1204e5d3 100644 --- a/configs/nginx/snippets/jschan_routes.conf +++ b/configs/nginx/snippets/jschan_routes.conf @@ -87,8 +87,7 @@ location ~* \.json$ { testcookie off; expires 0; root /path/to/jschan/static/json; - try_files $uri =404; - #json doesnt hit backend if it doesnt exist yet. + try_files $uri @backend; } # CSS diff --git a/controllers/pages.js b/controllers/pages.js index dda6aba0..c90e1fb9 100644 --- a/controllers/pages.js +++ b/controllers/pages.js @@ -33,11 +33,12 @@ router.get('/news.html', news); //board list router.get('/boards.html', useSession, sessionRefresh, calcPerms, boardlist); +router.get('/boards.json', useSession, sessionRefresh, calcPerms, boardlist); //board pages -router.get('/:board/:page(1[0-9]{1,}|[2-9][0-9]{0,}|index).html', Boards.exists, paramConverter, board); //index -router.get('/:board/thread/:id([1-9][0-9]{0,}).html', Boards.exists, paramConverter, Posts.exists, thread); //thread view -router.get('/:board/catalog.html', Boards.exists, catalog); //catalog +router.get('/:board/:page(1[0-9]{1,}|[2-9][0-9]{0,}|index).(html|json)', Boards.exists, paramConverter, board); //index +router.get('/:board/thread/:id([1-9][0-9]{0,}).(html|json)', Boards.exists, paramConverter, 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, paramConverter, modlog); //daily log router.get('/:board/banners.html', Boards.exists, banners); //banners diff --git a/helpers/render.js b/helpers/render.js index 0e31a67d..d5f6b415 100644 --- a/helpers/render.js +++ b/helpers/render.js @@ -49,5 +49,5 @@ module.exports = async (htmlName, templateName, options, json=null) => { } await Promise.all([htmlPromise, jsonPromise]); await lock.unlock(); - return html; + return { html, json }; }; diff --git a/helpers/tasks.js b/helpers/tasks.js index 318c6bb7..651c9010 100644 --- a/helpers/tasks.js +++ b/helpers/tasks.js @@ -16,7 +16,7 @@ module.exports = { buildBanners: async (options) => { const label = `/${options.board._id}/banners.html`; const start = process.hrtime(); - const html = await render(label, 'banners.pug', options, { + const { html } = await render(label, 'banners.pug', options, { 'name': `/${options.board._id}/banners.json`, 'data': options.board.banners }); @@ -32,7 +32,7 @@ module.exports = { options.board = await Boards.findOne(options.board); } const threads = await Posts.getCatalog(options.board._id); - const html = await render(label, 'catalog.pug', { + const { html, json } = await render(label, 'catalog.pug', { ...options, threads, }, { @@ -41,7 +41,7 @@ module.exports = { }); const end = process.hrtime(start); debugLogs && console.log(timeDiffString(label, end)); - return html; + return { html, json }; }, buildThread: async (options) => { @@ -54,7 +54,7 @@ module.exports = { if (!thread) { return; //this thread may have been an OP that was deleted } - const html = await render(label, 'thread.pug', { + const { html, json } = await render(label, 'thread.pug', { ...options, thread, }, { @@ -63,7 +63,7 @@ module.exports = { }); const end = process.hrtime(start); debugLogs && console.log(timeDiffString(label, end)); - return html; + return { html, json }; }, buildBoard: async (options) => { @@ -73,7 +73,7 @@ module.exports = { if (!options.maxPage) { options.maxPage = Math.min(Math.ceil((await Posts.getPages(options.board._id)) / 10), Math.ceil(options.board.settings.threadLimit/10)); } - const html = await render(label, 'board.pug', { + const { html, json } = await render(label, 'board.pug', { ...options, threads, }, { @@ -82,7 +82,7 @@ module.exports = { }); const end = process.hrtime(start); debugLogs && console.log(timeDiffString(label, end)); - return html; + return { html, json }; }, //building multiple pages (for rebuilds) @@ -130,7 +130,7 @@ module.exports = { const label = '/news.html'; const start = process.hrtime(); const news = await News.find(); - const html = await render('news.html', 'news.pug', { + const { html } = await render('news.html', 'news.pug', { news }); const end = process.hrtime(start); @@ -155,7 +155,7 @@ module.exports = { if (!options.logs) { options.logs = await Modlogs.findBetweenDate(options.board, options.startDate, options.endDate); } - const html = await render(label, 'modlog.pug', { + const { html } = await render(label, 'modlog.pug', { ...options }); const end = process.hrtime(start); @@ -187,7 +187,7 @@ module.exports = { await Modlogs.deleteOld(options.board, pruneAfter); } } - const html = await render(label, 'modloglist.pug', { + const { html } = await render(label, 'modloglist.pug', { board: options.board, dates }); @@ -205,7 +205,7 @@ module.exports = { Files.activeContent(), //size ans number of files News.find(maxRecentNews), //some recent newsposts ]); - const html = await render('index.html', 'home.pug', { + const { html } = await render('index.html', 'home.pug', { totalStats, boards, fileStats, diff --git a/models/pages/board.js b/models/pages/board.js index 75995432..0b8bfec4 100644 --- a/models/pages/board.js +++ b/models/pages/board.js @@ -1,26 +1,31 @@ 'use strict'; const Posts = require(__dirname+'/../../db/posts.js') + , buildQueue = require(__dirname+'/../../queue.js') , { buildBoard } = require(__dirname+'/../../helpers/tasks.js'); module.exports = async (req, res, next) => { const page = req.params.page === 'index' ? 1 : Number(req.params.page); - let html; + let html, json; try { const maxPage = Math.min(Math.ceil((await Posts.getPages(req.params.board)) / 10), Math.ceil(res.locals.board.settings.threadLimit/10)) || 1; if (page > maxPage) { return next(); } - html = await buildBoard({ + ({ html, json } = await buildBoard({ board: res.locals.board, page, maxPage - }); + })); } catch (err) { return next(err); } - return res.send(html); + if (req.path.endsWith('.json')) { + return res.json(json); + } else { + return res.send(html); + } } diff --git a/models/pages/boardlist.js b/models/pages/boardlist.js index d638d3a2..8d84f760 100644 --- a/models/pages/boardlist.js +++ b/models/pages/boardlist.js @@ -87,15 +87,25 @@ module.exports = async (req, res, next) => { } res - .set('Cache-Control', `${isGlobalStaff ? 'private' : 'public'}, max-age=60`) - .render('boardlist', { - localBoards, - webringBoards, - page, - maxPage, - query: req.query, - search, - queryString, - }); + .set('Cache-Control', `${isGlobalStaff ? 'private' : 'public'}, max-age=60`); + + if (req.path === '/boards.json') { + res.json({ + localBoards, + webringBoards, + page, + maxPage, + }); + } else { + res.render('boardlist', { + localBoards, + webringBoards, + page, + maxPage, + query: req.query, + search, + queryString, + }); + } } diff --git a/models/pages/catalog.js b/models/pages/catalog.js index f5816218..6dffe9e5 100644 --- a/models/pages/catalog.js +++ b/models/pages/catalog.js @@ -5,12 +5,16 @@ const { buildCatalog } = require(__dirname+'/../../helpers/tasks.js'); module.exports = async (req, res, next) => { let html; - try { - html = await buildCatalog({ board: res.locals.board }); - } catch (err) { - return next(err); - } + try { + ({ html } = await buildCatalog({ 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); + } } diff --git a/models/pages/thread.js b/models/pages/thread.js index 817e31d4..a1de3dcb 100644 --- a/models/pages/thread.js +++ b/models/pages/thread.js @@ -4,16 +4,20 @@ const { buildThread } = require(__dirname+'/../../helpers/tasks.js'); module.exports = async (req, res, next) => { - let html; - try { - html = await buildThread({ + let html, json; + try { + ({ html, json } = await buildThread({ threadId: res.locals.thread.postId, board: res.locals.board - }); - } catch (err) { - return next(err); + })); + } catch (err) { + return next(err); } - return res.send(html); + if (req.path.endsWith('.json')) { + return res.json(json); + } else { + return res.send(html); + } }