Permalink
Browse files

合并 cnode 主版本

  • Loading branch information...
1 parent 9aed309 commit d9d03c141c013d5b69c275afac04c6ee7bb848d3 @DongHongfei DongHongfei committed Apr 12, 2015
View
@@ -5,6 +5,7 @@ node_js:
- 'iojs'
services:
- mongodb
+ - redis
script: make test-cov
after_success: cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js
View
@@ -22,6 +22,7 @@ test: install pretest
@NODE_ENV=test ./node_modules/mocha/bin/mocha \
--reporter $(MOCHA_REPORTER) \
-r should \
+ -r test/env \
--timeout $(TEST_TIMEOUT) \
$(TESTS)
@@ -31,6 +32,7 @@ test-cov cov: install pretest
./node_modules/.bin/_mocha \
-- \
-r should \
+ -r test/env \
--reporter $(MOCHA_REPORTER) \
--timeout $(TEST_TIMEOUT) \
$(TESTS)
View
@@ -24,11 +24,11 @@ Nodeclub 是使用 **Node.js** 和 **MongoDB** 开发的社区系统,界面优
*不保证 Windows 系统的兼容性*
-线上跑的是 Node.js v1.5,MongoDB 是 v2.6。
+线上跑的是 Node.js v1.5,MongoDB 是 v2.6,Redis 是 v2.8.9
```
-1. install `node.js[必须]` `mongodb[必须]`
-2. run mongod
+1. 安装 `node.js[必须]` `mongodb[必须]` `redis[必须]`
+2. 启动 mongodb 和 redis
3. `$ make install` 安装 Nodeclub 的依赖包
4. `cp config.default.js config.js` 请根据需要修改配置文件
5. `$ make test` 确保各项服务都正常
View
@@ -20,8 +20,13 @@ var index = function (req, res, next) {
var query = {};
if (tab && tab !== 'all') {
- query.tab = tab;
+ if (tab === 'good') {
+ query.good = true;
+ } else {
+ query.tab = tab;
+ }
}
+ query.deleted = false;
var options = { skip: (page - 1) * limit, limit: limit, sort: '-top -last_reply_at'};
var ep = new eventproxy();
View
@@ -6,13 +6,15 @@ var toolsController = require('./api/v1/tools');
var replyController = require('./api/v1/reply');
var messageController = require('./api/v1/message');
var middleware = require('./api/v1/middleware');
+var limit = require('./middlewares/limit');
+var config = require('./config');
var router = express.Router();
// 主题
router.get('/topics', topicController.index);
router.get('/topic/:id', topicController.show);
-router.post('/topics', middleware.auth, topicController.create);
+router.post('/topics', middleware.auth, limit.peruserperday('create_topic', config.create_post_per_day), topicController.create);
router.post('/topic/collect', middleware.auth, topicController.collect); // 关注某话题
router.post('/topic/de_collect', middleware.auth, topicController.de_collect); // 取消关注某话题
@@ -23,7 +25,7 @@ router.get('/user/:loginname', userController.show);
router.post('/accesstoken', middleware.auth, toolsController.accesstoken);
// 评论
-router.post('/topic/:topic_id/replies', middleware.auth, replyController.create);
+router.post('/topic/:topic_id/replies', middleware.auth, limit.peruserperday('create_reply', config.create_reply_per_day), replyController.create);
router.post('/reply/:reply_id/ups', middleware.auth, replyController.ups);
// 通知
View
@@ -23,14 +23,16 @@ var githubStrategyMiddleware = require('./middlewares/github_strategy');
var webRouter = require('./web_router');
var apiRouterV1 = require('./api_router_v1');
var auth = require('./middlewares/auth');
-var MongoStore = require('connect-mongo')(session);
+var proxyMiddleware = require('./middlewares/proxy');
+var RedisStore = require('connect-redis')(session);
var _ = require('lodash');
var csurf = require('csurf');
var compress = require('compression');
var bodyParser = require('body-parser');
var busboy = require('connect-busboy');
var errorhandler = require('errorhandler');
var cors = require('cors');
+var limitMiddleware = require('./middlewares/limit');
// 静态文件目录
var staticDir = path.join(__dirname, 'public');
@@ -56,6 +58,16 @@ app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'html');
app.engine('html', require('ejs-mate'));
app.locals._layoutFile = 'layout.html';
+app.enable('trust proxy');
+
+
+// 静态资源
+app.use(Loader.less(__dirname));
+app.use('/public', express.static(staticDir));
+app.use('/agent', proxyMiddleware.proxy);
+
+// 每日访问限制
+// app.use(limitMiddleware.peripperday('all', config.visit_per_day));
app.use(require('response-time')());
app.use(bodyParser.json());
@@ -67,8 +79,9 @@ app.use(require('cookie-parser')(config.session_secret));
app.use(compress());
app.use(session({
secret: config.session_secret,
- store: new MongoStore({
- url: config.db
+ store: new RedisStore({
+ port: config.redis_port,
+ host: config.redis_host,
}),
resave: true,
saveUninitialized: true,
@@ -80,8 +93,6 @@ app.use(passport.initialize());
app.use(auth.authUser);
app.use(auth.blockUser());
-app.use(Loader.less(__dirname));
-app.use('/public', express.static(staticDir));
if (!config.debug) {
app.use(function (req, res, next) {
@@ -136,12 +147,13 @@ if (config.debug) {
app.use(errorhandler());
} else {
app.use(function (err, req, res, next) {
+ console.error('server 500 error:', err);
return res.status(500).send('500 status');
});
}
app.listen(config.port, function () {
- console.log("NodeClub listening on port %d in %s mode", config.port, app.settings.env);
+ console.log("NodeClub listening on port %d", config.port);
console.log("God bless love....");
console.log("You can debug your app with http://" + config.hostname + ':' + config.port);
});
View
@@ -0,0 +1,17 @@
+// 一次性脚本
+var TopicModel = require('../models').Topic;
+
+TopicModel.find({content: /\[{2,}@/}).exec(function (err, topics) {
+ topics.forEach(function (topic) {
+ topic.content = fix(topic.content);
+ console.log(topic.id);
+ topic.save();
+ });
+});
+
+function fix(str) {
+ str = str.replace(/\[{1,}(\[@\w+)(\]\(.+?\))\2+/, function (match_text, $1, $2) {
+ return $1 + $2;
+ });
+ return str;
+}
@@ -1,3 +1,4 @@
+// 一次性脚本
// 为所有老用户生成 accessToken
var uuid = require('node-uuid');
View
@@ -1,24 +1,34 @@
-
-var mcache = require('memory-cache');
+var redis = require('./redis');
+var _ = require('lodash');
var get = function (key, callback) {
- setImmediate(function () {
- callback(null, mcache.get(key));
+ redis.get(key, function (err, data) {
+ if (err) {
+ return callback(err);
+ }
+ if (!data) {
+ return callback();
+ }
+ data = JSON.parse(data);
+ callback(null, data);
});
};
exports.get = get;
-// time 参数可选,毫秒为单位
+// time 参数可选,秒为单位
var set = function (key, value, time, callback) {
if (typeof time === 'function') {
callback = time;
time = null;
}
- mcache.put(key, value, time);
- setImmediate(function () {
- callback && callback(null);
- });
+ callback = callback || _.noop;
+ value = JSON.stringify(value);
+ if (!time) {
+ redis.set(key, value, callback);
+ } else {
+ redis.setex(key, time, value, callback);
+ }
};
exports.set = set;
View
@@ -0,0 +1,6 @@
+var config = require('../config');
+var redis = require('redis');
+
+var client = redis.createClient(config.redis_port, config.redis_host);
+
+exports = module.exports = client;
@@ -89,4 +89,8 @@ exports.tabName = function (tab) {
}
};
+exports.proxy = function (url) {
+ return '"/agent?&url=' + encodeURIComponent(url) + '"';
+};
+
exports._ = _;
View
@@ -38,6 +38,9 @@ var config = {
db: 'mongodb://127.0.0.1/node_club_dev',
db_name: 'node_club_dev',
+ // redis 配置,默认是本地
+ redis_host: '127.0.0.1',
+ redis_port: 6379,
session_secret: 'node_club_secret', // 务必修改
auth_cookie_name: 'node_club',
@@ -48,9 +51,6 @@ var config = {
// 话题列表显示的话题数量
list_topic_count: 20,
- // 限制发帖时间间隔,单位:毫秒
- post_interval: 2000,
-
// RSS配置
rss: {
title: 'CNode:Node.js专业中文社区',
@@ -90,16 +90,18 @@ var config = {
// newrelic 是个用来监控网站性能的服务
newrelic_key: 'yourkey',
- //7牛的access信息,用于文件上传
+ // 下面两个配置都是文件上传的配置
+
+ // 7牛的access信息,用于文件上传
qn_access: {
accessKey: 'your access key',
secretKey: 'your secret key',
bucket: 'your bucket name',
domain: 'http://{bucket}.qiniudn.com'
},
- //文件上传配置
- //注:如果填写 qn_access,则会上传到 7牛,以下配置无效
+ // 文件上传配置
+ // 注:如果填写 qn_access,则会上传到 7牛,以下配置无效
upload: {
path: path.join(__dirname, 'public/upload/'),
url: '/public/upload/'
@@ -117,7 +119,11 @@ var config = {
appKey: 'YourAccessKeyyyyyyyyyyyy',
masterSecret: 'YourSecretKeyyyyyyyyyyyyy',
isDebug: false,
- }
+ },
+
+ create_post_per_day: 1000, // 每个用户一天可以发的主题数
+ create_reply_per_day: 1000, // 每个用户一天可以发的评论数
+ visit_per_day: 1000, // 每个 ip 每天能访问的次数
};
module.exports = config;
@@ -92,7 +92,8 @@ exports.delete = function (req, res, next) {
return;
}
if (reply.author_id.toString() === req.session.user._id.toString() || req.session.user.is_admin) {
- reply.remove();
+ reply.deleted = true;
+ reply.save();
res.json({status: 'success'});
if (!reply.reply_id) {
View
@@ -48,7 +48,7 @@ exports.index = function (req, res, next) {
var rssContent = convert('rss', rss_obj);
- cache.set('rss', rssContent, 1000 * 60 * 5); // 五分钟
+ cache.set('rss', rssContent, 60 * 5); // 五分钟
res.send(rssContent);
});
}
Oops, something went wrong.

0 comments on commit d9d03c1

Please sign in to comment.