sync attach [ok]

todo conflicts copy attach
This commit is contained in:
life
2015-01-31 22:04:20 +08:00
parent c309427fed
commit 00aac7c96a
9 changed files with 301 additions and 60 deletions

3
node_modules/api.js generated vendored
View File

@@ -123,6 +123,8 @@ var Api = {
log(url);
needle.get(url, function(error, response) {
if(error) {
console.log('note/getSyncNotes');
console.log(error);
return callback && callback(false);
}
var ret = response.body;
@@ -380,6 +382,7 @@ var Api = {
var ret = resp.body;
log('add note ret');
log(ret);
log('add note ret<-');
if(Common.isOk(ret)) {
// 将serverId保存
callback(ret);

9
node_modules/file.js generated vendored
View File

@@ -162,13 +162,17 @@ var File = {
},
// 笔记添加/修改后会有LocalFileId <=> FileId映射
updateFileForce: function(files) {
// 这个只对image有用
updateImageForce: function(files) {
if(!files) {
// callback && callback(false);
return;
}
for(var i in files) {
var file = files[i];
if(file.IsAttach) {
continue;
}
if(!file.FileId || !file.LocalFileId) {
continue;
}
@@ -207,6 +211,7 @@ var File = {
Name: rename,
UserId: User.getCurActiveUserId(),
Title: name,
IsDirty: true, // 先添加的肯定是dirty, 什么时候不是dirty ? sync 和 send changes后
Type: ext,
Size: fileStat && fileStat.size,
IsDirty: true, // 本地是新添加的, ServerFileId = 0
@@ -221,7 +226,7 @@ var File = {
// 删除不存在的attachs
deleteNotExistsAttach: function(noteId, attachs) {
var me = this;
console.log('--');
// console.log('--');
Attachs.find({NoteId: noteId}, function(err, everAttachs) {
if(err) {
return;

13
node_modules/needle/lib/multipart.js generated vendored
View File

@@ -41,7 +41,13 @@ var generate_part = function(name, part, boundary, callback) {
if (data) {
var binary = part.content_type.indexOf('text') == -1;
return_part += '; filename="' + encodeURIComponent(filename) + '"\r\n';
// 这里filename被encodeURIComponent, 中文会有问题
// return_part += '; filename="' + encodeURIComponent(filename) + '"\r\n';
// return_part += '; filename="' + filename + '"\r\n';
// 改成这样
return_part += '; filename="' + new Buffer(filename, 'utf8').toString("binary") + '"\r\n';
// return_part += new Buffer(part.value+'', 'utf8').toString("binary");
if (binary) return_part += 'Content-Transfer-Encoding: binary\r\n';
return_part += 'Content-Type: ' + part.content_type + '\r\n\r\n';
return_part += binary ? data.toString('binary') : data.toString('utf8');
@@ -71,7 +77,10 @@ var generate_part = function(name, part, boundary, callback) {
}
return_part += '\r\n\r\n';
return_part += part.value;
// https://github.com/tomas/needle/issues/97
// return_part += part.value;
return_part += new Buffer(part.value+'', 'utf8').toString("binary");
append();
}

252
node_modules/note.js generated vendored
View File

@@ -105,14 +105,6 @@ var Note = {
}
},
// 更新笔记的附件
updateAttach: function(noteId, attachs) {
var me = this;
Notes.update({NoteId: noteId}, {$set: {Attachs: attachs, IsDirty: true}});
// Files, 删除修改了的
File.deleteNotExistsAttach(noteId, attachs);
},
// 获取笔记列表
getNotes: function(notebookId, callback) {
@@ -351,6 +343,21 @@ var Note = {
note.IsDirty = false;
note.ServerNoteId = note.NoteId;
note.NoteId = Common.objectId();
// 附件操作
var files = note.Files || [];
var attachs = [];
for(var i in files) {
var file = files[i];
if(file.IsAttach) { // LocalFileId, FileId
file.ServerFileId = file.FileId;
file.FileId = file.ServerFileId; // 弄成一样的, 只是没有Path
attachs.push(file);
}
}
note.Attachs = attachs;
delete note['Files'];
Notebook.getNotebookIdByServerNotebookId(note.NotebookId, function(localNotebookId) {
note.NotebookId = localNotebookId;
Notes.insert(note, function (err, newDoc) { // Callback is optional
@@ -363,18 +370,108 @@ var Note = {
});
});
},
// 更新笔记本, 合并之, 内容要重新获取
// 删除附件
deleteAttachs: function(attachs) {
var me = this;
var fileBasePath = User.getCurUserAttachsPath();
if(!attachs) {
return;
}
for(var i in attachs) {
var path = attachs[i].Path;
if(path && path.indexOf(fileBasePath) > 0) {
try {
fs.unlink(path);
} catch(e) {
console.log(e);
}
}
}
},
// sync <- 时
// 更新笔记, 合并之, 内容要重新获取
// note是服务器传过来的, 需要处理下fix
// note.NoteId是服务器的
updateNoteForce: function(note, callback) {
var me = this;
note.IsDirty = false;
note.InitSync = true;
note.LocalIsNew = false;
me.getNoteIdByServerNoteId(note.NoteId, function(localNoteId) {
note.NoteId = localNoteId;
// 附件处理
var files = note.Files || [];
var attachsMap = [];
for(var i in files) {
var file = files[i];
if(file.IsAttach) { // LocalFileId, FileId
// 对于服务器上的, 只有FileId会传过来, 此时要与之前的做对比
file.ServerFileId = file.FileId;
delete file['FileId'];
attachsMap[file.ServerFileId] = file;
}
}
// 之前也是有attachs的, 得到之前的attachs, 进行个merge
me.getNoteByServerNoteId(note.NoteId, function(everNote) {
if(!everNote) {
return;
}
var everAttachs = everNote.Attachs;
var everAttachsMap = {};
// var needAdds = [];
// 得到要删除的
var needDeletes = [];
for(var i in everAttachs) {
var everAttach = everAttachs[i];
everAttachsMap[everAttach.ServerFileId] = everAttach;
if(!attachsMap[everAttach.ServerFileId]) {
needDeletes.push(everAttach);
}
}
console.log('everAttachs');
console.log(everAttachs);
console.log('attachsMap')
console.log(attachsMap);
// 通过FileId删除文件
me.deleteAttachs(needDeletes);
// 得到要添加的,所有的
// 新添加的没有Path
var allAttachs = [];
for(var serverFileId in attachsMap) {
if(!everAttachsMap[serverFileId]) {
// needAdds.push(attachMap[serverFileId]);
attachsMap[serverFileId].FileId = serverFileId; // 生成一个Id(一样的), 但是没有Path
allAttachs.push(attachsMap[serverFileId]);
} else {
allAttachs.push(everAttachsMap[serverFileId]);
}
}
note.Attachs = allAttachs;
note.ServerNoteId = note.NoteId;
note.NoteId = everNote.NoteId;
delete note['Files'];
// console.log('evernote');
// console.log(everNote);
// 得到本地笔记本Id
Notebook.getNotebookIdByServerNotebookId(note.NotebookId, function(localNotebookId) {
note['NotebookId'] = localNotebookId;
Notes.update({NoteId: localNoteId}, {$set: note}, {}, function (err, cnt) { // Callback is optional
console.log("updateNoteForce 后的")
console.log(note);
Notes.update({NoteId: note.NoteId}, {$set: note}, {}, function (err, cnt) { // Callback is optional
console.log('re:');
console.log(err);
console.log(cnt);
if(err) {
console.log(err);
callback && callback(false);
@@ -384,7 +481,6 @@ var Note = {
}
});
});
});
},
@@ -395,23 +491,64 @@ var Note = {
note.IsDirty = false;
note.InitSync = false;
note.LocalIsNew = false;
// note.UserId = User.getCurActiveUserId();
//
console.log("updateNoteForceForSendChange");
console.log(note);
// 如果是添加的, 因为不会传内容
if(isAdd) {
delete note['content'];
}
// if(isAdd) {
delete note['Content'];
// }
// 修改LocalFileId <=> FileId的映射
File.updateFileForce(note.Files);
console.log('server data from::::');
console.log(note.NoteId);
console.log(note.Files);
Notes.update({NoteId: note.NoteId}, {$set: note}, function(err, n) {
if(err || !n) {
log('updateNoteForceForSendChange err');
log(err);
return callback && callback(false);
// 修改Imags的LocalFileId <=> FileId的映射
File.updateImageForce(note.Files);
// 修改attach, 建立LocalFileId <=> FileId的映射
var files = note.Files || [];
var filesMap = {}; // LocalFileId => ServerFileId
for(var i in files) {
var file = files[i];
if(file.IsAttach) { // LocalFileId, FileId
filesMap[file.LocalFileId] = file.FileId;
}
return callback && callback(true);
}
// 之前也是有attachs的, 得到之前的attachs, 进行个merge
me.getNote(note.NoteId, function(everNote) {
if(!everNote) {
console.log('我靠, 没有?' + note.NoteId);
return;
}
var everAttachs = everNote.Attachs || [];
for(var i in everAttachs) {
var everAttach = everAttachs[i];
if(filesMap[everAttach.FileId]) {
everAttach.ServerFileId = filesMap[everAttach.FileId];
everAttach.IsDirty = false; // 不为dirty了, 记得在sync后也改为false
}
}
note.Attachs = everAttachs;
console.log('fix after');
console.log(everAttachs);
delete note['Files'];
Notes.update({NoteId: note.NoteId}, {$set: note}, function(err, n) {
if(err || !n) {
log('updateNoteForceForSendChange err');
log(err);
return callback && callback(false);
}
return callback && callback(true);
});
});
},
// 服务器上的数据
@@ -574,15 +711,20 @@ var Note = {
FileId: file.ServerFileId,
LocalFileId: file.FileId,
Type: file.Type,
HasBody: false
}
HasBody: false,
IsAttach: file.IsAttach,
};
// console.log(file);
// 要传数据的
if(file.IsDirty) {
fs.exists(file.Path, function(isExists) {
needTransferFiles[file.FileId] = {
file: file.Path,
content_type: 'image/' + file.Type // TODO
content_type: 'application/' + file.Type // TODO
}
if(file.Title) {
needTransferFiles[file.FileId].filename = file.Title;
}
needFile.HasBody = true;
needPostFilesAttr.push(needFile);
@@ -607,7 +749,7 @@ var Note = {
} else {
// 每一个笔记得到图片, 附件信息和数据
async.eachSeries(notes, function(note, cb) {
me.getNoteFiles(note.NoteId, note.Content, function(files) {
me.getNoteFiles(note, function(files) {
note.Content = me.fixNoteContentForSend(note.Content);
// note.Files = files || [];
me.getFilesPostInfo(files, function(attrs, fileDatas) {
@@ -624,7 +766,19 @@ var Note = {
},
// 得到笔记的文件
getNoteFiles: function(noteId, content, callback) {
getNoteFiles: function(note, callback) {
var noteId = note.NoteId;
var content = note.Content;
// 1. 先得到附件
var attachs = note.Attachs || [];
for(var i in attachs) {
var attach = attachs[i];
attach.IsAttach = true;
}
// 1. 先得到图片
// 得到图片信息, 通过内容
// http://localhost:8002/api/file/getImage?fileId=xxxxxx, 得到fileId, 查询数据库, 得到图片
// console.log(content);
@@ -644,24 +798,14 @@ var Note = {
if(fileIds.length > 0) {
// 得到所有的图片
File.getAllImages(fileIds, function(images) {
callback(images);
/*
if(!images) {
return;
// attach与图片结合
if(images) {
attachs = attachs.concat(images);
}
for(var i in images) {
var image = images[i];
files.push({
localFileId: image.FileId,
fileId: image.ServerFileId,
hasBody: image.IsDirty,
filename: image.Name,
});
}
*/
callback(attachs);
});
} else {
callback(false);
callback(attachs);
}
},
@@ -675,7 +819,25 @@ var Note = {
},
setIsNew: function(noteId) {
Notes.update({NoteId: noteId}, {$set:{LocalIsNew: true, IsDirty: true}})
}
},
//----------------------------------
// Attach
// 有部分操作放在File中了,
// 也有attach表, 但只作添加/删除附件用
//
// 更新笔记的附件
// web只要一个添加了, 删除的, 全部更新
updateAttach: function(noteId, attachs) {
var me = this;
console.log('updateAttach');
console.log(attachs);
Notes.update({NoteId: noteId}, {$set: {Attachs: attachs, IsDirty: true}});
// File, 删除修改了的
File.deleteNotExistsAttach(noteId, attachs);
},
};
module.exports = Note;

10
node_modules/sync.js generated vendored
View File

@@ -310,6 +310,8 @@ var Sync = {
// 同步失败
me._syncInfo.note.ok = false;
me._syncInfo.note.msg = "cann't get all chunks";
console.log(notes);
console.log('eeeeeeeeeeeeeeeeeerrror')
callback && callback(false);
}
});
@@ -375,6 +377,8 @@ var Sync = {
Note.fixConflicts(me._syncInfo.note, me._noteWeb, function() {
// 避免无限循环, 别send changes了
if(!me._needIncrSyncAgain) {
// alert("?")
console.log(">>>>>>>>>>>>>>>>>>>>>>>>>")
// send changes
callback && callback();
}
@@ -555,6 +559,8 @@ var Sync = {
return cb();
});
} else {
console.log('local');
console.log(note);
// 更新
Api.updateNote(note, function(ret) {
if(!Common.isOk(ret)) {
@@ -571,7 +577,9 @@ var Sync = {
}
// 更新成功
// TODO 返回是真note
Note.updateNoteForceForSendChange({NoteId: note.NoteId, Usn: ret.Usn}, false);
ret.ServerNoteId = ret.NoteId;
ret.NoteId = note.NoteId;
Note.updateNoteForceForSendChange(ret, false);
me.checkNeedIncSyncAgain(ret.Usn);

23
node_modules_updates.txt Normal file
View File

@@ -0,0 +1,23 @@
# node_modules
## needle
https://github.com/tomas/needle/issues/97
When i post a file (multipart) with another key-value pair (contains UTF8 characters), my servers got incorrect encoding.
then i see the code in multipart.js (generate_part) is :
return_part += part.value
the value look like in UTF8 encoding but send out with binary encoding
Finally i get the collect UTF8 characters by change to :
return_part += new Buffer(part.value+'', 'utf8').toString("binary");
// filename也有问题
// 这里filename被encodeURIComponent, 中文会有问题
// return_part += '; filename="' + encodeURIComponent(filename) + '"\r\n';
// return_part += '; filename="' + filename + '"\r\n';
// 改成这样
return_part += '; filename="' + new Buffer(filename, 'utf8').toString("binary") + '"\r\n';
// return_part += new Buffer(part.value+'', 'utf8').toString("binary");

View File

@@ -437,9 +437,11 @@ function log(o) {
<form id="uploadAttach" method="post" action="/attach/UploadAttach" enctype="multipart/form-data">
<div id="dropAttach" class="dropzone">
<input id="chooseFileInput" type="file" name="file" multiple/>
<input id="downloadFileInput" type="file" nwsaveas="" style=""/>
<a id="chooseFile" class="btn btn-success btn-choose-file">
<i class="fa fa-upload"></i>
<span>Choose File</span>
<i class="fa fa-upload"></i>
<span>Choose Files</span>
</a>
<a class="btn btn-default" id="downloadAllBtn">
<i class="fa fa-download"></i>

View File

@@ -1606,15 +1606,25 @@ var Attach = {
// 下载
self.attachListO.on("click", ".download-attach", function(e) {
e.stopPropagation();
var attachId = $(this).closest('li').data("id");
window.open(UrlPrefix + "/attach/download?attachId=" + attachId);
var $li = $(this).closest('li');
var attachId = $li.data("id");
$('#downloadFileInput').attr('nwsaveas', $li.find('.attach-title').text()).click();
// window.open(UrlPrefix + "/attach/download?attachId=" + attachId);
// location.href = "/attach/download?attachId=" + attachId;
});
// 下载全部
self.downloadAllBtnO.click(function() {
window.open(UrlPrefix + "/attach/downloadAll?noteId=" + Note.curNoteId);
// window.open(UrlPrefix + "/attach/downloadAll?noteId=" + Note.curNoteId);
// location.href = "/attach/downloadAll?noteId=" + Note.curNoteId;
});
// 下载
$('#downloadFileInput').change(function(e) {
var value = $(this).val();
$(this).val('');
alert(value);
});
// make link
self.attachListO.on("click", ".link-attach", function(e) {
@@ -1646,6 +1656,7 @@ var Attach = {
}
});
// 添加Attach
$('#chooseFile').click(function() {
$('#chooseFileInput').click();
});
@@ -1653,6 +1664,13 @@ var Attach = {
$('#chooseFileInput').change(function() {
var files = $(this).val();
$(this).val('');
// 如果是新建的笔记, 必须先保存note
var note = Note.getCurNote();
if(note && note.IsNew) {
Note.curChangedSaveIt(true);
}
FileService.addAttach(files, Note.curNoteId, function(files) {
if(files) {
me.addAttachs(files);
@@ -1707,11 +1725,18 @@ var Attach = {
console.log(attachs);
for(var i = 0; i < attachNum; ++i) {
var each = attachs[i];
var path = each.Path;
// 本地是否有, 没有, 是否是在显示的时候才去从服务器上抓? 不
if(path) {
var d = '<i class="fa fa-download"></i>';
} else {
d = 'no'
}
html += '<li class="clearfix" data-id="' + each.FileId + '">' +
'<div class="attach-title">' + each.Title + '</div>' +
'<div class="attach-process"> ' +
' <button class="btn btn-sm btn-warning delete-attach" data-loading-text="..."><i class="fa fa-trash-o"></i></button> ' +
' <button type="button" class="btn btn-sm btn-primary download-attach"><i class="fa fa-download"></i></button> ' +
' <button type="button" class="btn btn-sm btn-primary download-attach">' + d + '</button> ' +
' <button type="button" class="btn btn-sm btn-default link-attach" title="Insert link into content"><i class="fa fa-link"></i></button> ' +
'</div>' +
'</li>';

12
test.js
View File

@@ -18,20 +18,24 @@ Api.addNotebook({
*/
// Api.uploadImage();
User.userId = '54bdc65599c37b0da9000002';
Note.getNoteByServerNoteId('54ccc53d99c37bf812000001', function(doc) {
console.log(doc);
});
/*
// console.log(User.getCurActiveUserId());
Note.getDirtyNotes(function(ret) {
console.log(ret);
Api.updateNote(ret[2], function(ret2){
console.log(ret2);
});
// console.log(ret[2]);
/*
Api.addNote(ret[0], function(ret2){
Api.addNote(ret[3], function(ret2){
console.log(ret2);
});
*/
});
*/
/*
Note.getNoteByServerNoteId("54c6313799c37bdeec000008", function(ret){
console.log(ret);