var _ = require('lodash') var db = require('../db') var util = require('../util/util') var upload = require('../util/upload') var bucky = module.exports = { /* INDEX */ ensureLatestThreads: function (req, res, next){ db.getLatestThreads().then(function(threads){ res.threads = threads res.threads_ids = res.threads.pluck("id").sort() res.keywords = _.uniq(res.threads.pluck("keyword")) next() }) }, ensureCommentCountsForThreads: function (req, res, next){ db.getCommentCounts(res.threads_ids).then(function(counts){ var lookup = {} counts.forEach(function(c){ lookup[c.thread] = c }) res.threads.forEach(function(thread){ if (lookup[thread.id]) { thread.set("comment_count", lookup[thread.id].count) } }) next() }) }, ensureFileCountsForThreads: function (req, res, next){ db.getFileCounts(res.threads_ids).then(function(counts){ var lookup = {} counts.forEach(function(c){ lookup[c.thread] = c }) res.threads.forEach(function(t){ var c = lookup[t.id] t.set("file_count", c ? c.count : 0) }) next() }) }, ensureKeywordsForThreads: function (req, res, next){ db.getKeywords(res.keywords).then(function(keywords){ var lookup = {} keywords.forEach(function(k){ lookup[k.get('keyword')] = k }) res.threads.forEach(function(t){ var kw = t.get('keyword') if (! kw) return var k = lookup[kw] if (! k) return if (! t.get("color")) { t.set("color", k.get("color")) } }) next() }) }, ensureHootbox: function (req, res, next){ db.getCommentsForThread(1, 15, 0, "desc").then(function(hootbox){ res.hootbox = hootbox next() }) }, ensureLastlog: function (req, res, next){ db.getLastlog(6).then(function(lastlog){ res.lastlog = lastlog next() }) }, createThread: function (req, res, next){ if (! req.body.title || ! req.body.title.length) { res.json({ error: "no title" }) return } var data = { title: req.body.title, keyword: req.body.keyword, username: req.user.get('username'), createdate: util.now(), lastmodified: util.now(), size: 0, private: false, color: req.body.color, viewed: 0, revision: 0, } db.createThread(data).then(function(thread){ res.thread = thread next() }) }, /* DETAILS */ ensureThread: function (req, res, next){ var id = req.params.id.replace(/\D/g, "") if (! id) { return res.sendStatus(404) } db.getThread(id).then(function(thread){ if (thread) { res.thread = thread next() } else { res.sendStatus(404) } }) }, prepareThread: function (req, res, next){ var thread = res.thread if (thread) { var settings try { settings = JSON.parse(thread.get('settings') || '{}') } catch(e) { settings = {} } res.thread.set("settings", settings) res.thread.set("display", res.thread.get("display").toString()) res.thread.set("allowed", res.thread.get("allowed").toString()) } next() }, ensureCommentThread: function (req, res, next){ if (! res.comment) { return res.sendStatus(404) } var id = res.comment.get('thread') if (! id) { return res.sendStatus(404) } db.getThread(id).then(function(thread){ if (thread) { res.thread = thread next() } else { res.sendStatus(404) } }) }, ensureKeywordForThread: function (req, res, next){ var keyword = res.thread.get('keyword') if (! keyword) return next() db.getKeyword(keyword).then(function(keyword){ res.keyword = keyword if (keyword) { keyword.set("threads", keyword.get("threads").toString()) keyword.set("ops", keyword.get("ops").toString()) keyword.set("display", keyword.get("display").toString()) } next() }) }, ensureCommentsForThread: function (req, res, next){ db.getCommentsForThread(res.thread.get('id')).then(function(comments){ res.comments = comments next() }) }, ensureFilesForThread: function (req, res, next){ db.getFilesForThread(res.thread.get('id')).then(function(files){ res.files = files next() }) }, bumpViewCount: function(req, res, next) { res.thread.set('viewed', res.thread.get('viewed') + 1) res.thread.save().then( () => next() ) }, bumpThreadRevisions: function (req, res, next){ res.thread.set('revision', res.thread.get('revision')+1) res.thread.set('lastmodified', util.now()) res.thread.save().then( () => next() ) }, /* KEYWORDS */ ensureKeyword: function (req, res, next){ var keyword = req.params.keyword if (! keyword) { return res.sendStatus(404) } db.getKeyword(keyword).then(function(k){ if (! k) { return res.sendStatus(404) } res.keyword = k next() }) }, ensureKeywords: function (req, res, next){ db.getKeywords().then(function(k){ if (! k) { return res.sendStatus(404) } res.keywords = k next() }) }, ensureThreadsForKeyword: function (req, res, next){ var keyword = req.params.keyword if (! keyword) { res.sendStatus(404) } db.getThreadsForKeyword(keyword).then(function(threads){ res.threads = threads res.threads_ids = res.threads.pluck("id").sort() res.keywords = _.uniq(res.threads.pluck("keyword")) next() }) }, /* POSTING */ verifyFilesOrComment: function (req, res, next){ var hasComment = req.body.comment && req.body.comment.length var hasFile = req.files && req.files.length if (! hasComment && ! hasFile) { console.log(">>> no files or comment") return res.sendStatus(400) } next() }, /* COMMENTS */ ensureComment: function (req, res, next){ var id = req.params.id.replace(/\D/g, "") if (! id) { return res.sendStatus(404) } db.getCommentById(id).then(function(comment){ if (comment) { comment.set('comment', comment.get('comment').toString()) res.comment = comment next() } else { res.sendStatus(404) } }) }, checkCommentPrivacy: function(req, res, next) { if (req.user.get('ulevel') !== 3 && req.user.get('username') !== res.comment.get('username')) { return res.sendStatus(500) } next() }, createOptionalComment: function(req, res, next){ if (! req.body.comment || ! req.body.comment.length) { return next() } bucky.createComment(req, res, next) }, createComment: function (req, res, next){ if (! req.body.comment || ! req.body.comment.length) { res.json({ error: "no comment" }) return } var data = { thread: res.thread.get('id'), parent_id: req.body.parent_id || -1, username: req.user.get('username'), date: util.now(), comment: req.body.comment, } db.createComment(data).then(function(comment){ res.comment = comment next() }) }, updateComment: function(req, res, next){ if (! req.body.comment || ! req.body.comment.length) { return res.sendStatus(500) } res.comment.set('comment', req.body.comment) res.comment.set('date', util.now()) res.comment.save().then(() => { next() }).catch(err => { res.sendStatus(500) }) }, destroyComment: function(req, res, next){ res.comment.destroy().then(() => { next() }).catch(err => { res.sendStatus(500) }) }, /* FILES */ createOptionalFiles: function(req, res, next){ if (! req.files || ! req.files.length) { return next() } bucky.createFiles(req, res, next) }, createFiles: function (req, res, next){ if (! req.files || ! req.files.length) { res.json({ error: "no files" }) return } var thread_id = res.thread.get('id') var dirname = '/bucky/data/' + thread_id + '/' var promises = req.files.map((file) => { return new Promise( (resolve, reject) => { upload.put({ file: file, preserveFilename: true, dirname: dirname, unacceptable: function(err){ reject(err) }, success: function(url){ var data = { thread: res.thread.get('id'), username: req.user.get('username'), filename: file.originalname, date: util.now(), size: file.size, private: false, storage: 'i.asdf.us', } db.createFile(data).then(function(file){ resolve(file) }).catch( (err) => reject(err) ) } }) }) }) Promise.all(promises).then(values => { next() }).catch(err => { console.log(err) }) }, /* PROFILE */ ensureUser: function (req, res, next){ var username = util.sanitizeName(req.params.username) if (! username) { return res.sendStatus(404) } db.getUserByUsername(username).then(function(user){ if (user) { res.user = util.sanitizeUser(user) next() } else { res.sendStatus(404) } }) }, /* MAIL */ ensureMailboxes: function (req, res, next){ var username = req.user.get('username') var box = req.params.box var mbox = username + "." + box if (! box) { res.sendStatus(404) } db.getMailboxes(username).then(function(boxes){ if (! boxes) { return res.sendStatus(404) } if (! boxes.models.some(function(box){ return box.get('mbox') == mbox })) { return res.sendStatus(404) } res.boxes = boxes next() }) }, ensureMailboxCounts: function (req, res, next){ db.getMailboxCounts(res.boxes.pluck("mbox")).then(function(counts){ var lookup = {} counts.forEach(function(c){ lookup[c.mbox] = c }) res.boxes.forEach(function(box){ var count = lookup[box.get('mbox')] ? lookup[box.get('mbox')].count : 0 box.set("count", count) }) next() }) }, ensureMessages: function (req, res, next){ db.getMessages(req.user.get('username'), req.params.box, 50, 0).then(function(messages){ res.messages = messages next() }) }, ensureMessage: function(req, res, next){ db.getMessage(req.params.id).then(function(message){ var username = req.user.get('username') if (username !== message.get('recipient') && username !== message.get('sender')) { res.sendStatus(404) return } res.message = message next() }) } }