Closes #833, Displays a warning dialog if API key present but library empty
This commit is contained in:
parent
77a95b5e6d
commit
2e389de471
4 changed files with 94 additions and 4 deletions
|
@ -567,6 +567,15 @@ Zotero.Library.prototype.updateSearches = Zotero.Promise.coroutine(function* ()
|
||||||
this._hasSearches = !!(yield Zotero.DB.valueQueryAsync(sql, this.libraryID));
|
this._hasSearches = !!(yield Zotero.DB.valueQueryAsync(sql, this.libraryID));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Zotero.Library.prototype.hasItems = Zotero.Promise.coroutine(function* () {
|
||||||
|
if (!this.id) {
|
||||||
|
throw new Error("Library is not saved yet");
|
||||||
|
}
|
||||||
|
let sql = 'SELECT COUNT(*)>0 FROM items WHERE libraryID=?';
|
||||||
|
|
||||||
|
return Zotero.DB.valueQueryAsync(sql, this.libraryID);
|
||||||
|
});
|
||||||
|
|
||||||
Zotero.Library.prototype.hasItem = function (item) {
|
Zotero.Library.prototype.hasItem = function (item) {
|
||||||
if (!(item instanceof Zotero.Item)) {
|
if (!(item instanceof Zotero.Item)) {
|
||||||
throw new Error("item must be a Zotero.Item");
|
throw new Error("item must be a Zotero.Item");
|
||||||
|
|
|
@ -136,14 +136,20 @@ Zotero.Sync.Runner_Module = function (options = {}) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
let client = this.getAPIClient({ apiKey });
|
let client = this.getAPIClient({ apiKey });
|
||||||
|
|
||||||
let keyInfo = yield this.checkAccess(client, options);
|
let keyInfo = yield this.checkAccess(client, options);
|
||||||
if (!keyInfo) {
|
|
||||||
|
let emptyLibraryContinue = yield this.checkEmptyLibrary(keyInfo);
|
||||||
|
if (!emptyLibraryContinue) {
|
||||||
this.end();
|
this.end();
|
||||||
Zotero.debug("Syncing cancelled");
|
Zotero.debug("Syncing cancelled because user library is empty");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!Zotero.Users.getCurrentUserID()) {
|
||||||
|
Zotero.Users.setCurrentUserID(keyInfo.userID);
|
||||||
|
Zotero.Users.setCurrentUsername(keyInfo.username);
|
||||||
|
}
|
||||||
|
|
||||||
let engineOptions = {
|
let engineOptions = {
|
||||||
apiClient: client,
|
apiClient: client,
|
||||||
caller: this.caller,
|
caller: this.caller,
|
||||||
|
@ -233,6 +239,45 @@ Zotero.Sync.Runner_Module = function (options = {}) {
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// Prompt if library empty and there is no userID stored
|
||||||
|
this.checkEmptyLibrary = Zotero.Promise.coroutine(function* (keyInfo) {
|
||||||
|
let library = Zotero.Libraries.userLibrary;
|
||||||
|
let userID = Zotero.Users.getCurrentUserID();
|
||||||
|
|
||||||
|
if (!userID) {
|
||||||
|
let hasItems = yield library.hasItems();
|
||||||
|
if (!hasItems) {
|
||||||
|
let ps = Services.prompt;
|
||||||
|
let index = ps.confirmEx(
|
||||||
|
null,
|
||||||
|
Zotero.getString('general.warning'),
|
||||||
|
Zotero.getString('sync.warning.emptyLibrary', [keyInfo.username, Zotero.clientName]) + "\n\n"
|
||||||
|
+ Zotero.getString('sync.warning.existingDataElsewhere', Zotero.clientName),
|
||||||
|
(ps.BUTTON_POS_0 * ps.BUTTON_TITLE_IS_STRING)
|
||||||
|
+ (ps.BUTTON_POS_1 * ps.BUTTON_TITLE_CANCEL)
|
||||||
|
+ (ps.BUTTON_POS_2 * ps.BUTTON_TITLE_IS_STRING),
|
||||||
|
Zotero.getString('sync.sync'),
|
||||||
|
null,
|
||||||
|
Zotero.getString('dataDir.changeDataDirectory'),
|
||||||
|
null, {}
|
||||||
|
);
|
||||||
|
if (index == 1) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (index == 2) {
|
||||||
|
var win = Services.wm.getMostRecentWindow("navigator:browser");
|
||||||
|
win.openDialog("chrome://zotero/content/preferences/preferences.xul", null, null, {
|
||||||
|
pane: 'zotero-prefpane-advanced',
|
||||||
|
tabIndex: 1
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
this.checkLibraries = Zotero.Promise.coroutine(function* (client, options, keyInfo, libraries = []) {
|
this.checkLibraries = Zotero.Promise.coroutine(function* (client, options, keyInfo, libraries = []) {
|
||||||
var access = keyInfo.access;
|
var access = keyInfo.access;
|
||||||
|
|
||||||
|
|
|
@ -112,6 +112,7 @@ dataDir.notFound = The Zotero data directory could not be found.
|
||||||
dataDir.previousDir = Previous directory:
|
dataDir.previousDir = Previous directory:
|
||||||
dataDir.useProfileDir = Use %S profile directory
|
dataDir.useProfileDir = Use %S profile directory
|
||||||
dataDir.selectDir = Select a Zotero data directory
|
dataDir.selectDir = Select a Zotero data directory
|
||||||
|
dataDir.changeDataDirectory = Change Data Directory…
|
||||||
dataDir.unsafeLocation.selected.dropbox = Choosing a data directory within Dropbox may corrupt your database.
|
dataDir.unsafeLocation.selected.dropbox = Choosing a data directory within Dropbox may corrupt your database.
|
||||||
dataDir.unsafeLocation.selected.useAnyway = Use this directory anyway?
|
dataDir.unsafeLocation.selected.useAnyway = Use this directory anyway?
|
||||||
dataDir.unsafeLocation.existing.dropbox = Your Zotero data directory is within Dropbox, which may lead to data corruption.
|
dataDir.unsafeLocation.existing.dropbox = Your Zotero data directory is within Dropbox, which may lead to data corruption.
|
||||||
|
@ -828,6 +829,8 @@ sync.localDataWillBeCombined = If you continue, local Zotero data will be combi
|
||||||
sync.localGroupsWillBeRemoved1 = Local groups, including any with changed items, will also be removed from this computer.
|
sync.localGroupsWillBeRemoved1 = Local groups, including any with changed items, will also be removed from this computer.
|
||||||
sync.avoidCombiningData = To avoid combining data, revert to the '%S' account or use the Reset options in the Sync pane of the Zotero preferences.
|
sync.avoidCombiningData = To avoid combining data, revert to the '%S' account or use the Reset options in the Sync pane of the Zotero preferences.
|
||||||
sync.unlinkWarning = Are you sure you want to unlink this account?\n\n%S will no longer sync your data, but your data will remain locally.
|
sync.unlinkWarning = Are you sure you want to unlink this account?\n\n%S will no longer sync your data, but your data will remain locally.
|
||||||
|
sync.warning.emptyLibrary = You are about to sync the ‘%1$S’ account to an empty %2$S database. This could happen if you removed your previous %2$S database or if the location of your data directory changed.
|
||||||
|
sync.warning.existingDataElsewhere = If your %S data exists elsewhere on your computer, you should move it to your current data directory or change your data directory location to point to the existing data.
|
||||||
|
|
||||||
sync.conflict.autoChange.alert = One or more locally deleted Zotero %S have been modified remotely since the last sync.
|
sync.conflict.autoChange.alert = One or more locally deleted Zotero %S have been modified remotely since the last sync.
|
||||||
sync.conflict.autoChange.log = A Zotero %S has changed both locally and remotely since the last sync:
|
sync.conflict.autoChange.log = A Zotero %S has changed both locally and remotely since the last sync:
|
||||||
|
|
|
@ -256,6 +256,39 @@ describe("Zotero.Library", function() {
|
||||||
assert.isFalse(library.hasSearches());
|
assert.isFalse(library.hasSearches());
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
describe("#hasItems()", function() {
|
||||||
|
it("should throw if called before saving a library", function* () {
|
||||||
|
let library = new Zotero.Library();
|
||||||
|
try {
|
||||||
|
yield library.hasItems();
|
||||||
|
assert.isFalse(true, "Library#hasItems did not throw an error");
|
||||||
|
} catch (e) {
|
||||||
|
assert.ok(e);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
it("should stay up to date as items are added and removed", function* () {
|
||||||
|
let library = yield createGroup({ editable: true });
|
||||||
|
let libraryID = library.libraryID;
|
||||||
|
var hasItems = yield library.hasItems();
|
||||||
|
assert.isFalse(hasItems);
|
||||||
|
|
||||||
|
let i1 = yield createDataObject('item', { libraryID });
|
||||||
|
hasItems = yield library.hasItems();
|
||||||
|
assert.isTrue(hasItems);
|
||||||
|
|
||||||
|
let i2 = yield createDataObject('item', { libraryID });
|
||||||
|
hasItems = yield library.hasItems();
|
||||||
|
assert.isTrue(hasItems);
|
||||||
|
|
||||||
|
yield i1.eraseTx();
|
||||||
|
hasItems = yield library.hasItems();
|
||||||
|
assert.isTrue(hasItems);
|
||||||
|
|
||||||
|
yield i2.eraseTx();
|
||||||
|
hasItems = yield library.hasItems();
|
||||||
|
assert.isFalse(hasItems);
|
||||||
|
});
|
||||||
|
});
|
||||||
describe("#updateLastSyncTime()", function() {
|
describe("#updateLastSyncTime()", function() {
|
||||||
it("should set sync time to current time", function* () {
|
it("should set sync time to current time", function* () {
|
||||||
let group = yield createGroup();
|
let group = yield createGroup();
|
||||||
|
|
Loading…
Reference in a new issue