mirror of
https://github.com/leanote/desktop-app.git
synced 2025-10-13 14:34:54 +00:00
send changes for notebook
This commit is contained in:
50
node_modules/api.js
generated
vendored
50
node_modules/api.js
generated
vendored
@@ -218,5 +218,55 @@ var Api = {
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
//------------
|
||||
// 笔记本操作
|
||||
//------------
|
||||
addNotebook: function(notebook, callback) {
|
||||
var me = this;
|
||||
var data = {
|
||||
title: notebook.Title,
|
||||
seq: notebook.Seq,
|
||||
parentNotebookId: notebook.ParentNotebookId
|
||||
}
|
||||
log('add notebook');
|
||||
log(data);
|
||||
needle.post(me.getUrl('notebook/addNotebook'), data, {}, function(err, resp) {
|
||||
if(err) {
|
||||
return callback(false);
|
||||
}
|
||||
var ret = resp.body;
|
||||
log(ret);
|
||||
if(Common.isOk(ret)) {
|
||||
callback(ret);
|
||||
} else {
|
||||
callback(false);
|
||||
}
|
||||
});
|
||||
},
|
||||
updateNotebook: function(notebook, callback) {
|
||||
var me = this;
|
||||
var data = {
|
||||
NotebookId: notebook.NotebookId,
|
||||
Title: notebook.Title,
|
||||
Usn: notebook.Title,
|
||||
Seq: notebook.Seq,
|
||||
ParentNotebookId: notebook.ParentNotebookId
|
||||
}
|
||||
needle.post(me.getUrl('notebook/updateNotebook'), data, {}, function(err, resp) {
|
||||
if(err) {
|
||||
return callback(false);
|
||||
}
|
||||
var ret = resp.body;
|
||||
if(Common.isOk(ret)) {
|
||||
callback(ret);
|
||||
} else {
|
||||
callback(false);
|
||||
}
|
||||
});
|
||||
},
|
||||
deleteNotebook: function(notebook, callback) {
|
||||
var me = this;
|
||||
}
|
||||
};
|
||||
module.exports = Api;
|
||||
|
3
node_modules/async/.travis.yml
generated
vendored
Normal file
3
node_modules/async/.travis.yml
generated
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
language: node_js
|
||||
node_js:
|
||||
- "0.10"
|
19
node_modules/async/LICENSE
generated
vendored
Normal file
19
node_modules/async/LICENSE
generated
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
Copyright (c) 2010-2014 Caolan McMahon
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
1646
node_modules/async/README.md
generated
vendored
Normal file
1646
node_modules/async/README.md
generated
vendored
Normal file
File diff suppressed because it is too large
Load Diff
11
node_modules/async/component.json
generated
vendored
Normal file
11
node_modules/async/component.json
generated
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"name": "async",
|
||||
"repo": "caolan/async",
|
||||
"description": "Higher-order functions and common patterns for asynchronous code",
|
||||
"version": "0.1.23",
|
||||
"keywords": [],
|
||||
"dependencies": {},
|
||||
"development": {},
|
||||
"main": "lib/async.js",
|
||||
"scripts": [ "lib/async.js" ]
|
||||
}
|
1123
node_modules/async/lib/async.js
generated
vendored
Executable file
1123
node_modules/async/lib/async.js
generated
vendored
Executable file
File diff suppressed because it is too large
Load Diff
43
node_modules/async/package.json
generated
vendored
Normal file
43
node_modules/async/package.json
generated
vendored
Normal file
File diff suppressed because one or more lines are too long
18
node_modules/note.js
generated
vendored
18
node_modules/note.js
generated
vendored
@@ -1,3 +1,4 @@
|
||||
var async = require('async');
|
||||
var db = require('db');
|
||||
var User = require('user');
|
||||
var Notebook = require('notebook');
|
||||
@@ -248,6 +249,7 @@ var Note = {
|
||||
updateNoteForce: function(note, callback) {
|
||||
note.IsDirty = false;
|
||||
note.InitSync = true;
|
||||
note.LocalIsNew = false;
|
||||
Notes.update({NoteId: note.NoteId}, {$set: note}, {}, function (err, cnt) { // Callback is optional
|
||||
if(err) {
|
||||
console.log(err);
|
||||
@@ -291,22 +293,30 @@ var Note = {
|
||||
// notes是服务器的数据, 与本地的有冲突
|
||||
// 1) 将本地的note复制一份
|
||||
// 2) 服务器替换之前
|
||||
fixConflicts: function(noteSyncInfo, noteWeb) {
|
||||
fixConflicts: function(noteSyncInfo, noteWeb, callback) {
|
||||
var me = this;
|
||||
// 处理冲突
|
||||
var conflictNotes = noteSyncInfo.conflicts;
|
||||
for(var i in conflictNotes) {
|
||||
var note = conflictNotes[i];
|
||||
log('fix note conflicts');
|
||||
async.eachSeries(conflictNotes, function(note, cb) {
|
||||
var noteId = note.NoteId;
|
||||
// 复制一份
|
||||
me.copyNoteForConfict(noteId, function(newNote) {
|
||||
if(newNote) {
|
||||
// 更新之前的
|
||||
me.updateNoteForce(note, function() {
|
||||
cb();
|
||||
// 前端来处理, 全量sync时不用前端一个个处理
|
||||
noteWeb.fixSyncConflict && noteWeb.fixSyncConflict(note, newNote);
|
||||
});
|
||||
} else {
|
||||
cb();
|
||||
}
|
||||
});
|
||||
}
|
||||
}, function() {
|
||||
// 最后调用
|
||||
callback && callback();
|
||||
});
|
||||
|
||||
// 处理添加的
|
||||
var addNotes = noteSyncInfo.adds;
|
||||
|
39
node_modules/notebook.js
generated
vendored
39
node_modules/notebook.js
generated
vendored
@@ -107,6 +107,7 @@ var Notebook = {
|
||||
Seq: -1,
|
||||
UserId: User.getCurActiveUserId(),
|
||||
ParentNotebookId: parentNotebookId,
|
||||
LocalIsNew: true,
|
||||
IsDirty: true, // 必须, 同步后才为非dirty状态
|
||||
// TODO UrlTitle
|
||||
}
|
||||
@@ -123,6 +124,16 @@ var Notebook = {
|
||||
});
|
||||
},
|
||||
|
||||
// 修改笔记本
|
||||
updateNotebook: function(notebookId, callback) {
|
||||
|
||||
},
|
||||
|
||||
// 删除笔记本
|
||||
deleteNotebook: function(notebookId, callback) {
|
||||
|
||||
},
|
||||
|
||||
// 重新统计笔记本的笔记数据
|
||||
reCountNotebookNumberNotes: function(notebookId) {
|
||||
db.notes.count({NotebookId: notebookId, IsTrash: false}, function(err, count) {
|
||||
@@ -179,6 +190,7 @@ var Notebook = {
|
||||
// 更新笔记本
|
||||
updateNotebookForce: function(notebook, callback) {
|
||||
notebook.IsDirty = false;
|
||||
notebook.LocalIsNew = false;
|
||||
NB.update({NotebookId: notebook.NotebookId}, {$set: notebook}, {}, function (err, updates) { // Callback is optional
|
||||
if(err) {
|
||||
console.log(err);
|
||||
@@ -188,9 +200,34 @@ var Notebook = {
|
||||
}
|
||||
});
|
||||
},
|
||||
// 更新笔记本, NoteId可能也要更改
|
||||
updateNotebookForceForSendChange: function(notebookId, notebook, callback) {
|
||||
notebook.IsDirty = false;
|
||||
notebook.LocalIsNew = false;
|
||||
NB.update({NotebookId: notebookId}, {$set: notebook}, {}, function (err, updates) { // Callback is optional
|
||||
if(err) {
|
||||
console.log(err);
|
||||
callback && callback(false);
|
||||
} else {
|
||||
callback && callback(notebook);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 获得用户修改的笔记本
|
||||
getDirtyNotebooks: function(callback) {
|
||||
NB.find({UserId: User.getCurActiveUserId(), IsDirty: true}, function(err, notebooks) {
|
||||
if(err) {
|
||||
log(err);
|
||||
return callback && callback(false);
|
||||
} else {
|
||||
callback(notebooks);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
fixConflicts: function() {
|
||||
|
||||
|
||||
}
|
||||
};
|
||||
module.exports = Notebook;
|
171
node_modules/sync.js
generated
vendored
171
node_modules/sync.js
generated
vendored
@@ -1,4 +1,5 @@
|
||||
var db = require('db');
|
||||
var async = require('async');
|
||||
var Common = require('common');
|
||||
var User = require('user');
|
||||
var Tags = db.tags;
|
||||
@@ -16,10 +17,18 @@ function log(o) {
|
||||
var Sync = {
|
||||
// 同步的信息, 返回给调用者
|
||||
_syncInfo: {
|
||||
notebook: {changeAdds: [], adds: [], deletes: [], updates: []},
|
||||
note: {changeAdds: [], adds: [], deletes: [], updates: [], conflicts: []},
|
||||
tag: {}
|
||||
},
|
||||
/*
|
||||
_sendInfo: {
|
||||
notebook: {adds: [], deletes: [], updates: []},
|
||||
note: {adds: [], deletes: [], updates: [], conflicts: []},
|
||||
tag: {}
|
||||
},
|
||||
*/
|
||||
_needIncrSyncAgain: false,
|
||||
|
||||
// notebook
|
||||
_syncNotebookIsLastChunk: false,
|
||||
@@ -47,11 +56,23 @@ var Sync = {
|
||||
me._totalHasSyncNoteNum = 0;
|
||||
me._lockNote = 1;
|
||||
|
||||
// 同步信息
|
||||
me._syncInfo = {
|
||||
notebook: {ok: false, changeAdds: [], adds: [], deletes: [], updates: []},
|
||||
note: {ok: false, adds: [], changeAdds: [], deletes: [], updates: [], conflicts: []},
|
||||
tag: {ok: false, adds: [], changeAdds: [], deletes: [], updates: [], conflicts: []},
|
||||
};
|
||||
|
||||
// 发送改变信息
|
||||
/*
|
||||
me._sendInfo = {
|
||||
notebook: {ok: false, adds: [], deletes: [], updates: []},
|
||||
note: {ok: false, adds: [], deletes: [], updates: [], conflicts: []},
|
||||
tag: {ok: false}
|
||||
};
|
||||
*/
|
||||
// 是否还要来一次增量同步 ?
|
||||
me._needIncrSyncAgain = false;
|
||||
},
|
||||
|
||||
//---------------
|
||||
@@ -295,9 +316,11 @@ var Sync = {
|
||||
},
|
||||
|
||||
// 记录LastSyncUsn, LastUpdateTime 同步时间
|
||||
updateLastSyncState: function() {
|
||||
updateLastSyncState: function(callback) {
|
||||
var me = this;
|
||||
User.updateLastSyncState();
|
||||
User.updateLastSyncState(function() {
|
||||
callback();
|
||||
});
|
||||
},
|
||||
|
||||
// 全量同步
|
||||
@@ -315,10 +338,10 @@ var Sync = {
|
||||
// 同步标签
|
||||
me.syncTag(-1, function() {
|
||||
// 更新上次同步时间
|
||||
me.updateLastSyncState();
|
||||
|
||||
// send changes
|
||||
me.sendChanges(callback);
|
||||
me.updateLastSyncState(function() {
|
||||
// send changes
|
||||
me.sendChanges();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
callback && callback(me._syncInfo);
|
||||
@@ -334,13 +357,19 @@ var Sync = {
|
||||
_notebookWeb: null,
|
||||
_noteWeb: null,
|
||||
// 处理冲突
|
||||
fixConflicts: function() {
|
||||
fixConflicts: function(callback) {
|
||||
var me = this;
|
||||
log('--------------')
|
||||
var afterInfo = me._syncInfo;
|
||||
log('处理冲突....')
|
||||
log(me._syncInfo);
|
||||
log(me._syncInfo.note.updates);
|
||||
Notebook.fixConflicts(me._syncInfo.notebook, me._notebookWeb);
|
||||
Note.fixConflicts(me._syncInfo.note, me._noteWeb);
|
||||
Note.fixConflicts(me._syncInfo.note, me._noteWeb, function() {
|
||||
// 避免无限循环, 别send changes了
|
||||
if(!me._needIncrSyncAgain) {
|
||||
// send changes
|
||||
callback && callback();
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 增量同步
|
||||
@@ -370,12 +399,11 @@ var Sync = {
|
||||
// 同步标签
|
||||
me.syncTag(lastSyncUsn, function() {
|
||||
log('-------incr tag ok-----------')
|
||||
|
||||
// 更新上次同步时间
|
||||
me.updateLastSyncState();
|
||||
|
||||
// send changes
|
||||
me.sendChanges();
|
||||
me.updateLastSyncState(function() {
|
||||
// send changes
|
||||
me.sendChanges();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
log('-------incr note not ok-----------')
|
||||
@@ -389,13 +417,118 @@ var Sync = {
|
||||
});
|
||||
},
|
||||
|
||||
//---------
|
||||
// 发送改变
|
||||
sendChanges: function(callback) {
|
||||
var me = this;
|
||||
// 先处理冲突
|
||||
me.fixConflicts();
|
||||
//---------
|
||||
|
||||
// 发送笔记本的更改
|
||||
sendNotebookChanges: function(callback) {
|
||||
var me = this;
|
||||
// 获取所有笔记本的更改
|
||||
Notebook.getDirtyNotebooks(function(notebooks) {
|
||||
log('dirty notebooks');
|
||||
log(notebooks);
|
||||
if(!notebooks) {
|
||||
callback && callback();
|
||||
} else {
|
||||
// 调api, 所有执行后再callback();
|
||||
// 一个一个同步执行, 因为要有
|
||||
async.eachSeries(notebooks, function(notebook, cb) {
|
||||
var api = Api.updateNotebook;
|
||||
if(notebook.LocalIsNew) {
|
||||
api = Api.addNotebook;
|
||||
} else if(notebook.LocalIsDelete) {
|
||||
api = Api.deleteNotebook;
|
||||
}
|
||||
|
||||
api.call(Api, notebook, function(newNotebook) {
|
||||
// 更新失败
|
||||
if(!newNotebook) {
|
||||
return cb();
|
||||
}
|
||||
// 更新成功, 是否有冲突?
|
||||
// newNotebook是服务器上的笔记本
|
||||
// 没有更新成功
|
||||
if(!newNotebook.NotebookId) {
|
||||
if(newNotebook.Msg == 'conflict') {
|
||||
me._syncInfo.notebook.conflicts.push(newNotebook);
|
||||
// me._sendInfo.notebook.conflicts.push(newNotebook);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// 更新
|
||||
Notebook.updateNotebookForceForSendChange(notebook.NotebookId, newNotebook);
|
||||
|
||||
if(notebook.LocalIsNew) {
|
||||
newNotebook.OldNotebookId = notebook.NotebookId;
|
||||
me._syncInfo.notebook.changeAdds.push(newNotebook);
|
||||
// me._sendInfo.notebook.adds.push(newNotebook);
|
||||
} else {
|
||||
me._syncInfo.notebook.updates.push(newNotebook);
|
||||
// me._sendInfo.notebook.updates.push(newNotebook);
|
||||
}
|
||||
}
|
||||
// 如果之前都很正常
|
||||
if(!me._needIncrSyncAgain) {
|
||||
// 检查是否有问题
|
||||
if(User.getLastSyncUsn() + 1 == newNotebook.Usn) {
|
||||
// 更新到本地lastSyncUsn
|
||||
User.updateLastSyncUsn(newNotebook.Usn);
|
||||
} else {
|
||||
// newNotebook.Usn > User.getLastSyncUsn + 1, 表示服务器端在本次同步后, sendChanges之前有更新
|
||||
// 那么, 还需要来一次incrSync, 之后
|
||||
me._needIncrSyncAgain = true;
|
||||
}
|
||||
}
|
||||
cb();
|
||||
});
|
||||
}, function() {
|
||||
callback && callback();
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
// 发送笔记改变
|
||||
sendNoteChanges: function(callback) {
|
||||
log('send note changes');
|
||||
callback && callback();
|
||||
},
|
||||
// 发送标签改变
|
||||
sendTagChanges: function(callback) {
|
||||
log('send note changes');
|
||||
callback && callback();
|
||||
},
|
||||
|
||||
sendChanges: function() {
|
||||
var me = this;
|
||||
log('send changes before...')
|
||||
// 先处理冲突, 可以同时进行
|
||||
me.fixConflicts(function() {
|
||||
// send changes
|
||||
log('send changes');
|
||||
me._initSyncInfo(); // 重新初始化[]
|
||||
async.series([
|
||||
function(cb) {
|
||||
me.sendNotebookChanges(cb);
|
||||
},
|
||||
function(cb) {
|
||||
me.sendNoteChanges(cb);
|
||||
},
|
||||
function(cb) {
|
||||
me.sendTagChanges(cb);
|
||||
}
|
||||
], function() {
|
||||
// 重新再来一次增量同步
|
||||
if(me._needIncrSyncAgain) {
|
||||
log('-- _needIncrSyncAgain -- ')
|
||||
me.incrSync(me._notebookWeb, me._noteWeb);
|
||||
} else {
|
||||
log('send changes 后解决冲突');
|
||||
me.fixConflicts();
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
17
node_modules/user.js
generated
vendored
17
node_modules/user.js
generated
vendored
@@ -125,7 +125,7 @@ User = {
|
||||
},
|
||||
|
||||
// 同步后更新同步状态
|
||||
updateLastSyncState: function() {
|
||||
updateLastSyncState: function(callback) {
|
||||
var me = this;
|
||||
if(!Api) {
|
||||
Api = require('api');
|
||||
@@ -133,9 +133,24 @@ User = {
|
||||
log('--updateLastSyncState---')
|
||||
Api.getLastSyncState(function(state) {
|
||||
if(state) {
|
||||
me.LastSyncUsn = state.LastSyncUsn;
|
||||
me.LastSyncTime = state.LastSyncTime;
|
||||
db.users.update({UserId: me.getCurActiveUserId()}, {$set: state});
|
||||
}
|
||||
callback();
|
||||
});
|
||||
},
|
||||
|
||||
// send changes要用
|
||||
getLastSyncUsn: function() {
|
||||
var me = this;
|
||||
return me.LastSyncUsn;
|
||||
},
|
||||
// 更新 send changes要用
|
||||
updateLastSyncUsn: function(usn) {
|
||||
var me = this;
|
||||
me.LastSyncUsn = usn;
|
||||
db.users.update({UserId: me.getCurActiveUserId()}, {$set: {LastSyncUsn: usn}});
|
||||
}
|
||||
};
|
||||
|
||||
|
12
test.js
12
test.js
@@ -12,11 +12,13 @@ Notebook.addNotebook("3", "工作");
|
||||
Notebook.addNotebook("4", "life2", "1");
|
||||
*/
|
||||
|
||||
// Notebook.reCountNotebookNumberNotes('54bb2e89c596f2239a000000');
|
||||
Api.addNotebook({
|
||||
Title: "哈哈"
|
||||
}, function() {});
|
||||
|
||||
|
||||
// Api.auth('c@a.com', 'abc123');
|
||||
var content = '<img src="http://localhost:9000/api/file/getImage?fileId=54c2083f99c37bea5f000001"> <img src="http://localhost:9000/api/file/getImage?fileId=54c2083f99c37bea5f000001">' + "\n" + '<img src="http://localhost:9000/api/file/getImage?fileId=54c2083f99c37bea5f000001">';
|
||||
var reg = new RegExp('<img *src="' + Api.leanoteUrl + '/api/file/getImage', 'g');
|
||||
content = content.replace(reg, '<img src="' + Server.localUrl + '/api/file/getImage');
|
||||
console.log(content);
|
||||
// var content = '<img src="http://localhost:9000/api/file/getImage?fileId=54c2083f99c37bea5f000001"> <img src="http://localhost:9000/api/file/getImage?fileId=54c2083f99c37bea5f000001">' + "\n" + '<img src="http://localhost:9000/api/file/getImage?fileId=54c2083f99c37bea5f000001">';
|
||||
// var reg = new RegExp('<img *src="' + Api.leanoteUrl + '/api/file/getImage', 'g');
|
||||
// content = content.replace(reg, '<img src="' + Server.localUrl + '/api/file/getImage');
|
||||
// console.log(content);
|
||||
|
Reference in New Issue
Block a user