Name of the extension
I haven’t figured out a name for the extension yet. I initially named it gcontacts, but that name already exists for several programs. gcontactsync is a potential name. Any suggestions are welcome.
While syncing some newly-created cards, I encountered the following error:
org.xml.sax.SAXParseException: The entity name must immediately follow the “&”; in the entity reference.
The cause was an oversight on my part during the conversion from an nsIAbCard to an XML representation of the contact. I had forgotten to replace special characters, such as &, <, >, ‘, and ” with &, <, >, ‘, and “, respectively. I was fortunate to catch this error before it caused any real problems. I also wrote a function to do the opposite when converting from XML to an nsIAbCard.
Code refactoring and reformatting
While browsing through the code, I realized that I had changed many of the functions and their parameter types without changing the name and the contents of some of the global variables had also changed, so I started refactoring the code. I am also reformatting the code.
lastModifiedDate/Address Book Listener
Since I added support for lastModifiedDate, I no longer need the address book listener.
I didn’t like my previous HTTP Request methods, so made a few slight modifications. I currently have a generic method for sending an XMLHttpRequest with arguments for the type (POST, PUT, GET, DELETE), URL, body, header label(s)/value(s), and arrays of commands, as strings, to be evaluated depending on the response (OK, 0, or offline, and any error) since the XMLHttpRequest used is asynchronous. This flexibility allows me to call the same function for any HTTP Request that the program must send and act on the outcome.
More contacts supported
When a request is sent to Google for contacts, it only sends the first 25 by default. I now use the max-results query parameter to get the first 250 contacts. 250 was arbitrary, but having that many contacts to sync would probably take a long time. There is now a preference for the number of contacts supported by the extension.
I made a few miscellaneous improvements that resulted in a slight performance increase. More global variables were removed as well.
I was attempting to change my sync process today when I opened the Address Book and was greeted with 925 new Address Books. In the end, cleaning obj directory and rebuilding fixed the problem. Strange, but at least my extension wasn’t the direct cause of the problem.
I found and fixed an error that would sometimes occur when trying to sync after adding several new contacts.
After fixing that error, I re-defined what two cards must have in common for the sync function to consider them identical. Since Google only allows one contact/e-mail address, it first checks if the cards have any e-mail address in common (primaryEmail or secondEmail). If there aren’t any e-mail addresses (which is allowed in Thunderbird and Google) it checks the name.
I rewrote my old method to sync individual cards now that I use custom4 for the last modified date. It checks to see first if both have changed (and will eventually have a preference that can ask the user what to do in this case or pick one to always update) and then checks to see which (if any) changed and updates it. Unfortunately, updating a Thunderbird card isn’t as efficient as it could be. I kept getting NS_NOINTERFACE errors while trying to call the modifyCard function in the address book, so I have to actually delete the card and then add the card from Google… Updating a Google contact needs to be re-done soon, too.
In my casual tests I didn’t find any other errors. It now works well offline and syncs every 30 minutes by default or manually. Out of the 11 average contacts I added on one computer, every one synced perfectly with Google and with my other computer.
The only catch so far is that it has to use the card’s custom4 property to store the lastModifiedDate.