diff --git a/chrome/content/zotero/overlay.js b/chrome/content/zotero/overlay.js
index b1195ee520..ba0019388f 100644
--- a/chrome/content/zotero/overlay.js
+++ b/chrome/content/zotero/overlay.js
@@ -179,12 +179,40 @@ var ZoteroPane = new function()
// If the database was initialized and Zotero hasn't been run before
// in this profile, display the Quick Start Guide -- this way the guide
- // won't be displayed they sync their DB to another profile or if
+ // won't be displayed when they sync their DB to another profile or if
// they the DB is initialized erroneously (e.g. while switching data
// directory locations)
- if (Zotero.Schema.dbInitialized && Zotero.Prefs.get('firstRun')) {
+ if (Zotero.restoreFromServer) {
+ Zotero.restoreFromServer = false;
+
setTimeout(function () {
- gBrowser.selectedTab = gBrowser.addTab('http://www.zotero.org/documentation/quick_start_guide');
+ var pr = Components.classes["@mozilla.org/network/default-prompt;1"]
+ .getService(Components.interfaces.nsIPrompt);
+ var buttonFlags = (pr.BUTTON_POS_0) * (pr.BUTTON_TITLE_IS_STRING)
+ + (pr.BUTTON_POS_1) * (pr.BUTTON_TITLE_CANCEL);
+ var index = pr.confirmEx(
+ "Zotero Restore",
+ "The local Zotero database has been cleared."
+ + " "
+ + "Would you like to restore from the Zotero server now?",
+ buttonFlags,
+ "Sync Now",
+ null, null, null, {}
+ );
+
+ if (index == 0) {
+ Zotero.Sync.Server.sync(function () {
+ pr.alert(
+ "Restore Completed",
+ "The local Zotero database has been successfully restored."
+ );
+ });
+ }
+ }, 1000);
+ }
+ else if (Zotero.Schema.dbInitialized && Zotero.Prefs.get('firstRun')) {
+ setTimeout(function () {
+ gBrowser.selectedTab = gBrowser.addTab(ZOTERO_CONFIG.FIRST_RUN_URL);
}, 400);
Zotero.Prefs.set('firstRun', false);
}
diff --git a/chrome/content/zotero/preferences/preferences.js b/chrome/content/zotero/preferences/preferences.js
index edbfbbcfb2..7ace0d5c0d 100644
--- a/chrome/content/zotero/preferences/preferences.js
+++ b/chrome/content/zotero/preferences/preferences.js
@@ -148,6 +148,24 @@ function populateOpenURLResolvers() {
//
// Sync
//
+/*
+function updateSyncStatus() {
+ var disabled = !Zotero.Sync.Server.enabled;
+
+ var radioGroup = document.getElementById('zotero-reset').firstChild;
+ radioGroup.disabled = disabled;
+ var labels = radioGroup.getElementsByTagName('label');
+ for each(var label in labels) {
+ label.disabled = disabled;
+ }
+ var labels = radioGroup.getElementsByTagName('description');
+ for each(var label in labels) {
+ label.disabled = disabled;
+ }
+ document.getElementById('zotero-reset-button').disabled = disabled;
+}
+*/
+
function updateStorageSettings(value) {
if (!value) {
value = document.getElementById('pref-storage-protocol').value;
@@ -223,6 +241,130 @@ function verifyStorageServer() {
}
}
+function handleSyncResetSelect(obj) {
+ var index = obj.selectedIndex;
+ var rows = obj.getElementsByTagName('row');
+
+ for (var i=0; i
-
-
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Erase all local Zotero data and restore from the sync server.
+
+
+
+
+
+
+
+ Erase all server data and overwrite with local Zotero data.
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/chrome/content/zotero/xpcom/db.js b/chrome/content/zotero/xpcom/db.js
index c6d2713843..ec12232f25 100644
--- a/chrome/content/zotero/xpcom/db.js
+++ b/chrome/content/zotero/xpcom/db.js
@@ -658,11 +658,7 @@ Zotero.DBConnection.prototype.checkException = function (e) {
if (e.name && e.name == 'NS_ERROR_FILE_CORRUPTED') {
// Write corrupt marker to data directory
var file = Zotero.getZoteroDatabase(this._dbName, 'is.corrupt');
- var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"]
- .createInstance(Components.interfaces.nsIFileOutputStream);
- foStream.init(file, 0x02 | 0x08 | 0x20, 0664, 0); // write, create, truncate
- foStream.write('', 0);
- foStream.close();
+ Zotero.File.putContents(file, '');
this._dbIsCorrupt = true;
@@ -694,6 +690,12 @@ Zotero.DBConnection.prototype.checkException = function (e) {
}
+Zotero.DBConnection.prototype.closeDatabase = function () {
+ var db = this._getDBConnection();
+ db.close();
+}
+
+
Zotero.DBConnection.prototype.backupDatabase = function (suffix) {
if (this.transactionInProgress()) {
this._debug("Transaction in progress--skipping backup of DB '" + this._dbName + "'", 2);
diff --git a/chrome/content/zotero/xpcom/schema.js b/chrome/content/zotero/xpcom/schema.js
index 4fc6fde222..a2459d39bf 100644
--- a/chrome/content/zotero/xpcom/schema.js
+++ b/chrome/content/zotero/xpcom/schema.js
@@ -26,8 +26,8 @@ Zotero.Schema = new function(){
this.updateSchema = updateSchema;
this.stopRepositoryTimer = stopRepositoryTimer;
+ this.skipDefaultData = false;
this.dbInitialized = false;
- this.upgradeFinished = false;
this.goToChangeLog = false;
var _dbVersions = [];
@@ -685,30 +685,32 @@ Zotero.Schema = new function(){
_updateDBVersion('userdata', _getSchemaSQLVersion('userdata'));
_updateDBVersion('triggers', _getSchemaSQLVersion('triggers'));
- /*
- TODO: uncomment for release
- var sql = "INSERT INTO items VALUES(1, 14, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'AJ4PT6IT')";
- Zotero.DB.query(sql);
- var sql = "INSERT INTO itemAttachments VALUES (1, NULL, 3, 'text/html', 25, NULL, NULL)";
- Zotero.DB.query(sql);
- var sql = "INSERT INTO itemDataValues VALUES (?, ?)";
- Zotero.DB.query(sql, [1, "Zotero - " + Zotero.getString('install.quickStartGuide')]);
- var sql = "INSERT INTO itemData VALUES (1, 110, 1)";
- Zotero.DB.query(sql);
- var sql = "INSERT INTO itemDataValues VALUES (2, 'http://www.zotero.org/documentation/quick_start_guide')";
- Zotero.DB.query(sql);
- var sql = "INSERT INTO itemData VALUES (1, 1, 2)";
- Zotero.DB.query(sql);
- var sql = "INSERT INTO itemDataValues VALUES (3, CURRENT_TIMESTAMP)";
- Zotero.DB.query(sql);
- var sql = "INSERT INTO itemData VALUES (1, 27, 3)";
- Zotero.DB.query(sql);
- var sql = "INSERT INTO itemNotes (itemID, sourceItemID, note) VALUES (1, NULL, ?)";
- var msg = Zotero.getString('install.quickStartGuide.message.welcome')
- + " " + Zotero.getString('install.quickStartGuide.message.clickViewPage')
- + "\n\n" + Zotero.getString('install.quickStartGuide.message.thanks');
- Zotero.DB.query(sql, msg);
- */
+ if (!Zotero.Schema.skipDefaultData) {
+ /*
+ TODO: uncomment for release
+ var sql = "INSERT INTO items VALUES(1, 14, CURRENT_TIMESTAMP, CURRENT_TIMESTAMP, 'AJ4PT6IT')";
+ Zotero.DB.query(sql);
+ var sql = "INSERT INTO itemAttachments VALUES (1, NULL, 3, 'text/html', 25, NULL, NULL)";
+ Zotero.DB.query(sql);
+ var sql = "INSERT INTO itemDataValues VALUES (?, ?)";
+ Zotero.DB.query(sql, [1, "Zotero - " + Zotero.getString('install.quickStartGuide')]);
+ var sql = "INSERT INTO itemData VALUES (1, 110, 1)";
+ Zotero.DB.query(sql);
+ var sql = "INSERT INTO itemDataValues VALUES (2, 'http://www.zotero.org/documentation/quick_start_guide')";
+ Zotero.DB.query(sql);
+ var sql = "INSERT INTO itemData VALUES (1, 1, 2)";
+ Zotero.DB.query(sql);
+ var sql = "INSERT INTO itemDataValues VALUES (3, CURRENT_TIMESTAMP)";
+ Zotero.DB.query(sql);
+ var sql = "INSERT INTO itemData VALUES (1, 27, 3)";
+ Zotero.DB.query(sql);
+ var sql = "INSERT INTO itemNotes (itemID, sourceItemID, note) VALUES (1, NULL, ?)";
+ var msg = Zotero.getString('install.quickStartGuide.message.welcome')
+ + " " + Zotero.getString('install.quickStartGuide.message.clickViewPage')
+ + "\n\n" + Zotero.getString('install.quickStartGuide.message.thanks');
+ Zotero.DB.query(sql, msg);
+ */
+ }
Zotero.DB.commitTransaction();
self.dbInitialized = true;
diff --git a/chrome/content/zotero/xpcom/sync.js b/chrome/content/zotero/xpcom/sync.js
index f11c6a9934..bdbd896077 100644
--- a/chrome/content/zotero/xpcom/sync.js
+++ b/chrome/content/zotero/xpcom/sync.js
@@ -408,6 +408,7 @@ Zotero.Sync.Runner = new function () {
if (_running) {
throw ("Sync already running in Zotero.Sync.Runner.sync()");
}
+
_queue = [
Zotero.Sync.Server.sync,
Zotero.Sync.Storage.sync,
@@ -423,6 +424,12 @@ Zotero.Sync.Runner = new function () {
this.next = function () {
+ if (!_running) {
+ var msg = "Sync not running in Zotero.Sync.Runner.next()";
+ this.setError(msg);
+ throw (msg);
+ }
+
if (!_queue.length) {
this.setSyncIcon();
_running = false;
@@ -538,7 +545,6 @@ Zotero.Sync.Runner.EventListener = {
}
-
/**
* Methods for syncing with the Zotero Server
*/
@@ -666,7 +672,7 @@ Zotero.Sync.Server = new function () {
var _sessionLock;
- function login(callback) {
+ function login(callback, callbackCallback) {
var url = _serverURL + "login";
var username = Zotero.Sync.Server.username;
@@ -714,13 +720,13 @@ Zotero.Sync.Server = new function () {
//Zotero.debug('Got session ID ' + _sessionID + ' from server');
if (callback) {
- callback();
+ callback(callbackCallback);
}
});
}
- function sync() {
+ function sync(callback) {
Zotero.Sync.Runner.setSyncIcon('animate');
if (_attempts < 0) {
@@ -729,12 +735,12 @@ Zotero.Sync.Server = new function () {
if (!_sessionID) {
Zotero.debug("Session ID not available -- logging in");
- Zotero.Sync.Server.login(Zotero.Sync.Server.sync);
+ Zotero.Sync.Server.login(Zotero.Sync.Server.sync, callback);
return;
}
if (!_sessionLock) {
- Zotero.Sync.Server.lock(Zotero.Sync.Server.sync);
+ Zotero.Sync.Server.lock(Zotero.Sync.Server.sync, callback);
return;
}
@@ -764,7 +770,7 @@ Zotero.Sync.Server = new function () {
Zotero.debug("Invalid session ID -- logging in");
_sessionID = false;
_syncInProgress = false;
- Zotero.Sync.Server.login(Zotero.Sync.Server.sync);
+ Zotero.Sync.Server.login(Zotero.Sync.Server.sync, callback);
return;
}
@@ -828,8 +834,14 @@ Zotero.Sync.Server = new function () {
Zotero.debug("Sync cancelled");
Zotero.DB.rollbackTransaction();
Zotero.Sync.Server.unlock(function () {
- Zotero.Sync.Runner.reset();
- Zotero.Sync.Runner.next();
+ if (callback) {
+ Zotero.Sync.Runner.setSyncIcon();
+ callback();
+ }
+ else {
+ Zotero.Sync.Runner.reset();
+ Zotero.Sync.Runner.next();
+ }
});
Zotero.reloadDataObjects();
_syncInProgress = false;
@@ -849,7 +861,13 @@ Zotero.Sync.Server = new function () {
Zotero.DB.commitTransaction();
Zotero.Sync.Server.unlock(function () {
_syncInProgress = false;
- Zotero.Sync.Runner.next();
+ if (callback) {
+ Zotero.Sync.Runner.setSyncIcon();
+ callback();
+ }
+ else {
+ Zotero.Sync.Runner.next();
+ }
});
return;
}
@@ -890,7 +908,13 @@ Zotero.Sync.Server = new function () {
Zotero.DB.commitTransaction();
Zotero.Sync.Server.unlock(function () {
_syncInProgress = false;
- Zotero.Sync.Runner.next();
+ if (callback) {
+ Zotero.Sync.Runner.setSyncIcon();
+ callback();
+ }
+ else {
+ Zotero.Sync.Runner.next();
+ }
});
}
@@ -975,7 +999,7 @@ Zotero.Sync.Server = new function () {
}
- function lock(callback) {
+ function lock(callback, callbackCallback) {
Zotero.debug("Getting session lock");
if (_attempts < 0) {
@@ -1019,7 +1043,7 @@ Zotero.Sync.Server = new function () {
_sessionLock = true;
if (callback) {
- callback();
+ callback(callbackCallback);
}
});
}
@@ -1066,14 +1090,14 @@ Zotero.Sync.Server = new function () {
}
- function clear() {
+ function clear(callback) {
if (_attempts < 0) {
_error('Too many attempts in Zotero.Sync.Server.clear()');
}
if (!_sessionID) {
Zotero.debug("Session ID not available -- logging in");
- Zotero.Sync.Server.login(Zotero.Sync.Server.clear);
+ Zotero.Sync.Server.login(Zotero.Sync.Server.clear, callback);
return;
}
@@ -1085,7 +1109,7 @@ Zotero.Sync.Server = new function () {
if (_invalidSession(xmlhttp)) {
Zotero.debug("Invalid session ID -- logging in");
_sessionID = false;
- Zotero.Sync.Server.login(Zotero.Sync.Server.clear);
+ Zotero.Sync.Server.login(Zotero.Sync.Server.clear, callback);
return;
}
@@ -1102,6 +1126,10 @@ Zotero.Sync.Server = new function () {
}
Zotero.Sync.Server.resetClient();
+
+ if (callback) {
+ callback();
+ }
});
_resetAttempts();
@@ -1111,14 +1139,14 @@ Zotero.Sync.Server = new function () {
/**
* Clear session lock on server
*/
- function resetServer() {
+ function resetServer(callback) {
if (_attempts < 0) {
_error('Too many attempts in Zotero.Sync.Server.resetServer()');
}
if (!_sessionID) {
Zotero.debug("Session ID not available -- logging in");
- Zotero.Sync.Server.login(Zotero.Sync.Server.resetServer);
+ Zotero.Sync.Server.login(Zotero.Sync.Server.resetServer, callback);
return;
}
@@ -1130,7 +1158,7 @@ Zotero.Sync.Server = new function () {
if (_invalidSession(xmlhttp)) {
Zotero.debug("Invalid session ID -- logging in");
_sessionID = false;
- Zotero.Sync.Server.login(Zotero.Sync.Server.reset);
+ Zotero.Sync.Server.login(Zotero.Sync.Server.reset, callback);
return;
}
@@ -1149,6 +1177,10 @@ Zotero.Sync.Server = new function () {
}
_syncInProgress = false;
+
+ if (callback) {
+ callback();
+ }
});
_resetAttempts();
diff --git a/chrome/content/zotero/xpcom/zotero.js b/chrome/content/zotero/xpcom/zotero.js
index 15add400fc..934e851c23 100644
--- a/chrome/content/zotero/xpcom/zotero.js
+++ b/chrome/content/zotero/xpcom/zotero.js
@@ -26,6 +26,7 @@ const ZOTERO_CONFIG = {
REPOSITORY_URL: 'http://www.zotero.org/repo',
REPOSITORY_CHECK_INTERVAL: 86400, // 24 hours
REPOSITORY_RETRY_INTERVAL: 3600, // 1 hour
+ FIRST_RUN_URL: 'http://www.zotero.org/support/quick_start_guide',
SYNC_URL: 'https://sync.zotero.org/'
};
@@ -173,7 +174,7 @@ var Zotero = new function(){
}
try {
- this.getZoteroDirectory();
+ var dataDir = this.getZoteroDirectory();
}
catch (e) {
// Zotero dir not found
@@ -218,8 +219,32 @@ var Zotero = new function(){
Zotero.VersionHeader.init();
- // Initialize keyboard shortcuts
- Zotero.Keys.init();
+ // Check for DB restore
+ var restoreFile = dataDir.clone();
+ restoreFile.append('restore-from-server');
+ if (restoreFile.exists()) {
+ try {
+ // TODO: better error handling
+
+ // TODO: prompt for location
+ // TODO: Back up database
+
+ restoreFile.remove(false);
+
+ var dbfile = Zotero.getZoteroDatabase();
+ dbfile.remove(false);
+
+ // Recreate database with no quick start guide
+ Zotero.Schema.skipDefaultData = true;
+ Zotero.Schema.updateSchema();
+
+ this.restoreFromServer = true;
+ }
+ catch (e) {
+ // Restore from backup?
+ alert(e);
+ }
+ }
try {
Zotero.DB.test();
@@ -280,6 +305,9 @@ var Zotero = new function(){
Zotero.MIMETypeHandler.init();
Zotero.Proxies.init();
+ // Initialize keyboard shortcuts
+ Zotero.Keys.init();
+
this.initialized = true;
Zotero.debug("Initialized in "+((new Date()).getTime() - start)+" ms");
diff --git a/chrome/skin/default/zotero/preferences.css b/chrome/skin/default/zotero/preferences.css
index b26af72f83..9d6c2474be 100644
--- a/chrome/skin/default/zotero/preferences.css
+++ b/chrome/skin/default/zotero/preferences.css
@@ -72,6 +72,8 @@ grid row hbox:first-child
/*
* Sync pane
*/
+
+/* Settings tab */
#zotero-prefpane-sync row, #zotero-prefpane-sync row hbox
{
-moz-box-align: center;
@@ -113,6 +115,50 @@ grid row hbox:first-child
min-width: 8em;
}
+/* Reset tab */
+#zotero-reset row
+{
+ margin: 0;
+ padding: 15px;
+}
+
+#zotero-reset row:not(:last-child)
+{
+ border-bottom: 1px #999 solid;
+}
+
+#zotero-reset row vbox
+{
+ -moz-box-align: start;
+}
+
+#zotero-reset row[selected="true"]
+{
+}
+
+
+#zotero-reset row vbox label
+{
+ margin-left: 3px;
+ font-weight: bold;
+ font-size: 14px;
+}
+
+#zotero-reset description
+{
+ margin-left: 3px;
+ margin-top: 1px;
+ font-size: 12px;
+}
+
+/* Reset button */
+#zotero-reset > hbox
+{
+ margin-top: 5px;
+ -moz-box-pack: center;
+}
+
+
/*
* Search pane