Skip to content

Commit e524b2f

Browse files
committed
project init
1 parent 0451920 commit e524b2f

File tree

219 files changed

+33160
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

219 files changed

+33160
-0
lines changed

README

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
##Node Club
2+
3+
###### 介绍
4+
Node Club 是用 **Node.js** 和 **MongoDb** 开发的新型社区软件,界面优雅,功能丰富,已在Node.js 中文技术社区 [CNode](http://cnodejs.org) 得到应用,但你完全可以用它搭建自己的社区。
5+
6+
###### 安装部署
7+
// install node npm mongodb
8+
// run mongod
9+
cd Node-Club
10+
nmp install ./
11+
cp config.default.js config.js
12+
// modify the config file as yours
13+
node app.js
14+
15+
###### 其它
16+
小量修改了两个依赖模块:node-markdown,express
17+
18+
1.node-markdown/lib/markdown.js allowedTags 添加 `embed` 标签以支持 flash 视频,allowedAttributes 添加 `embed:'src|quality|width|height|align|allowScriptAccess|allowFullScreen|mode|type'`
19+
2.express/node_modules/connect/lib/middleware/csrf.js 添加 `if (req.xhr === true) return next();if (req.body.user_action && req.body.user_action == 'upload_image') return next();`
20+
21+

app.js

+107
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
var express = require('express'),
2+
routes = require('./routes'),
3+
config = require('./config').config;
4+
5+
var app = express.createServer();
6+
7+
var static_dir = __dirname+'/public';
8+
9+
// configuration in all env
10+
app.configure(function(){
11+
app.set('view engine', 'html');
12+
app.set('views', __dirname + '/views');
13+
app.register('.html',require('ejs'));
14+
app.use(express.bodyParser());
15+
app.use(express.cookieParser());
16+
app.use(express.session({
17+
secret:config.session_secret,
18+
}));
19+
// custom middleware
20+
app.use(routes.auth_user);
21+
app.use(express.csrf());
22+
});
23+
24+
//set static,dynamic helpers
25+
app.helpers({
26+
config:config
27+
});
28+
app.dynamicHelpers({
29+
csrf: function(req,res){
30+
return req.session ? req.session._csrf : '';
31+
},
32+
});
33+
34+
app.configure('development', function(){
35+
app.use(express.static(static_dir));
36+
app.use(express.errorHandler({ dumpExceptions: true, showStack: true }));
37+
});
38+
39+
app.configure('production', function(){
40+
var one_year=1000*60*60*24*365;
41+
app.use(express.static(static_dir,{maxAge:one_year}));
42+
app.use(express.errorHandler());
43+
app.set('view cache',true);
44+
});
45+
46+
// routes
47+
app.get('/signup', routes.signup);
48+
app.get('/signin', routes.signin);
49+
app.get('/signout', routes.signout);
50+
app.post('/signup', routes.signup);
51+
app.post('/signin', routes.signin);
52+
53+
app.get('/user/:name', routes.user_index);
54+
app.get('/setting', routes.user_setting);
55+
app.get('/stars', routes.show_stars);
56+
app.get('/users/top100', routes.users_top100);
57+
app.get('/my/tags', routes.get_collect_tags);
58+
app.get('/my/topics', routes.get_collect_topics);
59+
app.get('/my/messages', routes.get_messages);
60+
app.get('/my/follower', routes.get_followers);
61+
app.get('/my/following', routes.get_followings);
62+
app.get('/user/:name/topics', routes.list_user_topics);
63+
app.get('/user/:name/replies', routes.list_user_replies);
64+
app.post('/setting', routes.user_setting);
65+
app.post('/user/follow', routes.follow_user);
66+
app.post('/user/un_follow', routes.un_follow_user);
67+
app.post('/user/set_star', routes.set_star);
68+
app.post('/user/cancel_star', routes.cancel_star);
69+
app.post('/messages/mark_read', routes.mark_message_read);
70+
app.post('/messages/mark_all_read', routes.mark_all_messages_read);
71+
72+
app.get('/tags/edit', routes.edit_tags);
73+
app.get('/tag/:name', routes.list_topic_by_tag);
74+
app.get('/tag/:name/edit', routes.edit_tag);
75+
app.get('/tag/:name/delete', routes.delete_tag);
76+
app.post('/tag/add', routes.add_tag);
77+
app.post('/tag/:name/edit', routes.edit_tag);
78+
app.post('/tag/collect', routes.collect_tag);
79+
app.post('/tag/de_collect', routes.de_collect_tag);
80+
81+
app.get('/topic/create', routes.create_topic);
82+
app.get('/topic/:tid', routes.topic_index);
83+
app.get('/topic/:tid/edit', routes.edit_topic);
84+
app.get('/topic/:tid/delete', routes.delete_topic);
85+
app.post('/topic/create', routes.create_topic);
86+
app.post('/topic/:tid/edit', routes.edit_topic);
87+
app.post('/topic/collect', routes.collect_topic);
88+
app.post('/topic/de_collect', routes.de_collect_topic);
89+
90+
app.post('/:topic_id/reply',routes.reply_topic);
91+
app.post('/:topic_id/reply2',routes.reply2_topic);
92+
app.post('/reply/:reply_id/delete', routes.delete_reply);
93+
94+
app.get('/', routes.index);
95+
96+
app.post('/upload/image', routes.upload_image);
97+
app.post('/search_pass', routes.search_pass);
98+
app.get('/active_account', routes.active_account);
99+
app.get('/search_pass', routes.search_pass);
100+
app.get('/reset_pass',routes.reset_pass);
101+
app.get('/site_tools', routes.site_tools);
102+
app.get('/about', routes.about);
103+
app.get('/faq', routes.faq);
104+
105+
app.listen(config.port);
106+
console.log("NodeClub listening on port %d in %s mode", app.address().port, app.settings.env);
107+
console.log("God bless love....");

config.default.js

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* config
3+
*/
4+
5+
exports.config = {
6+
name: 'Node Club',
7+
description: 'Node Club 是用Node.js开发的社区软件',
8+
host: 'http://127.0.0.1/',
9+
db: 'mongodb://127.0.0.1/node_club',
10+
session_secret: 'node_club',
11+
auth_cookie_name: 'node_club',
12+
port: 80,
13+
version: '0.0.1',
14+
15+
// topics list count
16+
list_topic_count: 20,
17+
18+
// mail SMTP
19+
mail_port: 25,
20+
mail_user: 'club',
21+
mail_pass: 'club',
22+
mail_host: 'smtp.126.com',
23+
mail_sender: '[email protected]',
24+
mail_use_authentication: true,
25+
26+
//weibo app key
27+
weibo_key: 10000000,
28+
29+
// admins
30+
admins: {admin:true}
31+
};
32+

controllers/at.js

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
var models = require('../models'),
2+
User = models.User,
3+
Message = models.Message;
4+
5+
var user_ctrl = require('./user');
6+
var message_ctrl = require('./message');
7+
var EventProxy = require('eventproxy').EventProxy;
8+
9+
function search_at_who(str,cb){
10+
var pattern = /@[a-zA-Z0-9]+/ig;
11+
var results = str.match(pattern);
12+
var names = [];
13+
14+
if(results){
15+
for(var i=0; i<results.length; i++){
16+
var s = results[i];
17+
//remove char @
18+
s = s.slice(1);
19+
names.push(s);
20+
}
21+
}
22+
23+
if(names.length == 0){
24+
return cb(null,names);
25+
}
26+
27+
var users = [];
28+
var proxy = new EventProxy();
29+
var done = function(){
30+
return cb(null,users);
31+
}
32+
proxy.after('user_found',names.length,done);
33+
for(var i=0; i<names.length; i++){
34+
var name = names[i];
35+
var loginname = name.toLowerCase();
36+
user_ctrl.get_user_by_loginname(loginname,function(err,user){
37+
if(err) return cb(err);
38+
if(user){
39+
users.push(user);
40+
proxy.trigger('user_found');
41+
}else{
42+
proxy.trigger('user_found');
43+
}
44+
});
45+
}
46+
}
47+
48+
function send_at_message(str,topic_id,author_id){
49+
search_at_who(str,function(err,users){
50+
for(var i=0; i<users.length; i++){
51+
var user = users[i];
52+
message_ctrl.send_at_message(user._id,author_id,topic_id);
53+
}
54+
});
55+
}
56+
57+
function link_at_who(str,cb){
58+
search_at_who(str,function(err,users){
59+
if(err) return cb(err);
60+
for(var i=0; i<users.length; i++){
61+
var name = users[i].name;
62+
str = str.replace(new RegExp('@'+name,'gmi'),'@<a href="/user/'+name+'">'+name+'</a>');
63+
}
64+
return cb(err,str);
65+
});
66+
}
67+
68+
exports.send_at_message = send_at_message;
69+
exports.link_at_who = link_at_who;

controllers/mail.js

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
var mailer = require('nodemailer');
2+
var config = require('../config').config;
3+
4+
mailer.SMTP = {
5+
host: config.mail_host,
6+
port: config.mail_port,
7+
use_authentication: config.mail_use_authentication,
8+
user: config.mail_user,
9+
pass: config.mail_pass
10+
};
11+
12+
function send_mail(data,cb){
13+
mailer.send_mail(data,function(err,success){
14+
return cb(err,success);
15+
});
16+
}
17+
18+
function send_active_mail(who,token,name,email,cb){
19+
var sender = config.mail_sender;
20+
var to = who;
21+
var subject = config.name + '社区帐号激活';
22+
var html = '<p>您好:<p/>' +
23+
'<p>我们收到您在' + config.name + '社区的注册信息,请点击下面的链接来激活帐户:</p>' +
24+
'<a href="' + config.host + '/active_account?key=' + token + '&name=' + name + '&email=' + email + '">激活链接</a>' +
25+
'<p>若您没有在' + config.name + '社区填写过注册信息,说明有人滥用了您的电子邮箱,请删除此邮件,我们对给您造成的打扰感到抱歉。</p>' +
26+
'<p>' +config.name +'社区 谨上。</p>'
27+
28+
var data = {
29+
sender: sender,
30+
to: to,
31+
subject: subject,
32+
html: html
33+
}
34+
35+
send_mail(data,function(err,success){
36+
return cb(err,success);
37+
});
38+
}
39+
function send_reset_pass_mail(who,token,name,cb){
40+
var sender = config.mail_sender;
41+
var to = who;
42+
var subject = config.name + '社区密码重置';
43+
var html = '<p>您好:<p/>' +
44+
'<p>我们收到您在' + config.name + '社区重置密码的请求,请单击下面的链接来重置密码:</p>' +
45+
'<a href="' + config.host + '/reset_pass?key=' + token + '&name=' + name + '">重置密码链接</a>' +
46+
'<p>若您没有在' + config.name + '社区填写过注册信息,说明有人滥用了您的电子邮箱,请删除此邮件,我们对给您造成的打扰感到抱歉。</p>' +
47+
'<p>' + config.name +'社区 谨上。</p>'
48+
49+
var data = {
50+
sender: sender,
51+
to: to,
52+
subject: subject,
53+
html: html
54+
}
55+
56+
send_mail(data,function(err,success){
57+
return cb(err,success);
58+
});
59+
60+
}
61+
62+
exports.send_active_mail = send_active_mail;
63+
exports.send_reset_pass_mail = send_reset_pass_mail;

0 commit comments

Comments
 (0)