{"id":2294,"date":"2012-08-23T12:20:01","date_gmt":"2012-08-23T17:20:01","guid":{"rendered":"http:\/\/mikeconley.ca\/blog\/?p=2294"},"modified":"2023-12-20T16:25:12","modified_gmt":"2023-12-20T21:25:12","slug":"rambling-about-a-new-address-book-for-thunderbird","status":"publish","type":"post","link":"https:\/\/mikeconley.ca\/blog\/2012\/08\/23\/rambling-about-a-new-address-book-for-thunderbird\/","title":{"rendered":"Rambling about a new Address Book for Thunderbird"},"content":{"rendered":"<p>Hey all.<\/p>\n<p>I&#8217;ve been pretty bad about talking about the address book. Sorry about that. I&#8217;ve been pretty busy helping to get Instant Messaging shipped for TB 15.<\/p>\n<p>But with IM polished off, I&#8217;ve (once again) started refocusing my attention to the address book.<\/p>\n<p>So where am I?<\/p>\n<h3>The Ensemble Project<\/h3>\n<p>In short, I&#8217;m writing an add-on to experiment with approaches to a new address book. I&#8217;m calling it &#8220;Thunderbird Ensemble&#8221;, because every project needs a cool code name.<\/p>\n<p><em>The add-on is in its very very early stages.<\/em> Nothing is usable. Nothing is stable or guaranteed. There&#8217;s no UI yet, but there are some tests.<\/p>\n<p><a href=\"https:\/\/github.com\/mikeconley\/thunderbird-ensemble\">You can track my progress here.<\/a><\/p>\n<p>Here are some highlights, implementation details and unstructured thoughts about the add-on, and where I&#8217;m going with it:<\/p>\n<h4>SQLite Storage Back-end<\/h4>\n<p>I&#8217;ve chosen to use SQLite (via mozStorage) for the contact database. I was originally toying with using indexedDB, but it&#8217;s lack of support for substring searches (which is necessary for things like auto-complete) wasn&#8217;t very appealing. I briefly toyed with throwing my own indexing layer on TOP of indexedDB, and then I realized that I was probably reinventing the wheel.<\/p>\n<p>So SQLite it is!<\/p>\n<h4>Diffs, Diffs Everywhere<\/h4>\n<p>Contact records are a representation of the fields and meta data about a contact. My add-on will be able to calculate diffs between records, and those diffs can be applied on top of records to make changes.<\/p>\n<p>So, for example, suppose I decide to make some changes to a contact &#8211; I add some email addresses, remove a phone number, and change a birthday. I&#8217;m effectively creating a diff.<\/p>\n<p>Now we apply the diff on top of the original contact, and send the resulting contact record to the datastore for storage.<\/p>\n<p>If the storage happens to be on the network, and the original record we applied the diff on to was out of date, we should get a fresh copy of the contact record, apply the diff, and try again.<\/p>\n<h4>Conflict Resolution<\/h4>\n<p>With diffs comes conflicts resolution &#8211; but conflict resolution is never a pleasant experience, and I&#8217;d like the user to not have to deal with that if possible.<\/p>\n<p>My solution is to just be optimistic &#8211; if a diff is asking to remove something that isn&#8217;t there, great! Mission accomplished! If the diff is adding something that already exists, no problem! We skip!<\/p>\n<p>And for things that get changed, like birthdays, we simply say that the last writer wins.<\/p>\n<p>Maybe that&#8217;s naive, but that&#8217;s the approach that I&#8217;m taking.<\/p>\n<h4>What do I have?<\/h4>\n<p>I can create contact records, diff them, apply diffs, and &#8220;merge&#8221; two records together. And I have tests for all of that work.<\/p>\n<p>I&#8217;ve got the start of the SQLite backend working (basically, we can set up the database&#8230;but that&#8217;s it.)<\/p>\n<p>I&#8217;m currently working on importing old Thunderbird contacts into Ensemble&#8217;s notion of contact records.<\/p>\n<p>After that, I&#8217;ll work on getting them written to the database.<\/p>\n<p>Comments? Questions? Complaints? Ask them here. It&#8217;s still really early on in the process, but if you find bugs in my code, please file issues on GitHub.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey all. I&#8217;ve been pretty bad about talking about the address book. Sorry about that. I&#8217;ve been pretty busy helping to get Instant Messaging shipped for TB 15. But with IM polished off, I&#8217;ve (once again) started refocusing my attention to the address book. So where am I? The Ensemble Project In short, I&#8217;m writing [&hellip;]<\/p>\n","protected":false},"author":4,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[5,861,862],"tags":[934,935,96,35,867],"class_list":["post-2294","post","type-post","status-publish","format-standard","hentry","category-computer-science","category-mozilla-2","category-thunderbird","tag-address-book","tag-contacts","tag-ensemble","tag-mozilla","tag-thunderbird-2"],"jetpack_publicize_connections":[],"jetpack_featured_media_url":"","jetpack_shortlink":"https:\/\/wp.me\/prmTy-B0","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/mikeconley.ca\/blog\/wp-json\/wp\/v2\/posts\/2294","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mikeconley.ca\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mikeconley.ca\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mikeconley.ca\/blog\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/mikeconley.ca\/blog\/wp-json\/wp\/v2\/comments?post=2294"}],"version-history":[{"count":3,"href":"https:\/\/mikeconley.ca\/blog\/wp-json\/wp\/v2\/posts\/2294\/revisions"}],"predecessor-version":[{"id":3103,"href":"https:\/\/mikeconley.ca\/blog\/wp-json\/wp\/v2\/posts\/2294\/revisions\/3103"}],"wp:attachment":[{"href":"https:\/\/mikeconley.ca\/blog\/wp-json\/wp\/v2\/media?parent=2294"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mikeconley.ca\/blog\/wp-json\/wp\/v2\/categories?post=2294"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mikeconley.ca\/blog\/wp-json\/wp\/v2\/tags?post=2294"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}