Skip to content

Commit 2ecec3b

Browse files
committed
Support show last change user with profile and support YAML config inside the note with robots, lang, dir, breaks options
1 parent 1672df3 commit 2ecec3b

18 files changed

Lines changed: 546 additions & 167 deletions

bower.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
"handlebars": "~4.0.5",
3030
"js-url": "~2.0.2",
3131
"socket.io-client": "~1.3.7",
32-
"viz.js": "~1.3.0"
32+
"viz.js": "~1.3.0",
33+
"js-yaml": "~3.4.6"
3334
}
3435
}

lib/note.js

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ var model = mongoose.model('note', {
2626
type: String,
2727
enum: permissionTypes
2828
},
29+
lastchangeuser: {
30+
type: Schema.Types.ObjectId,
31+
ref: 'user'
32+
},
2933
viewcount: {
3034
type: Number,
3135
default: 0
@@ -45,7 +49,8 @@ var note = {
4549
getNoteTitle: getNoteTitle,
4650
generateWebTitle: generateWebTitle,
4751
increaseViewCount: increaseViewCount,
48-
updatePermission: updatePermission
52+
updatePermission: updatePermission,
53+
updateLastChangeUser: updateLastChangeUser
4954
};
5055

5156
function checkNoteIdValid(noteId) {
@@ -198,4 +203,18 @@ function updatePermission(note, permission, callback) {
198203
});
199204
}
200205

206+
function updateLastChangeUser(note, lastchangeuser, callback) {
207+
note.lastchangeuser = lastchangeuser;
208+
note.updated = Date.now();
209+
note.save(function (err) {
210+
if (err) {
211+
logger.error('update note lastchangeuser failed: ' + err);
212+
callback(err, null);
213+
} else {
214+
logger.info("update note lastchangeuser success: " + note.id);
215+
callback(null, note);
216+
};
217+
});
218+
}
219+
201220
module.exports = note;

lib/realtime.js

Lines changed: 124 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ var shortId = require('shortid');
99
var randomcolor = require("randomcolor");
1010
var Chance = require('chance'),
1111
chance = new Chance();
12-
var md5 = require("blueimp-md5").md5;
1312
var moment = require('moment');
1413

1514
//core
@@ -68,7 +67,9 @@ function secure(socket, next) {
6867

6968
function emitCheck(note) {
7069
var out = {
71-
updatetime: note.updatetime
70+
updatetime: note.updatetime,
71+
lastchangeuser: note.lastchangeuser,
72+
lastchangeuserprofile: note.lastchangeuserprofile
7273
};
7374
realtime.io.to(note.id).emit('check', out);
7475
/*
@@ -89,18 +90,52 @@ var updater = setInterval(function () {
8990
if (note.server.isDirty) {
9091
if (config.debug)
9192
logger.info("updater found dirty note: " + key);
92-
var body = note.server.document;
93-
var title = Note.getNoteTitle(body);
94-
title = LZString.compressToBase64(title);
95-
body = LZString.compressToBase64(body);
96-
db.saveToDB(key, title, body, function (err, result) {
97-
if (err) return;
98-
note.server.isDirty = false;
99-
note.updatetime = Date.now();
100-
emitCheck(note);
93+
Note.findNote(note.id, function (err, _note) {
94+
if (err || !_note) return callback(err, null);
95+
//mongo update
96+
if (note.lastchangeuser && _note.lastchangeuser != note.lastchangeuser) {
97+
var lastchangeuser = note.lastchangeuser;
98+
var lastchangeuserprofile = null;
99+
User.findUser(lastchangeuser, function (err, user) {
100+
if (err) return callback(err, null);
101+
if (user && user.profile) {
102+
var profile = JSON.parse(user.profile);
103+
if (profile) {
104+
lastchangeuserprofile = {
105+
name: profile.displayName || profile.username,
106+
photo: User.parsePhotoByProfile(profile)
107+
}
108+
note.lastchangeuser = lastchangeuser;
109+
note.lastchangeuserprofile = lastchangeuserprofile;
110+
Note.updateLastChangeUser(_note, lastchangeuser, function (err, result) {
111+
if (err) return callback(err, null);
112+
});
113+
}
114+
}
115+
});
116+
} else {
117+
note.lastchangeuser = null;
118+
note.lastchangeuserprofile = null;
119+
Note.updateLastChangeUser(_note, null, function (err, result) {
120+
if (err) return callback(err, null);
121+
});
122+
}
123+
//postgres update
124+
var body = note.server.document;
125+
var title = Note.getNoteTitle(body);
126+
title = LZString.compressToBase64(title);
127+
body = LZString.compressToBase64(body);
128+
db.saveToDB(key, title, body, function (err, result) {
129+
if (err) return callback(err, null);
130+
note.server.isDirty = false;
131+
note.updatetime = Date.now();
132+
emitCheck(note);
133+
callback(null, null);
134+
});
101135
});
136+
} else {
137+
callback(null, null);
102138
}
103-
callback();
104139
}, function (err) {
105140
if (err) return logger.error('updater error', err);
106141
});
@@ -121,7 +156,7 @@ var cleaner = setInterval(function () {
121156
disconnectSocketQueue.push(socket);
122157
disconnect(socket);
123158
}
124-
callback();
159+
callback(null, null);
125160
}, function (err) {
126161
if (err) return logger.error('cleaner error', err);
127162
});
@@ -250,7 +285,11 @@ function emitRefresh(socket) {
250285
socket.emit('refresh', {
251286
docmaxlength: config.documentmaxlength,
252287
owner: note.owner,
288+
ownerprofile: note.ownerprofile,
289+
lastchangeuser: note.lastchangeuser,
290+
lastchangeuserprofile: note.lastchangeuserprofile,
253291
permission: note.permission,
292+
createtime: note.createtime,
254293
updatetime: note.updatetime
255294
});
256295
}
@@ -321,32 +360,80 @@ function startConnection(socket) {
321360
isConnectionBusy = false;
322361
return logger.error(err);
323362
}
363+
324364
var owner = data.rows[0].owner;
365+
var ownerprofile = null;
325366
var permission = "freely";
326367
if (owner && owner != "null") {
327368
permission = "editable";
328369
}
370+
371+
//find or new note
329372
Note.findOrNewNote(notename, permission, function (err, note) {
330373
if (err) {
331374
responseError(res, "404", "Not Found", "oops.");
332375
clearSocketQueue(connectionSocketQueue, socket);
333376
isConnectionBusy = false;
334377
return;
335378
}
379+
336380
var body = LZString.decompressFromBase64(data.rows[0].content);
337381
//body = LZString.compressToUTF16(body);
382+
var createtime = data.rows[0].create_time;
338383
var updatetime = data.rows[0].update_time;
339384
var server = new ot.EditorSocketIOServer(body, [], notename, ifMayEdit);
385+
386+
var lastchangeuser = note.lastchangeuser || null;
387+
var lastchangeuserprofile = null;
388+
340389
notes[notename] = {
341390
id: notename,
342391
owner: owner,
392+
ownerprofile: ownerprofile,
343393
permission: note.permission,
394+
lastchangeuser: lastchangeuser,
395+
lastchangeuserprofile: lastchangeuserprofile,
344396
socks: [],
345397
users: {},
398+
createtime: moment(createtime).valueOf(),
346399
updatetime: moment(updatetime).valueOf(),
347400
server: server
348401
};
349-
finishConnection(socket, notes[notename], users[socket.id]);
402+
403+
if (lastchangeuser) {
404+
//find last change user profile if lastchangeuser exists
405+
User.findUser(lastchangeuser, function (err, user) {
406+
if (!err && user && user.profile) {
407+
var profile = JSON.parse(user.profile);
408+
if (profile) {
409+
lastchangeuserprofile = {
410+
name: profile.displayName || profile.username,
411+
photo: User.parsePhotoByProfile(profile)
412+
}
413+
notes[notename].lastchangeuserprofile = lastchangeuserprofile;
414+
}
415+
}
416+
});
417+
}
418+
419+
if (owner && owner != "null") {
420+
//find owner profile if owner exists
421+
User.findUser(owner, function (err, user) {
422+
if (!err && user && user.profile) {
423+
var profile = JSON.parse(user.profile);
424+
if (profile) {
425+
ownerprofile = {
426+
name: profile.displayName || profile.username,
427+
photo: User.parsePhotoByProfile(profile)
428+
}
429+
notes[notename].ownerprofile = ownerprofile;
430+
}
431+
}
432+
finishConnection(socket, notes[notename], users[socket.id]);
433+
});
434+
} else {
435+
finishConnection(socket, notes[notename], users[socket.id]);
436+
}
350437
});
351438
});
352439
} else {
@@ -433,23 +520,7 @@ function updateUserData(socket, user) {
433520
//retrieve user data from passport
434521
if (socket.request.user && socket.request.user.logged_in) {
435522
var profile = JSON.parse(socket.request.user.profile);
436-
var photo = null;
437-
switch (profile.provider) {
438-
case "facebook":
439-
photo = 'https://graph.facebook.com/' + profile.id + '/picture';
440-
break;
441-
case "twitter":
442-
photo = profile.photos[0].value;
443-
break;
444-
case "github":
445-
photo = 'https://avatars.githubusercontent.com/u/' + profile.id + '?s=48';
446-
break;
447-
case "dropbox":
448-
//no image api provided, use gravatar
449-
photo = 'https://www.gravatar.com/avatar/' + md5(profile.emails[0].value);
450-
break;
451-
}
452-
user.photo = photo;
523+
user.photo = User.parsePhotoByProfile(profile);
453524
user.name = profile.displayName || profile.username;
454525
user.userid = socket.request.user._id;
455526
user.login = true;
@@ -466,19 +537,28 @@ function ifMayEdit(socket, callback) {
466537
var note = notes[notename];
467538
var mayEdit = true;
468539
switch (note.permission) {
469-
case "freely":
470-
//not blocking anyone
471-
break;
472-
case "editable":
473-
//only login user can change
474-
if (!socket.request.user || !socket.request.user.logged_in)
475-
mayEdit = false;
476-
break;
477-
case "locked":
478-
//only owner can change
479-
if (note.owner != socket.request.user._id)
480-
mayEdit = false;
481-
break;
540+
case "freely":
541+
//not blocking anyone
542+
break;
543+
case "editable":
544+
//only login user can change
545+
if (!socket.request.user || !socket.request.user.logged_in)
546+
mayEdit = false;
547+
break;
548+
case "locked":
549+
//only owner can change
550+
if (note.owner != socket.request.user._id)
551+
mayEdit = false;
552+
break;
553+
}
554+
//if user may edit and this note have owner (not anonymous usage)
555+
if (mayEdit && note.owner && note.owner != "null") {
556+
//save for the last change user id
557+
if (socket.request.user && socket.request.user.logged_in) {
558+
note.lastchangeuser = socket.request.user._id;
559+
} else {
560+
note.lastchangeuser = null;
561+
}
482562
}
483563
callback(mayEdit);
484564
}

0 commit comments

Comments
 (0)