storage.js (5255B)
1 /* 2 ***** BEGIN LICENSE BLOCK ***** 3 4 Copyright © 2009 Center for History and New Media 5 George Mason University, Fairfax, Virginia, USA 6 http://zotero.org 7 8 This file is part of Zotero. 9 10 Zotero is free software: you can redistribute it and/or modify 11 it under the terms of the GNU Affero General Public License as published by 12 the Free Software Foundation, either version 3 of the License, or 13 (at your option) any later version. 14 15 Zotero is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 GNU Affero General Public License for more details. 19 20 You should have received a copy of the GNU Affero General Public License 21 along with Zotero. If not, see <http://www.gnu.org/licenses/>. 22 23 ***** END LICENSE BLOCK ***** 24 */ 25 26 27 Zotero.Sync.Storage = new function () { 28 29 // TEMP 30 this.__defineGetter__("defaultError", function () { return Zotero.getString('sync.storage.error.default', Zotero.appName); }); 31 this.__defineGetter__("defaultErrorRestart", function () { return Zotero.getString('sync.storage.error.defaultRestart', Zotero.appName); }); 32 33 var _itemDownloadPercentages = {}; 34 35 // 36 // Public properties 37 // 38 this.compressionTracker = { 39 compressed: 0, 40 uncompressed: 0, 41 get ratio() { 42 return (Zotero.Sync.Storage.compressionTracker.uncompressed - 43 Zotero.Sync.Storage.compressionTracker.compressed) / 44 Zotero.Sync.Storage.compressionTracker.uncompressed; 45 } 46 } 47 48 49 /** 50 * Check if modification time of file on disk matches the mod time 51 * in the database 52 * 53 * @param {Integer} itemID 54 * @return {Boolean} 55 */ 56 this.isFileModified = function (itemID) { 57 var item = Zotero.Items.get(itemID); 58 var file = item.getFile(); 59 if (!file) { 60 return false; 61 } 62 63 var fileModTime = item.attachmentModificationTime; 64 if (!fileModTime) { 65 return false; 66 } 67 68 var syncModTime = item.attachmentSyncedModificationTime; 69 if (fileModTime != syncModTime) { 70 var syncHash = item.attachmentSyncedHash; 71 if (syncHash) { 72 var fileHash = item.attachmentHash; 73 if (fileHash && fileHash == syncHash) { 74 Zotero.debug("Mod time didn't match (" + fileModTime + "!=" + syncModTime + ") " 75 + "but hash did for " + file.leafName + " -- ignoring"); 76 return false; 77 } 78 } 79 return true; 80 } 81 82 return false; 83 } 84 85 86 this.getItemDownloadImageNumber = function (item) { 87 var numImages = 64; 88 89 var lk = item.libraryID + "/" + item.key; 90 91 if (typeof _itemDownloadPercentages[lk] == 'undefined') { 92 return false; 93 } 94 95 var percentage = _itemDownloadPercentages[lk]; 96 return Math.round(percentage / 100 * (numImages - 1)) + 1; 97 } 98 99 100 /** 101 * @param {String} libraryKey 102 * @param {Number|NULL} 103 */ 104 this.setItemDownloadPercentage = function (libraryKey, percentage) { 105 Zotero.debug("Setting image download percentage to " + percentage 106 + " for item " + libraryKey); 107 108 if (percentage !== false) { 109 _itemDownloadPercentages[libraryKey] = percentage; 110 } 111 else { 112 delete _itemDownloadPercentages[libraryKey]; 113 } 114 115 var libraryID, key; 116 [libraryID, key] = libraryKey.split("/"); 117 var item = Zotero.Items.getByLibraryAndKey(libraryID, key); 118 // TODO: yield or switch to queue 119 Zotero.Notifier.trigger('redraw', 'item', item.id, { column: "hasAttachment" }); 120 121 var parent = item.parentItemKey; 122 if (parent) { 123 var parentItem = Zotero.Items.getByLibraryAndKey(libraryID, parent); 124 var parentLibraryKey = libraryID + "/" + parentItem.key; 125 if (percentage !== false) { 126 _itemDownloadPercentages[parentLibraryKey] = percentage; 127 } 128 else { 129 delete _itemDownloadPercentages[parentLibraryKey]; 130 } 131 Zotero.Notifier.trigger('redraw', 'item', parentItem.id, { column: "hasAttachment" }); 132 } 133 } 134 135 136 function error(e) { 137 if (_syncInProgress) { 138 Zotero.Sync.Storage.QueueManager.cancel(true); 139 _syncInProgress = false; 140 } 141 142 Zotero.DB.rollbackAllTransactions(); 143 144 if (e) { 145 Zotero.debug(e, 1); 146 } 147 else { 148 e = Zotero.Sync.Storage.defaultError; 149 } 150 151 if (e.error && e.error == Zotero.Error.ERROR_ZFS_FILE_EDITING_DENIED) { 152 setTimeout(function () { 153 var group = Zotero.Groups.get(e.data.groupID); 154 155 var ps = Components.classes["@mozilla.org/embedcomp/prompt-service;1"] 156 .getService(Components.interfaces.nsIPromptService); 157 var buttonFlags = (ps.BUTTON_POS_0) * (ps.BUTTON_TITLE_IS_STRING) 158 + (ps.BUTTON_POS_1) * (ps.BUTTON_TITLE_CANCEL) 159 + ps.BUTTON_DELAY_ENABLE; 160 var index = ps.confirmEx( 161 null, 162 Zotero.getString('general.warning'), 163 Zotero.getString('sync.storage.error.fileEditingAccessLost', group.name) + "\n\n" 164 + Zotero.getString('sync.error.groupWillBeReset') + "\n\n" 165 + Zotero.getString('sync.error.copyChangedItems'), 166 buttonFlags, 167 Zotero.getString('sync.resetGroupAndSync'), 168 null, null, null, {} 169 ); 170 171 if (index == 0) { 172 // TODO: transaction 173 group.erase(); 174 Zotero.Sync.Server.resetClient(); 175 Zotero.Sync.Storage.resetAllSyncStates(); 176 Zotero.Sync.Runner.sync(); 177 return; 178 } 179 }, 1); 180 } 181 } 182 } 183 184 185