Skip to content

Commit

Permalink
Added warning if imported file overwrites local files.
Browse files Browse the repository at this point in the history
  • Loading branch information
sdalmeida committed May 12, 2017
1 parent 25bfe6b commit fca9257
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 20 deletions.
115 changes: 99 additions & 16 deletions src/filesystem/impls/filer/ArchiveUtils.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,15 @@ define(function (require, exports, module) {
var Buffer = Filer.Buffer;
var Path = Filer.Path;
var fs = Filer.fs();
var Dialogs = require("widgets/Dialogs");
var DefaultDialogs = require("widgets/DefaultDialogs");
var Strings = require("strings");
var StringUtils = require("utils/StringUtils");

// These are const variables
var CANCEL_OPERATION = -1,
OVERWRITE_OPERATION = 1,
KEEP_EXISTING_OPERATION = 2;

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

function showOverwriteWarning(path, callback) {
var filepath = stripRoot(path);
Dialogs.showModalDialog(
DefaultDialogs.DIALOG_ID_INFO,
Strings.FILE_EXISTS_HEADER,
StringUtils.format(Strings.DND_FILE_REPLACE, filepath),
[
{
className : Dialogs.DIALOG_BTN_CLASS_NORMAL,
id : Dialogs.DIALOG_BTN_CANCEL,
text : Strings.CANCEL
},
{
className : Dialogs.DIALOG_BTN_CLASS_NORMAL,
id : Dialogs.DIALOG_BTN_IMPORT,
text : Strings.USE_IMPORTED
},
{
className : Dialogs.DIALOG_BTN_CLASS_PRIMARY,
id : Dialogs.DIALOG_BTN_OK,
text : Strings.KEEP_EXISTING
}
]
).getPromise().then(function (id) {
var result;
if (id === Dialogs.DIALOG_BTN_IMPORT) {
result = OVERWRITE_OPERATION;
} else if (id === Dialogs.DIALOG_BTN_OK) {
result = KEEP_EXISTING_OPERATION;
} else if (id === Dialogs.DIALOG_BTN_CANCEL) {
result = CANCEL_OPERATION;
}
callback(null, result);
}, callback);
}

function stripRoot(path) {
var root = StartupState.project("root");
var rootRegex = new RegExp("^" + root + "\/?");

return path.replace(rootRegex, "");
}

// zipfile can be a path (string) to a zipfile, or raw binary data.
function unzip(zipfile, options, callback) {
if(typeof options === 'function') {
Expand Down Expand Up @@ -100,21 +152,30 @@ define(function (require, exports, module) {
} else {
// XXX: some zip files don't seem to be structured such that dirs
// get created before files. Create base dir if not there yet.
fs.stat(basedir, function(err, stats) {
if(err) {
if(err.code !== "ENOENT") {
return callback(err);
}

fs.mkdirp(basedir, function(err) {
if(err) {
return callback(err);
}
fs.writeFile(path.absPath, path.data, callback);
});
} else {
fs.writeFile(path.absPath, path.data, callback);
fs.mkdirp(basedir, function (err) {
if (err) {
return callback(err);
}
fs.stat(path.absPath, function(err, stats) {
if(err && err.code !== "ENOENT") {
return callback(err);
}
if (stats.type === "FILE") {
showOverwriteWarning(path.absPath, function (err, result) {
if (err) {
return callback(err);
}

if (result === OVERWRITE_OPERATION) {
fs.writeFile(path.absPath, path.data, callback);
} else if (result === KEEP_EXISTING_OPERATION) {
callback();
} else if (result === CANCEL_OPERATION) {
callback(new Error("Operation Cancelled"));
}
});
}
});
});
}
}
Expand Down Expand Up @@ -227,11 +288,33 @@ define(function (require, exports, module) {
}

fs.mkdirp(basedir, function(err) {
if(err && err.code !== "EEXIST") {
if(err) {
return callback(err);
}

fs.writeFile(path, new Buffer(data), {encoding: null}, callback);
fs.stat(path, function (err, stats) {
if (err && err.code !== "ENOENT") {
return callback(err);
}

if (stats.type !== "FILE") {
return callback();
}

showOverwriteWarning(path, function (err, result) {
if (err) {
return callback(err);
}

if (result === OVERWRITE_OPERATION) {
fs.writeFile(path, new Buffer(data), {encoding: null}, callback);
} else if (result === KEEP_EXISTING_OPERATION) {
return callback();
} else if (result === CANCEL_OPERATION) {
callback(new Error("Operation Cancelled"));
}
});
});
});
}

Expand Down
52 changes: 50 additions & 2 deletions src/filesystem/impls/filer/lib/WebKitFileImport.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ define(function (require, exports, module) {
StringUtils = require("utils/StringUtils"),
Filer = require("filesystem/impls/filer/BracketsFiler"),
Path = Filer.Path,
fs = Filer.fs(),
Content = require("filesystem/impls/filer/lib/content"),
LanguageManager = require("language/LanguageManager"),
StartupState = require("bramble/StartupState"),
Expand Down Expand Up @@ -134,13 +135,13 @@ define(function (require, exports, module) {
});
}

function handleRegularFile(deferred, file, filename, buffer, encoding) {
function saveFile(deferred, file, filename, buffer, encoding) {
file.write(buffer, {encoding: encoding}, function(err) {
if (err) {
onError(deferred, filename, err);
return;
}

// See if this file is worth trying to open in the editor or not
if(shouldOpenFile(filename, encoding)) {
pathList.push(filename);
Expand All @@ -150,11 +151,55 @@ define(function (require, exports, module) {
});
}

function handleRegularFile(deferred, file, filename, buffer, encoding) {
fs.exists(filename, function(doesExist) {
if (doesExist) {
console.log("File: ", filename, " already exists!");

// File exists. Prompt user for action
Dialogs.showModalDialog(
DefaultDialogs.DIALOG_ID_INFO,
Strings.FILE_EXISTS_HEADER,
StringUtils.format(Strings.DND_FILE_REPLACE, FileUtils.getBaseName(filename)),
[
{
className : Dialogs.DIALOG_BTN_CLASS_NORMAL,
id : Dialogs.DIALOG_BTN_CANCEL,
text : Strings.CANCEL
},
{
className : Dialogs.DIALOG_BTN_CLASS_NORMAL,
id : Dialogs.DIALOG_BTN_IMPORT,
text : Strings.USE_IMPORTED
},
{
className : Dialogs.DIALOG_BTN_CLASS_PRIMARY,
id : Dialogs.DIALOG_BTN_OK,
text : Strings.KEEP_EXISTING
}
]
)
.done(function(id) {
if (id === Dialogs.DIALOG_BTN_IMPORT) {
// Override file per user's request
saveFile(deferred, file, filename, buffer, encoding);
}
});
} else {
// File doesn't exist. Save without prompt
saveFile(deferred, file, filename, buffer, encoding);
}
});
}

function handleZipFile(deferred, file, filename, buffer, encoding) {
var basename = Path.basename(filename);

ArchiveUtils.unzip(buffer, { root: parentPath }, function(err) {
if (err) {
if (err.message === "Operation Cancelled") {
return deferred.resolve();
}
onError(deferred, filename, new Error(Strings.DND_ERROR_UNZIP));
return;
}
Expand All @@ -168,6 +213,9 @@ define(function (require, exports, module) {

ArchiveUtils.untar(buffer, { root: parentPath }, function(err) {
if (err) {
if (err.message === "Operation Cancelled") {
return deferred.resolve();
}
onError(deferred, filename, new Error(Strings.DND_ERROR_UNTAR));
return;
}
Expand Down
3 changes: 1 addition & 2 deletions src/utils/DragAndDrop.js
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ define(function (require, exports, module) {
// this is the path they want to use as a parent dir root.
var _dropPathHint;


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

return Async.doInParallel(paths, function (path, idx) {
var result = new $.Deferred();

// Only open files.
FileSystem.resolve(path, function (err, item) {
if (!err && item.isFile) {
Expand Down Expand Up @@ -183,6 +181,7 @@ define(function (require, exports, module) {
return result.promise();
}, false)
.fail(function () {
console.log("fail");
function errorToString(err) {
if (err === ERR_MULTIPLE_ITEMS_WITH_DIR) {
return Strings.ERROR_MIXED_DRAGDROP;
Expand Down

0 comments on commit fca9257

Please sign in to comment.