Fx60: Update Zotero.File.iterateDirectory() signature
StopIteration is no longer supported in Firefox 60, so instead of taking a generator function that might throw StopIteration for the second parameter, take a function that is passed to iterator.forEach() that receives an OS.File.DirectoryIterator.Entry for each directory entry. If the function returns a promise, it's waited for. Also update other direct uses of OS.File.DirectoryIterator to remove StopIteration use.
This commit is contained in:
parent
f26b1592a3
commit
8fa4cc9387
7 changed files with 142 additions and 186 deletions
|
@ -238,19 +238,16 @@ var Zotero_File_Interface = new function() {
|
|||
Zotero.debug(`${dir} does not exist`);
|
||||
return dbs;
|
||||
}
|
||||
await Zotero.File.iterateDirectory(dir, function* (iterator) {
|
||||
while (true) {
|
||||
let entry = yield iterator.next();
|
||||
if (entry.isDir) continue;
|
||||
// online.sqlite, counterintuitively, is the default database before you sign in
|
||||
if (entry.name == 'online.sqlite' || entry.name.endsWith('@www.mendeley.com.sqlite')) {
|
||||
dbs.push({
|
||||
name: entry.name,
|
||||
path: entry.path,
|
||||
lastModified: null,
|
||||
size: null
|
||||
});
|
||||
}
|
||||
await Zotero.File.iterateDirectory(dir, function (entry) {
|
||||
if (entry.isDir) return;
|
||||
// online.sqlite, counterintuitively, is the default database before you sign in
|
||||
if (entry.name == 'online.sqlite' || entry.name.endsWith('@www.mendeley.com.sqlite')) {
|
||||
dbs.push({
|
||||
name: entry.name,
|
||||
path: entry.path,
|
||||
lastModified: null,
|
||||
size: null
|
||||
});
|
||||
}
|
||||
});
|
||||
for (let i = 0; i < dbs.length; i++) {
|
||||
|
|
|
@ -1208,19 +1208,16 @@ Zotero_Import_Mendeley.prototype.deleteNonPrimaryFiles = async function () {
|
|||
let filename = row.path.substr(8);
|
||||
|
||||
Zotero.debug(`Checking for extra files in ${dir}`);
|
||||
await Zotero.File.iterateDirectory(dir, function* (iterator) {
|
||||
while (true) {
|
||||
let entry = yield iterator.next();
|
||||
if (entry.name.startsWith('.zotero') || entry.name == filename) {
|
||||
continue;
|
||||
}
|
||||
Zotero.debug(`Deleting ${entry.path}`);
|
||||
try {
|
||||
yield OS.File.remove(entry.path);
|
||||
}
|
||||
catch (e) {
|
||||
Zotero.logError(e);
|
||||
}
|
||||
await Zotero.File.iterateDirectory(dir, async function (entry) {
|
||||
if (entry.name.startsWith('.zotero') || entry.name == filename) {
|
||||
return;
|
||||
}
|
||||
Zotero.debug(`Deleting ${entry.path}`);
|
||||
try {
|
||||
await OS.File.remove(entry.path);
|
||||
}
|
||||
catch (e) {
|
||||
Zotero.logError(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -2113,21 +2113,15 @@ Zotero.Attachments = new function(){
|
|||
var parent = OS.Path.dirname(path);
|
||||
var iterator = new OS.File.DirectoryIterator(parent);
|
||||
try {
|
||||
while (true) {
|
||||
let entry = yield iterator.next();
|
||||
yield iterator.forEach((entry) => {
|
||||
if (entry.name.startsWith('.')) {
|
||||
continue;
|
||||
return;
|
||||
}
|
||||
numFiles++;
|
||||
if (numFiles > 1) {
|
||||
break;
|
||||
iterator.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
if (e != StopIteration) {
|
||||
throw e;
|
||||
}
|
||||
});
|
||||
}
|
||||
finally {
|
||||
iterator.close();
|
||||
|
|
|
@ -1012,21 +1012,13 @@ Zotero.DataDirectory = {
|
|||
// Focus the first file/folder in the old directory
|
||||
else if (index == 2) {
|
||||
try {
|
||||
let it = new OS.File.DirectoryIterator(oldDir);
|
||||
let entry;
|
||||
try {
|
||||
entry = yield it.next();
|
||||
}
|
||||
catch (e) {
|
||||
if (e != StopIteration) {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
finally {
|
||||
it.close();
|
||||
}
|
||||
if (entry) {
|
||||
yield Zotero.File.reveal(entry.path);
|
||||
let firstEntry;
|
||||
yield Zotero.File.iterateDirectory(oldDir, function (entry, index, iterator) {
|
||||
firstEntry = entry;
|
||||
iterator.close();
|
||||
});
|
||||
if (firstEntry) {
|
||||
yield Zotero.File.reveal(firstEntry.path);
|
||||
}
|
||||
// Focus the database file in the new directory
|
||||
yield Zotero.File.reveal(OS.Path.join(newDir, this.getDatabaseFilename()));
|
||||
|
|
|
@ -562,51 +562,39 @@ Zotero.File = new function(){
|
|||
/**
|
||||
* @return {Promise<Boolean>}
|
||||
*/
|
||||
this.directoryIsEmpty = Zotero.Promise.coroutine(function* (path) {
|
||||
var it = new OS.File.DirectoryIterator(path);
|
||||
this.directoryIsEmpty = async function (path) {
|
||||
var iterator = new OS.File.DirectoryIterator(path);
|
||||
var empty = true;
|
||||
try {
|
||||
let entry = yield it.next();
|
||||
return false;
|
||||
}
|
||||
catch (e) {
|
||||
if (e != StopIteration) {
|
||||
throw e;
|
||||
}
|
||||
await iterator.forEach(() => {
|
||||
iterator.close();
|
||||
empty = false;
|
||||
});
|
||||
}
|
||||
finally {
|
||||
it.close();
|
||||
iterator.close();
|
||||
}
|
||||
return true;
|
||||
});
|
||||
return empty;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Run a generator with an OS.File.DirectoryIterator, closing the
|
||||
* iterator when done. Promises yielded by the generator are awaited.
|
||||
* Run a function on each entry in a directory
|
||||
*
|
||||
* The DirectoryIterator is passed as the first parameter to the generator.
|
||||
* 'entry' is an instance of OS.File.DirectoryIterator.Entry:
|
||||
*
|
||||
* Zotero.File.iterateDirectory(path, function* (iterator) {
|
||||
* while (true) {
|
||||
* let entry = yield iterator.next();
|
||||
* let contents = yield Zotero.File.getContentsAsync(entry.path);
|
||||
* [...]
|
||||
* }
|
||||
* })
|
||||
* https://developer.mozilla.org/en-US/docs/Mozilla/JavaScript_code_modules/OSFile.jsm/OS.File.DirectoryIterator.Entry
|
||||
*
|
||||
* @return {Promise}
|
||||
*/
|
||||
this.iterateDirectory = function (path, generator) {
|
||||
this.iterateDirectory = async function (path, onEntry) {
|
||||
var iterator = new OS.File.DirectoryIterator(path);
|
||||
return Zotero.Promise.coroutine(generator)(iterator)
|
||||
.catch(function (e) {
|
||||
if (e != StopIteration) {
|
||||
throw e;
|
||||
}
|
||||
})
|
||||
.finally(function () {
|
||||
try {
|
||||
await iterator.forEach(onEntry);
|
||||
}
|
||||
finally {
|
||||
iterator.close();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -681,85 +669,82 @@ Zotero.File = new function(){
|
|||
|
||||
Zotero.debug("Moving files in " + oldDir);
|
||||
|
||||
yield Zotero.File.iterateDirectory(oldDir, function* (iterator) {
|
||||
while (true) {
|
||||
let entry = yield iterator.next();
|
||||
let dest = newDir + entry.path.substr(rootDir.length);
|
||||
|
||||
// entry.isDir can be false for some reason on Travis, causing spurious test failures
|
||||
if (Zotero.automatedTest && !entry.isDir && (yield OS.File.stat(entry.path)).isDir) {
|
||||
Zotero.debug("Overriding isDir for " + entry.path);
|
||||
entry.isDir = true;
|
||||
yield Zotero.File.iterateDirectory(oldDir, async function (entry) {
|
||||
var dest = newDir + entry.path.substr(rootDir.length);
|
||||
|
||||
// entry.isDir can be false for some reason on Travis, causing spurious test failures
|
||||
if (Zotero.automatedTest && !entry.isDir && (await OS.File.stat(entry.path)).isDir) {
|
||||
Zotero.debug("Overriding isDir for " + entry.path);
|
||||
entry.isDir = true;
|
||||
}
|
||||
|
||||
// Move files in directory
|
||||
if (!entry.isDir) {
|
||||
try {
|
||||
await OS.File.move(
|
||||
entry.path,
|
||||
dest,
|
||||
{
|
||||
noOverwrite: options
|
||||
&& options.noOverwrite
|
||||
&& options.noOverwrite(entry.path)
|
||||
}
|
||||
);
|
||||
}
|
||||
catch (e) {
|
||||
checkError(e);
|
||||
Zotero.debug("Error moving " + entry.path);
|
||||
addError(e);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Move directory with external command if possible and the directory doesn't
|
||||
// already exist in target
|
||||
let moved = false;
|
||||
|
||||
// Move files in directory
|
||||
if (!entry.isDir) {
|
||||
if (useCmd && !(await OS.File.exists(dest))) {
|
||||
Zotero.debug(`Moving ${entry.path} with ${cmd}`);
|
||||
let args = [entry.path, dest];
|
||||
try {
|
||||
yield OS.File.move(
|
||||
entry.path,
|
||||
dest,
|
||||
{
|
||||
noOverwrite: options
|
||||
&& options.noOverwrite
|
||||
&& options.noOverwrite(entry.path)
|
||||
}
|
||||
);
|
||||
await Zotero.Utilities.Internal.exec(cmd, args);
|
||||
moved = true;
|
||||
}
|
||||
catch (e) {
|
||||
checkError(e);
|
||||
Zotero.debug("Error moving " + entry.path);
|
||||
addError(e);
|
||||
Zotero.debug(e, 1);
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Move directory with external command if possible and the directory doesn't
|
||||
// already exist in target
|
||||
let moved = false;
|
||||
|
||||
if (useCmd && !(yield OS.File.exists(dest))) {
|
||||
Zotero.debug(`Moving ${entry.path} with ${cmd}`);
|
||||
let args = [entry.path, dest];
|
||||
try {
|
||||
yield Zotero.Utilities.Internal.exec(cmd, args);
|
||||
moved = true;
|
||||
}
|
||||
catch (e) {
|
||||
checkError(e);
|
||||
Zotero.debug(e, 1);
|
||||
}
|
||||
|
||||
|
||||
// If can't use command, try moving with OS.File.move(). Technically this is
|
||||
// unsupported for directories, but it works on all platforms as long as noCopy
|
||||
// is set (and on some platforms regardless)
|
||||
if (!moved && useFunction) {
|
||||
Zotero.debug(`Moving ${entry.path} with OS.File`);
|
||||
try {
|
||||
await OS.File.move(
|
||||
entry.path,
|
||||
dest,
|
||||
{
|
||||
noCopy: true
|
||||
}
|
||||
);
|
||||
moved = true;
|
||||
}
|
||||
|
||||
|
||||
// If can't use command, try moving with OS.File.move(). Technically this is
|
||||
// unsupported for directories, but it works on all platforms as long as noCopy
|
||||
// is set (and on some platforms regardless)
|
||||
if (!moved && useFunction) {
|
||||
Zotero.debug(`Moving ${entry.path} with OS.File`);
|
||||
try {
|
||||
yield OS.File.move(
|
||||
entry.path,
|
||||
dest,
|
||||
{
|
||||
noCopy: true
|
||||
}
|
||||
);
|
||||
moved = true;
|
||||
}
|
||||
catch (e) {
|
||||
checkError(e);
|
||||
Zotero.debug(e, 1);
|
||||
}
|
||||
catch (e) {
|
||||
checkError(e);
|
||||
Zotero.debug(e, 1);
|
||||
}
|
||||
|
||||
// Otherwise, recurse into subdirectories to copy files individually
|
||||
if (!moved) {
|
||||
try {
|
||||
yield moveSubdirs(entry.path, depth - 1);
|
||||
}
|
||||
catch (e) {
|
||||
checkError(e);
|
||||
addError(e);
|
||||
}
|
||||
}
|
||||
|
||||
// Otherwise, recurse into subdirectories to copy files individually
|
||||
if (!moved) {
|
||||
try {
|
||||
await moveSubdirs(entry.path, depth - 1);
|
||||
}
|
||||
catch (e) {
|
||||
checkError(e);
|
||||
addError(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -983,11 +968,8 @@ Zotero.File = new function(){
|
|||
unixMode: 0o755
|
||||
});
|
||||
|
||||
return this.iterateDirectory(source, function* (iterator) {
|
||||
while (true) {
|
||||
let entry = yield iterator.next();
|
||||
yield OS.File.copy(entry.path, OS.Path.join(target, entry.name));
|
||||
}
|
||||
return this.iterateDirectory(source, function (entry) {
|
||||
return OS.File.copy(entry.path, OS.Path.join(target, entry.name));
|
||||
})
|
||||
});
|
||||
|
||||
|
|
|
@ -283,17 +283,14 @@ Zotero.Profile = {
|
|||
*/
|
||||
_getProfilesInDir: Zotero.Promise.coroutine(function* (profilesDir) {
|
||||
var dirs = [];
|
||||
yield Zotero.File.iterateDirectory(profilesDir, function* (iterator) {
|
||||
while (true) {
|
||||
let entry = yield iterator.next();
|
||||
// entry.isDir can be false for some reason on Travis, causing spurious test failures
|
||||
if (Zotero.automatedTest && !entry.isDir && (yield OS.File.stat(entry.path)).isDir) {
|
||||
Zotero.debug("Overriding isDir for " + entry.path);
|
||||
entry.isDir = true;
|
||||
}
|
||||
if (entry.isDir && (yield OS.File.exists(OS.Path.join(entry.path, "prefs.js")))) {
|
||||
dirs.push(entry.path);
|
||||
}
|
||||
yield Zotero.File.iterateDirectory(profilesDir, async function (entry) {
|
||||
// entry.isDir can be false for some reason on Travis, causing spurious test failures
|
||||
if (Zotero.automatedTest && !entry.isDir && (await OS.File.stat(entry.path)).isDir) {
|
||||
Zotero.debug("Overriding isDir for " + entry.path);
|
||||
entry.isDir = true;
|
||||
}
|
||||
if (entry.isDir && (await OS.File.exists(OS.Path.join(entry.path, "prefs.js")))) {
|
||||
dirs.push(entry.path);
|
||||
}
|
||||
});
|
||||
return dirs;
|
||||
|
|
|
@ -499,28 +499,25 @@ Services.scriptloader.loadSubScript("resource://zotero/polyfill.js");
|
|||
let lastError;
|
||||
// Delete all files in directory rather than removing directory, in case it's
|
||||
// a symlink
|
||||
yield Zotero.File.iterateDirectory(dataDir, function* (iterator) {
|
||||
while (true) {
|
||||
let entry = yield iterator.next();
|
||||
// Don't delete some files
|
||||
if (entry.name == 'pipes') {
|
||||
continue;
|
||||
yield Zotero.File.iterateDirectory(dataDir, async function (entry) {
|
||||
// Don't delete some files
|
||||
if (entry.name == 'pipes') {
|
||||
return;
|
||||
}
|
||||
Zotero.debug("Deleting " + entry.path);
|
||||
try {
|
||||
if (entry.isDir) {
|
||||
await OS.File.removeDir(entry.path);
|
||||
}
|
||||
Zotero.debug("Deleting " + entry.path);
|
||||
try {
|
||||
if (entry.isDir) {
|
||||
yield OS.File.removeDir(entry.path);
|
||||
}
|
||||
else {
|
||||
yield OS.File.remove(entry.path);
|
||||
}
|
||||
}
|
||||
// Keep trying to delete as much as we can
|
||||
catch (e) {
|
||||
lastError = e;
|
||||
Zotero.logError(e);
|
||||
else {
|
||||
await OS.File.remove(entry.path);
|
||||
}
|
||||
}
|
||||
// Keep trying to delete as much as we can
|
||||
catch (e) {
|
||||
lastError = e;
|
||||
Zotero.logError(e);
|
||||
}
|
||||
});
|
||||
if (lastError) {
|
||||
throw lastError;
|
||||
|
|
Loading…
Reference in a new issue