From e0f1ef76461f394707552342fc950b16874e20d4 Mon Sep 17 00:00:00 2001
From: Dan Stillman <dstillman@zotero.org>
Date: Wed, 27 May 2009 04:13:25 +0000
Subject: [PATCH] Automatically correct missing item server errors by flagging
 missing items for update on next sync

---
 chrome/content/zotero/xpcom/data/item.js | 14 +++++++++++++-
 chrome/content/zotero/xpcom/sync.js      | 21 ++++++++++++++++++---
 2 files changed, 31 insertions(+), 4 deletions(-)

diff --git a/chrome/content/zotero/xpcom/data/item.js b/chrome/content/zotero/xpcom/data/item.js
index 8b153a3032..f97b93c93d 100644
--- a/chrome/content/zotero/xpcom/data/item.js
+++ b/chrome/content/zotero/xpcom/data/item.js
@@ -1943,6 +1943,18 @@ Zotero.Item.prototype.save = function() {
 }
 
 
+/**
+ * Used by sync code
+ */
+Zotero.Item.prototype.updateClientDateModified = function () {
+	if (!this.id) {
+		throw ("Cannot update clientDateModified of unsaved item in Zotero.Item.updateClientDateModified()");
+	}
+	var sql = "UPDATE items SET clientDateModified=? WHERE itemID=?";
+	Zotero.DB.query(sql, [Zotero.DB.transactionDateTime, this.id]);
+}
+
+
 Zotero.Item.prototype.isRegularItem = function() {
 	return !(this.isNote() || this.isAttachment());
 }
@@ -2481,7 +2493,7 @@ Zotero.Item.prototype.getFile = function(row, skipExistsCheck) {
 	}
 	
 	if (!skipExistsCheck && !file.exists()) {
-		Zotero.debug("Attachment file not found", 2);
+		Zotero.debug("Attachment file '" + file.path + "' not found", 2);
 		return false;
 	}
 	
diff --git a/chrome/content/zotero/xpcom/sync.js b/chrome/content/zotero/xpcom/sync.js
index 7c1a7a975c..bfcc3ba766 100644
--- a/chrome/content/zotero/xpcom/sync.js
+++ b/chrome/content/zotero/xpcom/sync.js
@@ -846,7 +846,7 @@ Zotero.Sync.Server = new function () {
 		if (!username) {
 			_error("Username not set in Zotero.Sync.Server.login()");
 		}
-		else if (!username.match(/^[\w\d\. ]+$/)) {
+		else if (!username.match(/^[\w\d\. \-\_]+$/)) {
 			_error("Invalid username '" + username + "' in Zotero.Sync.Server.login()");
 		}
 		
@@ -1442,10 +1442,12 @@ Zotero.Sync.Server = new function () {
 			_error('Invalid response from server', xmlhttp.responseText);
 		}
 		
+		var firstChild = xmlhttp.responseXML.firstChild.firstChild;
+		
 		// Temporarily disable auto-sync if instructed by server
-		if (xmlhttp.responseXML.firstChild.firstChild.localName == 'throttle') {
+		if (firstChild.localName == 'throttle') {
 			Zotero.debug(xmlhttp.responseText);
-			var delay = xmlhttp.responseXML.firstChild.firstChild.getAttribute('delay');
+			var delay = first.getAttribute('delay');
 			var time = new Date();
 			time = time.getTime() + (delay * 1000);
 			time = new Date(time);
@@ -1459,6 +1461,19 @@ Zotero.Sync.Server = new function () {
 			// TODO: localize
 			_error("Auto-syncing disabled until " + timeStr);
 		}
+		
+		
+		if (firstChild.localName == 'error' && firstChild.getAttribute('code') == 'ITEM_MISSING') {
+			var [libraryID, key] = firstChild.getAttribute('missingItem').split('/');
+			if (libraryID == Zotero.libraryID) {
+				libraryID = null;
+			}
+			var item = Zotero.Items.getByLibraryAndKey(libraryID, key);
+			if (item) {
+				Zotero.DB.rollbackAllTransactions();
+				item.updateClientDateModified();
+			}
+		}
 	}