diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/auth.js | 78 | ||||
| -rw-r--r-- | lib/bucky.js | 191 | ||||
| -rw-r--r-- | lib/db/bookshelf.js | 24 | ||||
| -rw-r--r-- | lib/db/index.js | 187 | ||||
| -rw-r--r-- | lib/fortune.js | 28 | ||||
| -rw-r--r-- | lib/index.js | 60 | ||||
| -rw-r--r-- | lib/middleware.js | 23 | ||||
| -rw-r--r-- | lib/router.js | 169 | ||||
| -rw-r--r-- | lib/search/index.js | 12 | ||||
| -rw-r--r-- | lib/search/snippet.js | 103 | ||||
| -rw-r--r-- | lib/util.js | 4 |
11 files changed, 113 insertions, 766 deletions
diff --git a/lib/auth.js b/lib/auth.js deleted file mode 100644 index 38901e4..0000000 --- a/lib/auth.js +++ /dev/null @@ -1,78 +0,0 @@ - -var passport = require('passport'), - LocalStrategy = require('passport-local').Strategy, - crypto = require('crypto'), - db = require('./db'); - - -var auth = module.exports = { - - init: function(){ - passport.serializeUser(auth.serializeUser) - passport.deserializeUser(auth.deserializeUser) - - passport.use(new LocalStrategy(auth.verifyLocalUser)) - }, - - serializeUser: function (user, done) { - done(null, user.id); - }, - - deserializeUser: function (id, done) { - db.getUser(id).then(function(user){ - done(! user, user) - }) - }, - - validPassword: function(user, pw){ - var shasum = crypto.createHash('sha1') - shasum.update(pw) - return user.get('password') === shasum.digest('hex'); - }, - - verifyLocalUser: function (username, password, done) { - // handle passwords!! - db.getUserByUsername(username).then(function(user){ - - // if (err) { return done(err); } - if (! user) { return done("no user") } - - return done(null, user) - - if (! user) { - return done(null, false, { error: { errors: { username: { message: 'No such username.' } }}}) - } - if (! auth.validPassword(user, password)) { - return done(null, false, { error: { errors: { password: { message: 'Incorrect password.' } }}}) - } - return done(null, user); - }) - }, - - loggedInLocal: function (req, res, next) { - passport.authenticate("local", function(err, user, info){ - if (err) { - return res.json({ error: err }); - } - if (! user) { - return info ? res.json(info) : res.redirect("/login"); - } - - // user.last_seen = new Date () - // user.save(function(err, data){ if (err) console.err('error setting ip for user') }) - - req.logIn(user, function(err) { - if (err) { return next(err); } - var returnTo = req.session.returnTo - delete req.session.returnTo - return res.json({ status: "OK", returnTo: returnTo || "/index" }) - }); - })(req, res, next) - }, - - logout: function (req, res) { - req.logout(); - res.redirect('/'); - }, - -}
\ No newline at end of file diff --git a/lib/bucky.js b/lib/bucky.js deleted file mode 100644 index 70910ef..0000000 --- a/lib/bucky.js +++ /dev/null @@ -1,191 +0,0 @@ -var db = require('./db') -var util = require('./util') -var _ = require('lodash') - -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() - }) - }, - - /* 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) - } - }) - }, - ensureKeywordForThread: function (req, res, next){ - var keyword = res.thread.get('keyword') - if (! keyword) return next() - db.getKeyword(keyword).then(function(keyword){ - res.keyword = keyword - 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() - }) - }, - - /* 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() - }) - }, - 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() - }) - }, - - /* 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() - }) - } -}
\ No newline at end of file diff --git a/lib/db/bookshelf.js b/lib/db/bookshelf.js deleted file mode 100644 index 69157cc..0000000 --- a/lib/db/bookshelf.js +++ /dev/null @@ -1,24 +0,0 @@ -var knex = require('knex')({ - client: 'mysql2', - connection: { - host : process.env.DB_HOST, - user : process.env.DB_USER, - password : process.env.DB_PASS, - database : process.env.DB_NAME, - charset : 'utf8', - typecast : function (field, next) { - console.log(field.type) - if (field.type == 'BLOB') { - return field.string() - } - return next() - } - } -}) - -var bookshelf = require('bookshelf')(knex) - -module.exports = { - bookshelf: bookshelf, - knex: knex, -} diff --git a/lib/db/index.js b/lib/db/index.js deleted file mode 100644 index f376308..0000000 --- a/lib/db/index.js +++ /dev/null @@ -1,187 +0,0 @@ -var db = module.exports - -var connection = require("./bookshelf") -var bookshelf = connection.bookshelf -var knex = connection.knex - - -/* MODELS */ - -var User = db.User = bookshelf.Model.extend({ - tableName: 'users', - hasTimestamps: false, -}) -var Thread = db.Thread = bookshelf.Model.extend({ - tableName: 'threads', - hasTimestamps: false, -}) -var Comment = db.Comment = bookshelf.Model.extend({ - tableName: 'comments', - hasTimestamps: false, -}) -var File = db.File = bookshelf.Model.extend({ - tableName: 'files', - hasTimestamps: false, -}) -var Keyword = db.Keyword = bookshelf.Model.extend({ - tableName: 'keywords', - hasTimestamps: false, -}) -var Mailbox = db.Mailbox = bookshelf.Model.extend({ - tableName: 'boxes', - hasTimestamps: false, -}) -var Message = db.Message = bookshelf.Model.extend({ - tableName: 'messages', - hasTimestamps: false, -}) - -/* USERS */ - -db.createUser = function(data){ - return new db.User(data).save() -} -db.getUsers = function () { - return User.query(function(qb){ - qb.orderBy("id", "desc") - }).fetchAll() -} -db.getUser = function(id) { - var model = new User({'id': id}) - return model.fetch() -} -db.getUserByUsername = function(username) { - var model = new User({'username': username}) - return model.fetch() -} -db.getLastlog = function(limit){ - return knex.column('username').column('lastseen').select().from('users').orderBy('lastseen', 'desc').limit(limit || 10) -} - -/* THREADS */ - -db.getLatestThreads = function () { - return Thread.query(function(qb){ - qb.orderBy("lastmodified", "desc").limit(50) - }).fetchAll() -} -db.getThreadsForKeyword = function (keyword) { - return Thread.query(function(qb){ - qb.where("keyword", "=", keyword).orderBy("id", "desc") - }).fetchAll() -} -db.getThread = function (id) { - return Thread.query("where", "id", "=", id).fetch() -} -db.createThread = function(data){ - return new db.Thread(data).save() -} -db.updateThread = function(data){ -} -db.removeThread = function(id){ -} - -/* FILES */ - -db.getFilesForThread = function (id){ - return File.query("where", "thread", "=", id).fetchAll() -} -db.getFileCounts = function(ids){ - return knex.column('thread').count('* as count').select().from('files').where('thread', 'in', ids).groupBy('thread') -} -db.getFileSizes = function(ids){ - return knex.column('thread').sum('size as size').select().from('files').where('thread', 'in', ids).groupBy('thread') -} -db.createFile = function(data){ - return new db.File(data).save() -} -db.removeFile = function(id){ -} - -/* COMMENTS */ - -db.getCommentsForThread = function (id, limit, offset, order){ - order = order || "asc" - return Comment.query(function(qb){ - qb.where("thread", "=", id).orderBy("id", order) - if (limit) { - qb.limit(limit) - } - if (offset) { - qb.offset(offset) - } - }).fetchAll().then(function(comments){ - comments.forEach(function(comment){ - comment.set("comment", comment.get("comment").toString() ) - }) - return comments - }) -} -db.getCommentCounts = function(ids){ - return knex.column('thread').count('* as count').select().from('comments').where('thread', 'in', ids).groupBy('thread') -} -db.createComment = function(data){ - return new db.Comment(data).save() -} -db.updateComment = function(data){ -} -db.removeComment = function(id){ -} - - -/* KEYWORDS */ - -db.getKeywords = function (keywords){ - return Keyword.query("where", "keyword", "in", keywords).fetchAll() -} -db.getKeyword = function (keyword) { - return Keyword.query("where", "keyword", "=", keyword).fetch() -} -db.createKeyword = function(data){ - return new db.Keyword(data).save() -} -db.updateKeyword = function(data){ -} -db.removeKeyword = function(id){ -} - - -/* MAILBOXES */ - -db.getMailboxes = function(username){ - return Mailbox.query("where", "owner", "=", username).fetchAll() -} -db.getMailboxCounts = function(boxes){ - return knex.column('mbox').count('* as count').select().from('messages').where('mbox', 'in', boxes).groupBy('mbox') -} -db.createMailbox = function(data){ -} - -/* MESSAGES */ - -db.getMessages = function(username, box, limit, offset){ - var mbox = username + "." + box - return Message.query(function(qb){ - qb.column('id', 'mbox', 'unread', 'sender', 'recipient', 'date', 'subject', knex.raw("CHAR_LENGTH(body) as size")).where("mbox", "=", mbox).orderBy("id", "desc") - if (limit) { - qb.limit(limit) - } - if (offset) { - qb.offset(offset) - } - }).fetchAll() -} -db.getMessage = function (id){ - var model = new Message({'id': id}) - return model.fetch().then(function(message){ - message.set("body", message.get("body").toString() ) - return message - }) -} -db.createMessage = function(data){ - return new db.Message(data).save() -} -db.updateMessage = function(data){ -} -db.removeMessage = function(id){ -} diff --git a/lib/fortune.js b/lib/fortune.js deleted file mode 100644 index 7adba5a..0000000 --- a/lib/fortune.js +++ /dev/null @@ -1,28 +0,0 @@ -function choice (a){ return a[ Math.floor(Math.random()*a.length) ] } - -var fs = require("fs"), path = require("path") -var fortunes = {} -var dir = "fortune" - -fs.readdirSync(path.resolve(dir)).forEach(function(fn){ - - var file = dir + '/' + fn - var stat = fs.statSync(file) - - if (stat && ! stat.isDirectory()) { - fortunes[fn] = fs.readFileSync(file) - .toString() - .split("\n") - .filter(function(s){ return !! s }) - } - -}) - -module.exports = function(tag){ - if (tag in fortunes) { - return choice(fortunes[tag]) - } - else { - return "bucky" - } -}
\ No newline at end of file diff --git a/lib/index.js b/lib/index.js deleted file mode 100644 index 5aef342..0000000 --- a/lib/index.js +++ /dev/null @@ -1,60 +0,0 @@ -require('dotenv').load(); -var fs = require('fs') -var app, express = require('express'); -var http = require('http'); -var https = require('https'); -var bodyParser = require('body-parser') -var cookieParser = require('cookie-parser') -var csurf = require('csurf') -var path = require('path') -var multiparty = require('multiparty') -var ejs = require('ejs') -var passport = require('passport') -var sessionstore = require('sessionstore') -var session = require('express-session') -var multer = require('multer') - -var app, server - -var mongodb = require('mongodb') - -var site = module.exports = {} -site.init = function(){ - app = express() - app.set('port', 5000) - app.set('view engine', 'ejs') - app.set('views', path.join(__dirname, '../views')) - app.use(express.static(path.join(__dirname, '../public'))) - app.use(bodyParser.json()) - app.use(bodyParser.urlencoded({ extended: false })) - app.use( multer({ dest:'./uploads/' }).single("file") ) - - app.use(session({ - key: 'bucky.sid', - secret: 'argonauts', - cookie: { domain: '.' + process.env.HOST_NAME, maxAge: 43200000000 }, - store: sessionstore.createSessionStore({ - type: 'mongodb', - host: 'localhost', - port: 27017, - dbName: 'buckySessionDb', - collectionName: 'sessions', - timeout: 10000, - }), - resave: true, - saveUninitialized: false, - })) - app.use(csurf({ cookie: false })) - - app.use(express.query()) - app.use(passport.initialize()) - app.use(passport.session()) - - server = http.createServer(app).listen(process.env.PORT || 5000, function () { - console.log('Bucky listening at http://5.k:%s', server.address().port) - }) - - site.route(app) -} - -site.route = require('./router') diff --git a/lib/middleware.js b/lib/middleware.js deleted file mode 100644 index a744c89..0000000 --- a/lib/middleware.js +++ /dev/null @@ -1,23 +0,0 @@ -var middleware = module.exports = { - - ensureAuthenticated: function (req, res, next) { - if (! req.isAuthenticated()) { - req.session.returnTo = req.path - return res.redirect('/login') - } - next() - }, - - ensureLocals: function (req, res, next) { - res.locals.csrfToken = req.csrfToken() - res.locals.title = "bucky" - if (req.isAuthenticated()) { - res.locals.show_header = true - } - else { - res.locals.show_header = false - } - next() - }, - -}
\ No newline at end of file diff --git a/lib/router.js b/lib/router.js deleted file mode 100644 index c08037e..0000000 --- a/lib/router.js +++ /dev/null @@ -1,169 +0,0 @@ -var auth = require('./auth') -var middleware = require('./middleware') -var fortune = require('./fortune') -var bucky = require('./bucky') -var db = require('./db') -var util = require('./util') - -module.exports = function(app){ - app.all('*', middleware.ensureLocals) - - auth.init() - - app.get("/", middleware.ensureAuthenticated, function(req, res){ - res.redirect('/index') - }) - app.get("/login", function(req, res){ - res.render("pages/login", { - title: "login" - }) - }) - app.get("/index", middleware.ensureAuthenticated, function(req, res){ - res.render("pages/index", { - title: fortune("titles"), - hoot_text: fortune("hoots"), - }) - }) - app.get("/details/:id", middleware.ensureAuthenticated, function(req, res){ - res.render("pages/details", {}) - }) - - app.post("/api/login", auth.loggedInLocal) - app.get("/api/index", - bucky.ensureLastlog, - middleware.ensureAuthenticated, - bucky.ensureLatestThreads, - bucky.ensureCommentCountsForThreads, - bucky.ensureFileCountsForThreads, - bucky.ensureKeywordsForThreads, - bucky.ensureHootbox, - function(req, res){ - res.json({ - threads: res.threads, - hootbox: res.hootbox, - lastlog: res.lastlog, - }) - } - ) - app.get("/api/thread/:id", - middleware.ensureAuthenticated, - bucky.ensureThread, - bucky.ensureKeywordForThread, - bucky.ensureCommentsForThread, - bucky.ensureFilesForThread, - function(req, res){ - res.json({ - thread: res.thread, - comments: res.comments, - files: res.files, - keyword: res.keyword, - }) - } - ) - app.post("/api/thread", - middleware.ensureAuthenticated, - function(req, res){ - // make a new thread - }) - app.post("/api/thread/:id/comment", - middleware.ensureAuthenticated, - bucky.ensureThread, - function(req, res){ - if (!req.params.id) return res.sendStatus(500) - var comment = { - thread: req.params.id, - parent_id: req.body.parent_id || -1, - username: req.user.get('username'), - date: Math.round(+(new Date) / 1000), - comment: req.body.comment, - hidden: false, - } - db.createComment(comment).then(function(c){ - res.json(comment) - }) - }) - app.post("/api/thread/:id/file", - middleware.ensureAuthenticated, - bucky.ensureThread, - function(req, res){ - // add comments and files - }) - app.delete("/api/thread/:id", - middleware.ensureAuthenticated, - function(req, res){ - // delete a thread - }) - app.put("/api/comment/:id", - middleware.ensureAuthenticated, - function(req, res){ - // edit a comment - }) - app.delete("/api/comment/:id", - middleware.ensureAuthenticated, - function(req, res){ - // delete a comment - }) - - - app.get("/api/keyword/:keyword", - middleware.ensureAuthenticated, - bucky.ensureKeyword, - bucky.ensureThreadsForKeyword, - bucky.ensureCommentCountsForThreads, - bucky.ensureFileCountsForThreads, - bucky.ensureKeywordsForThreads, - function(req, res){ - res.json({ - keyword: res.keyword, - threads: res.threads, - }) - } - ) - - app.get("/mail/", - middleware.ensureAuthenticated, - function(req, res){ - res.render("pages/mailbox", {title: "inbox" }) - } - ) - app.get("/mail/:box", - middleware.ensureAuthenticated, - function(req, res){ - res.render("pages/mailbox", { title: util.sanitize(req.params.box) }) - } - ) - app.get("/message/:id", - middleware.ensureAuthenticated, - function(req, res){ - res.render("pages/message", { title: util.sanitize(req.params.box) }) - } - ) - app.get("/api/mailbox/:box", - middleware.ensureAuthenticated, - bucky.ensureMailboxes, - bucky.ensureMailboxCounts, - bucky.ensureMessages, - function(req, res){ - res.json({ - user: { id: req.user.get("id"), username: req.user.get("username") }, - messages: res.messages, - boxes: res.boxes, - }) - } - ) - app.get("/api/message/:id", - middleware.ensureAuthenticated, - bucky.ensureMessage, - function(req, res){ - res.json({ - message: res.message, - }) - }) - app.post("/mail/", - middleware.ensureAuthenticated, - function(req, res){ - // send new mail - } - ) - -} diff --git a/lib/search/index.js b/lib/search/index.js index 8d209e6..27f436f 100644 --- a/lib/search/index.js +++ b/lib/search/index.js @@ -35,8 +35,16 @@ var STOPWORDS = new Set( ); function find_term(term) { - bdb.get(term) - + var matches = bdb.get(term).split(",").map((s) => { + var partz = s.split(" ") + var match = { + thread: s[0], + comment: s[1], + file: s[2], + strength: s[3], + } + }) + return matches } function search (query, start, limit) { diff --git a/lib/search/snippet.js b/lib/search/snippet.js new file mode 100644 index 0000000..de71911 --- /dev/null +++ b/lib/search/snippet.js @@ -0,0 +1,103 @@ +var util = require('../util/util') + +function bold_terms (s, terms) { + +} +sub bold_terms + { + my ($self, $string, $terms) = @_; + $string = $self->strip_html($string); + foreach my $term (@$terms) + { + $string =~ s/\b($term)\b/<b>$1<\/b>/gi; + } + return $string; + } +sub bold_snippet + { + my ($self, $string, $terms) = @_; + my $snippet = $self->snippet($string, $terms); + return $self->bold_terms($snippet, $terms); + } +sub snippet + { + my ($self, $string, $terms) = @_; + + # clean up the string we got + $string = $self->strip_html($string); + + # create a regex out of the search terms + my $term_re = join "|", @$terms; + + # take the string to be snippetized and split it into words + my @words = split /\s+/, $string; + + # deduper for matching @words indexes, so we don't add a word twice + my $index_matches = {}; + + # words in the eventual snippet + my @words_matched; + + # the snippet itself + my $snippet = ''; + + # counter for aggregating context after a match + my $aggr = 0; + + # amount of context to show, in number of words surrounding a match + my $pad = 4; + + # loop over each of the words in the string + for (my $i = 0; $i < scalar @words; $i++) + { + # does this word contain a match? + if ($words[$i] =~ /\b($term_re)\b/i && ! $self->is_stopword($1)) + { + # if we aren't already aggregating, add an ellipsis + if (! $aggr) + { + push @words_matched, "..."; + } + # look backward $pad words + for (my $j = -$pad; $j < 1; $j++) + { + # create a new index from the offset + my $idx = $i + $j; + + # is this a valid index? has it already been encountered? + next if $idx < 0; + next if $idx > scalar @words; + next if exists $index_matches->{$i+$j}; + + # checks out, save this word + push @words_matched, $words[$i+$j]; + + # note the matching index in our deduper + $index_matches->{$i+$j} ++; + } + # enter aggregate mode -- add the next $pad words + $aggr = $pad; + } + # have we been told to aggregate? + elsif ($aggr) + { + # save this word + push @words_matched, $words[$i]; + + # add index to the deduper + $index_matches->{$i} ++; + + # one less word to aggregate + $aggr--; + } + # keep snippets to a modest length + last if scalar @words_matched > 30; + } + # add a trailing ellipsis + push @words_matched, "..."; + + # create the snippet from the saved context words + $snippet = join " ", @words_matched; + + return $snippet; + }
\ No newline at end of file diff --git a/lib/util.js b/lib/util.js deleted file mode 100644 index e67488b..0000000 --- a/lib/util.js +++ /dev/null @@ -1,4 +0,0 @@ -var util = module.exports = {} - -util.sanitizeName = function (s){ return (s || "").replace(new RegExp("[^-_a-zA-Z0-9]", 'g'), "") } -util.sanitize = function (s){ return (s || "").replace(/<>&/g, "") } |
