full text search using reds, issue #142

v1.18.x
Baris Soner Usakli 12 years ago
parent 797d05a84a
commit d6b9a2799b

@ -32,7 +32,8 @@
"nconf": "~0.6.7",
"sitemap": "~0.6.0",
"cheerio": "~0.12.0",
"request": "~2.25.0"
"request": "~2.25.0",
"reds": "0.2.3"
},
"bugs": {
"url": "https://github.com/designcreateplay/NodeBB/issues"

@ -823,3 +823,27 @@ body .navbar .nodebb-inline-block {
-webkit-animation: scroll-0 6s ease 0.5s infinite normal;
animation: scroll-0 6s ease 0.5s infinite normal;/* Safari and Chrome: */
}
.form-search {
float: left;
margin-top: 5px;
margin-bottom:0px;
}
.search-result-post {
width: 100%;
height: 50px;
line-height: 16px;
padding: 5px;
overflow:hidden;
img {
display: block;
float: left;
width:48px;
height:48px;
padding-right:10px;
}
span {
padding-left:10px;
}
}

@ -362,6 +362,13 @@ var socket,
jQuery('document').ready(function() {
addTouchEvents();
$('#search-form').on('submit', function() {
var input = $(this).find('input');
ajaxify.go("search/"+input.val(), null, "search");
input.val('');
return false;
})
});
loadConfig();

@ -30,7 +30,8 @@
"recent": "recent",
"unread": "unread",
"popular": "category",
"active": "category"
"active": "category",
"search": "search"
},
"force_refresh": {
"logout": true

@ -57,6 +57,11 @@
</li>
</ul>
<ul id="right-menu" class="nav pull-right nodebb-inline-block">
<form id="search-form"
class="form-search form-inline" action="" method="GET">
<input type="text" name="query" class="input-medium search-query">
<button type="submit" class="btn hide">Search</button>
</form>
<li class="notifications dropdown text-center">
<a class="dropdown-toggle" data-toggle="dropdown" href="#" id="notif_dropdown"><i class="icon-circle-blank"></i></a>
<ul id="notif-list" class="dropdown-menu" aria-labelledby="notif_dropdown">

@ -0,0 +1,36 @@
<div class="container">
<ul class="breadcrumb">
<li><a href="/">Home</a><span class="divider">/</span></li>
<li class="active">Search</li>
</ul>
</div>
<div class="alert alert-warning {show_no_results}" id="no-search-results">
<strong>No search results for {search_query}.</strong>
</div>
<div class="category row">
<div class="span12">
<ul id="topics-container">
<!-- BEGIN posts -->
<a href="../../topic/{posts.topicSlug}#{posts.pid}" id="tid-{posts.tid}">
<li class="category-item">
<div class="row-fluid">
<div class="span12 img-polaroid">
<div class="search-result-post">
<img src="{posts.picture}" />
<strong>{posts.username}</strong>: {posts.content}
</div>
</div>
</div>
</li>
</a>
<!-- END posts -->
</ul>
</div>
</div>
<!--
<script type="text/javascript" src="{relative_path}/src/forum/search.js"></script>
-->

@ -6,7 +6,9 @@ var RDB = require('./redis.js'),
async = require('async'),
utils = require('../public/src/utils'),
plugins = require('./plugins');
plugins = require('./plugins'),
reds = require('reds'),
search = reds.createSearch('nodebbsearch');
(function(PostTools) {
PostTools.isMain = function(pid, tid, callback) {
@ -56,6 +58,10 @@ var RDB = require('./redis.js'),
posts.setPostField(pid, 'edited', Date.now());
posts.setPostField(pid, 'editor', uid);
search.remove(pid, function() {
search.index(content, pid);
});
posts.getPostField(pid, 'tid', function(tid) {
PostTools.isMain(pid, tid, function(isMainPost) {
if (isMainPost)
@ -84,6 +90,7 @@ var RDB = require('./redis.js'),
var success = function() {
posts.setPostField(pid, 'deleted', 1);
search.remove(pid);
posts.getPostFields(pid, ['tid', 'uid'], function(postData) {
@ -119,7 +126,7 @@ var RDB = require('./redis.js'),
var success = function() {
posts.setPostField(pid, 'deleted', 0);
posts.getPostFields(pid, ['tid', 'uid'], function(postData) {
posts.getPostFields(pid, ['tid', 'uid', 'content'], function(postData) {
user.incrementUserFieldBy(postData.uid, 'postcount', 1);
@ -132,6 +139,8 @@ var RDB = require('./redis.js'),
topics.updateTimestamp(postData.tid, timestamp);
});
});
search.index(postData.content, pid);
});
};

@ -8,7 +8,9 @@ var RDB = require('./redis.js'),
postTools = require('./postTools'),
feed = require('./feed.js'),
async = require('async'),
plugins = require('./plugins');
plugins = require('./plugins'),
reds = require('reds'),
search = reds.createSearch('nodebbsearch');
(function(Posts) {
@ -323,46 +325,19 @@ var RDB = require('./redis.js'),
user.onNewPostMade(uid, tid, pid, timestamp);
var imgur = require('./imgur');
imgur.setClientID(global.nconf.get('imgurClientID'));
uploadPostImages(postData, images, function(err, uploadedImages) {
if(err) {
console.log('Uploading images failed!');
} else {
postData.uploadedImages = JSON.stringify(uploadedImages);
Posts.setPostField(pid, 'uploadedImages', postData.uploadedImages);
}
callback(postData);
});
var uploadedImages = [];
function uploadImage(image, callback) {
imgur.upload(image.data, 'base64', function(err, data) {
if(err) {
callback(err);
} else {
if(data.success) {
var img= {url:data.data.link, name:image.name};
uploadedImages.push(img);
callback(null);
} else {
callback(data);
}
}
});
}
plugins.fireHook('action:save_post_content', [pid, content]);
if(!images) {
postData.uploadedImages = JSON.stringify(uploadedImages);
Posts.setPostField(pid, 'uploadedImages', postData.uploadedImages);
callback(postData);
} else {
async.each(images, uploadImage, function(err) {
if(!err) {
postData.uploadedImages = JSON.stringify(uploadedImages);
Posts.setPostField(pid, 'uploadedImages', postData.uploadedImages);
callback(postData);
} else {
console.log(err);
callback(null);
}
});
}
search.index(content, pid);
});
});
} else {
@ -370,6 +345,42 @@ var RDB = require('./redis.js'),
}
});
}
function uploadPostImages(postData, images, callback) {
var imgur = require('./imgur');
imgur.setClientID(global.nconf.get('imgurClientID'));
var uploadedImages = [];
function uploadImage(image, callback) {
imgur.upload(image.data, 'base64', function(err, data) {
if(err) {
callback(err);
} else {
if(data.success) {
var img= {url:data.data.link, name:image.name};
uploadedImages.push(img);
callback(null);
} else {
callback(data);
}
}
});
}
if(!images) {
callback(null, uploadedImages);
} else {
async.each(images, uploadImage, function(err) {
if(!err) {
callback(null, uploadedImages);
} else {
console.log(err);
callback(err, null);
}
});
}
}
Posts.getPostsByUid = function(uid, start, end, callback) {

@ -146,5 +146,36 @@ var user = require('./../user.js'),
res.redirect(global.nconf.get('relative_path') + '/404');
}
});
app.get('/api/search', function(req, res) {
return res.json({
show_no_results:'hide',
search_query:'',
posts:[]
});
});
app.get('/api/search/:term', function(req, res, next) {
var reds = require('reds');
var search = reds.createSearch('nodebbsearch');
search
.query(query = req.params.term).type('or')
.end(function(err, ids) {
if (err)
return next();
posts.getPostSummaryByPids(ids, function(posts) {
res.json(200, {
show_no_results:ids.length?'hide':'show',
search_query:req.params.term,
posts:posts
});
});
});
});
}
}(exports));

@ -382,6 +382,18 @@ var express = require('express'),
res.redirect(global.nconf.get('relative_path') + '/404');
}
});
app.get('/search', function(req, res) {
app.build_header({ req: req, res: res }, function(err, header) {
res.send(header + app.create_route("search", null, "search") + templates['footer']);
});
});
app.get('/search/:term', function(req, res) {
app.build_header({ req: req, res: res }, function(err, header) {
res.send(header + app.create_route("search/"+req.params.term, null, "search") + templates['footer']);
});
});
});
}(WebServer));

Loading…
Cancel
Save