1 /* ***** BEGIN LICENSE BLOCK ***** 2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 3 * 4 * The contents of this file are subject to the Mozilla Public License Version 5 * 1.1 (the "License"); you may not use this file except in compliance with 6 * the License. You may obtain a copy of the License at 7 * http://www.mozilla.org/MPL/ 8 * 9 * Software distributed under the License is distributed on an "AS IS" basis, 10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License 11 * for the specific language governing rights and limitations under the 12 * License. 13 * 14 * The Original Code is gContactSync. 15 * 16 * The Initial Developer of the Original Code is 17 * Josh Geenen <gcontactsync@pirules.org>. 18 * Portions created by the Initial Developer are Copyright (C) 2008-2010 19 * the Initial Developer. All Rights Reserved. 20 * 21 * Contributor(s): 22 * 23 * Alternatively, the contents of this file may be used under the terms of 24 * either the GNU General Public License Version 2 or later (the "GPL"), or 25 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), 26 * in which case the provisions of the GPL or the LGPL are applicable instead 27 * of those above. If you wish to allow use of your version of this file only 28 * under the terms of either the GPL or the LGPL, and not to allow others to 29 * use your version of this file under the terms of the MPL, indicate your 30 * decision by deleting the provisions above and replace them with the notice 31 * and other provisions required by the GPL or the LGPL. If you do not delete 32 * the provisions above, a recipient may use your version of this file under 33 * the terms of any one of the MPL, the GPL or the LGPL. 34 * 35 * ***** END LICENSE BLOCK ***** */ 36 37 if (!com) var com = {}; // A generic wrapper variable 38 // A wrapper for all GCS functions and variables 39 if (!com.gContactSync) com.gContactSync = {}; 40 41 /** 42 * An object that can obtain address books by the name or URI, find the synced 43 * address books, and edit contacts. 44 * @extends com.gContactSync.AbManager 45 * @class 46 */ 47 com.gContactSync.GAbManager = com.gContactSync.AbManager; 48 49 /** Stores GAddressBook objects keyed by preference ID *AND* URI */ 50 com.gContactSync.GAbManager.mABs = {}; 51 52 /** 53 * Resets all synchronized address books in the following ways: 54 * - Deletes all mailing lists 55 * - Deletes all contacts 56 * - Sets the last sync date to 0. 57 * See AddressBook.reset for more details. 58 * 59 * It asks the user to restart Thunderbird when finished. 60 * 61 * @param showConfirm {boolean} Show a confirmation dialog first and quit if 62 * the user presses Cancel. 63 */ 64 com.gContactSync.GAbManager.resetAllSyncedABs = 65 function GAbManager_resetSyncedABs(showConfirm) { 66 if (showConfirm) { 67 if (!com.gContactSync.confirm(com.gContactSync.StringBundle.getStr("confirmReset"))) { 68 return false; 69 } 70 } 71 72 com.gContactSync.LOGGER.LOG("Resetting all synchronized directories."); 73 var abs = com.gContactSync.GAbManager.getSyncedAddressBooks(true), 74 i, 75 needRestart = false;; 76 for (i in abs) { 77 if (abs[i].ab && abs[i].ab.mPrefs.Disabled !== "true") { 78 needRestart = abs[i].ab.reset() || needRestart; 79 } 80 } 81 82 com.gContactSync.LOGGER.LOG("Finished resetting all synchronized directories."); 83 if (needRestart) { 84 com.gContactSync.alert(com.gContactSync.StringBundle.getStr("pleaseRestart")); 85 } 86 return true; 87 }; 88 /** 89 * Returns an object filled with GAddressBook objects. 90 * The properties are the names of those address books. 91 * @param aMakeArray {boolean} If this parameter evaluates as true then the 92 * returned object will be an array. 93 * @returns If aMakeArray then the returned object is an array of objects. 94 * Each object has a 'username' property with the username of this 95 * synced AB and an 'ab' property with a GAddressBook object. 96 * If !aMakeArray then the returned object is keyed by username and 97 * the value of that property is an array of GAddressBook objects. 98 */ 99 com.gContactSync.GAbManager.getSyncedAddressBooks = 100 function AbManager_getSyncedAddressBooks(aMakeArray) { 101 this.mAddressBooks = {}; 102 var iter, 103 abManager, 104 dir, 105 data, 106 ab, 107 username, 108 arr = [], 109 i, 110 j; 111 if (Components.classes["@mozilla.org/abmanager;1"]) { // TB 3 112 abManager = Components.classes["@mozilla.org/abmanager;1"] 113 .getService(Components.interfaces.nsIAbManager); 114 iter = abManager.directories; 115 } 116 else { // TB 2 117 // obtain the main directory through the RDF service 118 dir = Components.classes["@mozilla.org/rdf/rdf-service;1"] 119 .getService(Components.interfaces.nsIRDFService) 120 .GetResource("moz-abdirectory://") 121 .QueryInterface(Components.interfaces.nsIAbDirectory); 122 iter = dir.childNodes; 123 } 124 while (iter.hasMoreElements()) { 125 data = iter.getNext(); 126 if (data instanceof Components.interfaces.nsIAbDirectory && (this.mVersion === 3 || 127 data instanceof Components.interfaces.nsIAbMDBDirectory)) { 128 ab = this.getGAb(data); 129 username = ab.mPrefs.Username; 130 if (username && username.toLowerCase() !== "none") { 131 if (!this.mAddressBooks[username]) 132 this.mAddressBooks[username] = []; 133 this.mAddressBooks[username].push(ab); 134 } 135 } 136 } 137 if (!aMakeArray) 138 return this.mAddressBooks; 139 // now convert to an array 140 arr = []; 141 for (i in this.mAddressBooks) { 142 for (j in this.mAddressBooks[i]) { 143 arr.push({ 144 username: i, 145 ab: this.mAddressBooks[i][j] 146 }); 147 } 148 } 149 return arr; 150 }; 151 152 /** 153 * Backs up the given address book. This consists of copying the Mork Address 154 * Book (MAB) file into the gContactSync directory. 155 * The backup is prefixed with the value of aPrefix (if not blank) followed by 156 * the original name of the file and ended with the value of aSuffix. 157 * NOTE: If a file already exists with the 158 * @param aAb {GAddressBook} The address book to backup. 159 * @returns {boolean} True if the AB was successfully backed up 160 */ 161 com.gContactSync.GAbManager.backupAB = function GAbManager_backupAB(aAB, aPrefix, aSuffix) { 162 var destFile = com.gContactSync.FileIO.getProfileDirectory(), 163 uri = aAB.mURI, 164 srcFileName = uri.substr(1 + uri.lastIndexOf("/")), 165 srcFile = com.gContactSync.FileIO.getProfileDirectory(), 166 lines = []; 167 // the source file is profile_dir/{FileNameFromURI} 168 srcFile.append(srcFileName); 169 // the destination is profile_dir/gcontactsync/{aPrefix}{FileName}{aSuffix} 170 destFile.append(com.gContactSync.FileIO.fileNames.FOLDER_NAME); 171 destFile.append(com.gContactSync.FileIO.fileNames.AB_BACKUP_DIR); 172 destFile.append((aPrefix || "") + srcFileName + (aSuffix || "")); 173 com.gContactSync.LOGGER.LOG("Beginning a backup of the Address Book:\n" + 174 srcFile.path + "\nto:\n" + destFile.path); 175 // make sure the AB we are copying exists 176 if (!srcFile.exists()) { 177 com.gContactSync.LOGGER.LOG_ERROR("The source file does not exist"); 178 return false; 179 } 180 if (com.gContactSync.FileIO.copyFile(srcFile, destFile)) { 181 aAB.savePref("lastBackup", (new Date()).getTime()); 182 com.gContactSync.LOGGER.LOG(" - Backup finished successfully"); 183 return true; 184 } 185 com.gContactSync.LOGGER.LOG(" - Unable to read the source address book"); 186 return false; 187 }; 188 189 /** 190 * Returns a GAddressBook object for the given URI. 191 * If a GAddressBook for the URI or directory's pref branch has already been 192 * returned and is still stored, it is returned and no new object is created. 193 */ 194 com.gContactSync.GAbManager.getGAbByURI = function GAbManager_getGAbByURI(aURI) { 195 // first check if a GAddressBook object for the URI already exists 196 var ab = com.gContactSync.GAbManager.mABs[aURI] 197 if (ab) { 198 return ab; 199 } 200 // if it hasn't been obtained yet, get the nsIAbDirectory through its URI 201 // then get a GAddressBook object from that and add it to 202 // com.gContactSync.GAbManager.mABs 203 return com.gContactSync.GAbManager.getGAb(com.gContactSync.GAbManager.getAbByURI(aURI)); 204 }; 205 206 /** 207 * Returns a GAddressBook object for the given nsIAbDirectory. 208 * If a GAddressBook for the directory's URI or pref branch has already been 209 * returned and is still stored, it is returned and no new object is created. 210 */ 211 com.gContactSync.GAbManager.getGAb = function GAbManager_getGAb(aDirectory, aNoPrefs) { 212 if (!aDirectory) { 213 return aDirectory; 214 } 215 // first check if a GAddressBook object for the URI already exists 216 // if so, return it 217 var uri = aDirectory.URI || aDirectory.getDirUri(); 218 if (uri && com.gContactSync.GAbManager.mABs[uri]) { 219 return com.gContactSync.GAbManager.mABs[uri]; 220 } 221 // otherwise create a new GAddressBook object and add it to 222 // com.gContactSync.GAbManager.mABs 223 var ab = new com.gContactSync.GAddressBook(aDirectory, aNoPrefs); 224 com.gContactSync.GAbManager.mABs[ab.mURI] = ab; 225 com.gContactSync.GAbManager.mABs[ab.getPrefId()] = ab; 226 return ab; 227 }; 228 229 /** 230 * Returns an object filled with GAddressBook objects keyed by URI. 231 * @param aDirType {int} The type of directory (2 is the usual Mork AB) 232 * @returns {object} An object filled with GAddressBook objects keyed by URI. 233 */ 234 com.gContactSync.GAbManager.getAllAddressBooks = function GAbManager_getAllAddressBooks(aDirType) { 235 var iter, 236 abManager, 237 dir, 238 abs = {}, 239 data, 240 ab, 241 dirType; 242 if (Components.classes["@mozilla.org/abmanager;1"]) { // TB 3 243 abManager = Components.classes["@mozilla.org/abmanager;1"] 244 .getService(Components.interfaces.nsIAbManager); 245 iter = abManager.directories; 246 } 247 else { // TB 2 248 // obtain the main directory through the RDF service 249 dir = Components.classes["@mozilla.org/rdf/rdf-service;1"] 250 .getService(Components.interfaces.nsIRDFService) 251 .GetResource("moz-abdirectory://") 252 .QueryInterface(Components.interfaces.nsIAbDirectory); 253 iter = dir.childNodes; 254 } 255 while (iter.hasMoreElements()) { 256 data = iter.getNext(); 257 if (data instanceof Components.interfaces.nsIAbDirectory && (this.mVersion === 3 || 258 data instanceof Components.interfaces.nsIAbMDBDirectory)) { 259 260 // If data isn't a valid AB then skip to the next one. 261 try { 262 ab = this.getGAb(data); 263 } catch (e) { 264 continue; 265 } 266 dirType = ab.getDirType(); 267 // If no dir type was passed or the type matches then add it to abs 268 if (this.mVersion < 3 || aDirType === undefined || dirType === aDirType) 269 abs[ab.mURI] = ab; 270 } 271 } 272 return abs; 273 }; 274