Skip to content

Commit fca9257

Browse files
committed
Added warning if imported file overwrites local files.
1 parent 25bfe6b commit fca9257

File tree

3 files changed

+150
-20
lines changed

3 files changed

+150
-20
lines changed

src/filesystem/impls/filer/ArchiveUtils.js

Lines changed: 99 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,15 @@ define(function (require, exports, module) {
1616
var Buffer = Filer.Buffer;
1717
var Path = Filer.Path;
1818
var fs = Filer.fs();
19+
var Dialogs = require("widgets/Dialogs");
20+
var DefaultDialogs = require("widgets/DefaultDialogs");
21+
var Strings = require("strings");
22+
var StringUtils = require("utils/StringUtils");
23+
24+
// These are const variables
25+
var CANCEL_OPERATION = -1,
26+
OVERWRITE_OPERATION = 1,
27+
KEEP_EXISTING_OPERATION = 2;
1928

2029
// Mac and Windows clutter zip files with extra files/folders we don't need
2130
function skipFile(filename) {
@@ -57,6 +66,49 @@ define(function (require, exports, module) {
5766
});
5867
}
5968

69+
function showOverwriteWarning(path, callback) {
70+
var filepath = stripRoot(path);
71+
Dialogs.showModalDialog(
72+
DefaultDialogs.DIALOG_ID_INFO,
73+
Strings.FILE_EXISTS_HEADER,
74+
StringUtils.format(Strings.DND_FILE_REPLACE, filepath),
75+
[
76+
{
77+
className : Dialogs.DIALOG_BTN_CLASS_NORMAL,
78+
id : Dialogs.DIALOG_BTN_CANCEL,
79+
text : Strings.CANCEL
80+
},
81+
{
82+
className : Dialogs.DIALOG_BTN_CLASS_NORMAL,
83+
id : Dialogs.DIALOG_BTN_IMPORT,
84+
text : Strings.USE_IMPORTED
85+
},
86+
{
87+
className : Dialogs.DIALOG_BTN_CLASS_PRIMARY,
88+
id : Dialogs.DIALOG_BTN_OK,
89+
text : Strings.KEEP_EXISTING
90+
}
91+
]
92+
).getPromise().then(function (id) {
93+
var result;
94+
if (id === Dialogs.DIALOG_BTN_IMPORT) {
95+
result = OVERWRITE_OPERATION;
96+
} else if (id === Dialogs.DIALOG_BTN_OK) {
97+
result = KEEP_EXISTING_OPERATION;
98+
} else if (id === Dialogs.DIALOG_BTN_CANCEL) {
99+
result = CANCEL_OPERATION;
100+
}
101+
callback(null, result);
102+
}, callback);
103+
}
104+
105+
function stripRoot(path) {
106+
var root = StartupState.project("root");
107+
var rootRegex = new RegExp("^" + root + "\/?");
108+
109+
return path.replace(rootRegex, "");
110+
}
111+
60112
// zipfile can be a path (string) to a zipfile, or raw binary data.
61113
function unzip(zipfile, options, callback) {
62114
if(typeof options === 'function') {
@@ -100,21 +152,30 @@ define(function (require, exports, module) {
100152
} else {
101153
// XXX: some zip files don't seem to be structured such that dirs
102154
// get created before files. Create base dir if not there yet.
103-
fs.stat(basedir, function(err, stats) {
104-
if(err) {
105-
if(err.code !== "ENOENT") {
106-
return callback(err);
107-
}
108-
109-
fs.mkdirp(basedir, function(err) {
110-
if(err) {
111-
return callback(err);
112-
}
113-
fs.writeFile(path.absPath, path.data, callback);
114-
});
115-
} else {
116-
fs.writeFile(path.absPath, path.data, callback);
155+
fs.mkdirp(basedir, function (err) {
156+
if (err) {
157+
return callback(err);
117158
}
159+
fs.stat(path.absPath, function(err, stats) {
160+
if(err && err.code !== "ENOENT") {
161+
return callback(err);
162+
}
163+
if (stats.type === "FILE") {
164+
showOverwriteWarning(path.absPath, function (err, result) {
165+
if (err) {
166+
return callback(err);
167+
}
168+
169+
if (result === OVERWRITE_OPERATION) {
170+
fs.writeFile(path.absPath, path.data, callback);
171+
} else if (result === KEEP_EXISTING_OPERATION) {
172+
callback();
173+
} else if (result === CANCEL_OPERATION) {
174+
callback(new Error("Operation Cancelled"));
175+
}
176+
});
177+
}
178+
});
118179
});
119180
}
120181
}
@@ -227,11 +288,33 @@ define(function (require, exports, module) {
227288
}
228289

229290
fs.mkdirp(basedir, function(err) {
230-
if(err && err.code !== "EEXIST") {
291+
if(err) {
231292
return callback(err);
232293
}
233294

234-
fs.writeFile(path, new Buffer(data), {encoding: null}, callback);
295+
fs.stat(path, function (err, stats) {
296+
if (err && err.code !== "ENOENT") {
297+
return callback(err);
298+
}
299+
300+
if (stats.type !== "FILE") {
301+
return callback();
302+
}
303+
304+
showOverwriteWarning(path, function (err, result) {
305+
if (err) {
306+
return callback(err);
307+
}
308+
309+
if (result === OVERWRITE_OPERATION) {
310+
fs.writeFile(path, new Buffer(data), {encoding: null}, callback);
311+
} else if (result === KEEP_EXISTING_OPERATION) {
312+
return callback();
313+
} else if (result === CANCEL_OPERATION) {
314+
callback(new Error("Operation Cancelled"));
315+
}
316+
});
317+
});
235318
});
236319
}
237320

src/filesystem/impls/filer/lib/WebKitFileImport.js

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ define(function (require, exports, module) {
3838
StringUtils = require("utils/StringUtils"),
3939
Filer = require("filesystem/impls/filer/BracketsFiler"),
4040
Path = Filer.Path,
41+
fs = Filer.fs(),
4142
Content = require("filesystem/impls/filer/lib/content"),
4243
LanguageManager = require("language/LanguageManager"),
4344
StartupState = require("bramble/StartupState"),
@@ -134,13 +135,13 @@ define(function (require, exports, module) {
134135
});
135136
}
136137

137-
function handleRegularFile(deferred, file, filename, buffer, encoding) {
138+
function saveFile(deferred, file, filename, buffer, encoding) {
138139
file.write(buffer, {encoding: encoding}, function(err) {
139140
if (err) {
140141
onError(deferred, filename, err);
141142
return;
142143
}
143-
144+
144145
// See if this file is worth trying to open in the editor or not
145146
if(shouldOpenFile(filename, encoding)) {
146147
pathList.push(filename);
@@ -150,11 +151,55 @@ define(function (require, exports, module) {
150151
});
151152
}
152153

154+
function handleRegularFile(deferred, file, filename, buffer, encoding) {
155+
fs.exists(filename, function(doesExist) {
156+
if (doesExist) {
157+
console.log("File: ", filename, " already exists!");
158+
159+
// File exists. Prompt user for action
160+
Dialogs.showModalDialog(
161+
DefaultDialogs.DIALOG_ID_INFO,
162+
Strings.FILE_EXISTS_HEADER,
163+
StringUtils.format(Strings.DND_FILE_REPLACE, FileUtils.getBaseName(filename)),
164+
[
165+
{
166+
className : Dialogs.DIALOG_BTN_CLASS_NORMAL,
167+
id : Dialogs.DIALOG_BTN_CANCEL,
168+
text : Strings.CANCEL
169+
},
170+
{
171+
className : Dialogs.DIALOG_BTN_CLASS_NORMAL,
172+
id : Dialogs.DIALOG_BTN_IMPORT,
173+
text : Strings.USE_IMPORTED
174+
},
175+
{
176+
className : Dialogs.DIALOG_BTN_CLASS_PRIMARY,
177+
id : Dialogs.DIALOG_BTN_OK,
178+
text : Strings.KEEP_EXISTING
179+
}
180+
]
181+
)
182+
.done(function(id) {
183+
if (id === Dialogs.DIALOG_BTN_IMPORT) {
184+
// Override file per user's request
185+
saveFile(deferred, file, filename, buffer, encoding);
186+
}
187+
});
188+
} else {
189+
// File doesn't exist. Save without prompt
190+
saveFile(deferred, file, filename, buffer, encoding);
191+
}
192+
});
193+
}
194+
153195
function handleZipFile(deferred, file, filename, buffer, encoding) {
154196
var basename = Path.basename(filename);
155197

156198
ArchiveUtils.unzip(buffer, { root: parentPath }, function(err) {
157199
if (err) {
200+
if (err.message === "Operation Cancelled") {
201+
return deferred.resolve();
202+
}
158203
onError(deferred, filename, new Error(Strings.DND_ERROR_UNZIP));
159204
return;
160205
}
@@ -168,6 +213,9 @@ define(function (require, exports, module) {
168213

169214
ArchiveUtils.untar(buffer, { root: parentPath }, function(err) {
170215
if (err) {
216+
if (err.message === "Operation Cancelled") {
217+
return deferred.resolve();
218+
}
171219
onError(deferred, filename, new Error(Strings.DND_ERROR_UNTAR));
172220
return;
173221
}

src/utils/DragAndDrop.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,6 @@ define(function (require, exports, module) {
4747
// this is the path they want to use as a parent dir root.
4848
var _dropPathHint;
4949

50-
5150
/**
5251
* Returns true if the drag and drop items contains valid drop objects.
5352
* @param {Array.<DataTransferItem>} items Array of items being dragged
@@ -141,7 +140,6 @@ define(function (require, exports, module) {
141140

142141
return Async.doInParallel(paths, function (path, idx) {
143142
var result = new $.Deferred();
144-
145143
// Only open files.
146144
FileSystem.resolve(path, function (err, item) {
147145
if (!err && item.isFile) {
@@ -183,6 +181,7 @@ define(function (require, exports, module) {
183181
return result.promise();
184182
}, false)
185183
.fail(function () {
184+
console.log("fail");
186185
function errorToString(err) {
187186
if (err === ERR_MULTIPLE_ITEMS_WITH_DIR) {
188187
return Strings.ERROR_MIXED_DRAGDROP;

0 commit comments

Comments
 (0)