-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapp.js
More file actions
193 lines (171 loc) · 6.94 KB
/
app.js
File metadata and controls
193 lines (171 loc) · 6.94 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
// load modules
var http = require('http'),
express = require('express'),
socketio = require('socket.io'),
sass = require('node-sass'),
lingua = require('lingua'),
redirect = require('redirect')('ctlnode.herokuapp.com'),
listdao = require('list-dal');
// create an express instance
var app = express();
// create new HTTP-server for the express instance
var server = http.createServer(app);
// configure express
app.configure(function () {
app.use(redirect);
// configure jade (template engine)
app.set('view engine', 'jade'); // use jade, which is integrated in express
app.set('views', __dirname + '/views'); // where the template files are
// configure directory for static embedding
app.use(express.static(__dirname + '/public'));
// configure node-sass (css preprocessor)
app.use(sass.middleware({
src: __dirname, // where the sass files are
dest: __dirname + '/public', // where css should go
debug: true
}));
// configure lingua (internationalization module)
app.use(lingua(app, {
defaultLocale: 'en',
path: __dirname + '/i18n'
}));
});
// case 1: receive url without alias
app.get('/', function (req, res) {
// create new random url and link to it
logEvent("got url without alias");
makeNewAlias(function (newAlias) {
res.redirect(307, '/' + newAlias); // redirect to new alias
});
});
// case 2: receive url with alias
app.get('/:alias', function (req, res) {
// ignore request for favion
if (req.params.alias === 'favicon.ico') return;
logEvent("got url with alias: " + req.params.alias);
// function object renders list
var renderList = function (reqList) {
logEvent("render list: " + reqList.alias);
res.render('index', {
list: reqList
});
}
// find mapped list in mongodb 'ctlnode' or create a new one and let it render
listdao.findOne(req.params.alias, function (err, result) {
if (err) {
logEvent("\n" + err + "\n--------------------");
} else {
// if list for alias has been found in db: render it
if (result) {
logEvent("found list in db for: " + result.alias);
renderList(result);
} else {
// if there is no list for alias in db: create one...
listdao.create(req.params.alias, function (err, result) {
if (err) {
logEvent("\n" + err + "\n--------------------");
} else {
logEvent("created new list in db for: ", result[0].alias);
// ...and render it
renderList(result[0]);
}
});
}
}
});
});
// bind app to the listening-port specified by the environment
// or to the default port 4242, used during deveopment
server.listen(process.env.PORT || 4242);
// start socket server of socket.io
var io = socketio.listen(server);
// configure socket.io (use environment flags: 'development' | 'production')
io.configure('production', function () {
io.enable('browser client minification'); // send minified client script
io.enable('browser client etag'); // apply etag caching logic based on version number
io.enable('browser client gzip'); // gzip the file
io.set('log level', 1); // reduce logging
// enable all transports
io.set('transports', [
'websocket'
, 'flashsocket'
, 'htmlfile'
, 'xhr-polling'
, 'jsonp-polling'
]);
});
// listen to connection-request of clients - argument is the clients socket
io.sockets.on('connection', function (socket) {
logEvent("got connection-request from: " + socket.id);
// listen to client sending an alias
socket.on('aliasResponse', function (aliasData, callbackAliasResponse) {
logEvent("got alias: " + aliasData.alias);
// join client to a room (a socket partition for all clients who collaborate on one list)
socket.join(aliasData.alias);
logEvent("joined aliasroom: " + aliasData.alias);
// respond to client and let him attend to the 'conversation' in room
callbackAliasResponse();
// listen to addTask-actions of client
socket.on('addTask', function (taskData) {
logEvent("got task to add: " + taskData.description);
// create new task for taskData on db and send it back to all clients, listening on alias
listdao.addTask(aliasData.alias, taskData.description, function (newTask) {
// respond to client that the task is added
io.sockets.in(aliasData.alias).emit('addedTask', newTask);
});
});
// listen to removeTask-actions of client
socket.on('removeTask', function (taskData) {
listdao.removeTask(aliasData.alias, taskData.id, function () {
// respond to client that the task is removed
io.sockets.in(aliasData.alias).emit('removedTask', taskData.id);
});
});
// listen to changeTaskState-actions of client
socket.on('changeTaskState', function (taskData) {
listdao.changeTaskState(aliasData.alias, taskData.id, taskData.state, function (changedTask) {
// respond to client that the task is changed
io.sockets.in(aliasData.alias).emit('changedTaskState', changedTask);
});
});
});
// listen to disconnection of client bound to 'socket'
socket.on('dissconnect', function () {
// nothing to do on dissconection of client
});
});
// db-worker: clean db from expired lists and inform list-clients
// worker-function runs once every hour
setInterval(function () {
listdao.find(function (err, result) {
for (var i = 0; i < result.length; i++) {
if (moment() >= moment(result[i].expireMoment, 'MM/DD/YYYY', true)) {
listdao.delete(result[i].alias, function () {
io.sockets.in(result[i].alias).emit('deletedList');
});
}
}
});
}, 3600 * 1000);
// make a new random alias
function makeNewAlias(callback) {
var alias = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
for (var i = 0; i < 10; i++)
alias += possible.charAt(Math.floor(Math.random() * possible.length));
// proove generated alias against db...
listdao.findOne(alias, function (err, result) {
if (!result) {
logEvent("made a new alias: " + alias);
// ...and return return it
return callback(alias);
} else {
logEvent("alias already exists - try generating another one");
// ...and call function recursivly in case of already existing alias
makeNewAlias(callback);
}
});
}
function logEvent(msg) {
console.log("CTLNODE: " + msg);
}