So’s your facet: Faceted global search for Mozilla Thunderbird

faceting-gloda-hover-davida-1

Following in the footsteps of the MIT SIMILE project’s Exhibit tool (originally authored by David Huynh) and Thunderbird Seek extension (again by David Huynh), we are hoping to land faceted global search for Thunderbird 3.0 (a la gloda) in beta 4.

I think it’s important to point out how ridiculously awesome the Seek extension is.  It is the only example of faceted browsing or search in an e-mail client that I am aware of.  (Note: I have to assume there are some research e-mail clients out there with faceting, but I haven’t seen them.)  Given the data model available to extensions in Thunderbird 2.0 and the idiosyncratic architecture of the UI code in 2.0, it’s not only a feature marvel but also a technical marvel.

Unfortunately, there was only so much Seek could do before it hit a wall given the limitations it had to work with.  Thunderbird 2.0’s per-folder indices are just that, per-folder.  They also require (fast) O(n) search on any attribute other than their unique key.  Although Seek populated an in-memory index for each folder, it was faced with having to implement its own global indexer and persistent database.

Gloda is now at a point where a global database should no longer be the limiting factor for extensions, or the core Thunderbird experience…

faceting-gloda-action-tag-hover-bienvenu-1

The screenshots are of a fulltext search for “gloda” in my message store.  The first screenshot is without any facets applied and me hovering over one of David Ascher’s e-mail address.  The second is after having selected the “!action” tag and hovering over one of David Bienvenu’s e-mail address.  Gloda has a concept of contact aggregation of identities but owing to a want of UI for this in the address-book right now, it doesn’t happen.  We do not yet coalesce (approximately) duplicate messages, which explains any apparent duplicates you see.

The current state of things is a result of development effort by myself and David Ascher with design input from Bryan Clark and Andreas Nilsson (with hopefully much more to come soon :).  Although we aren’t using much code from our previous exptoolbar efforts, a lot of the thinking is based on the work David, Bryan, and myself did on that.  Much thanks to Kent James, Siddharth Agarwal, and David Bienvenu for their recent and ongoing improvements to the gloda (and mailnews) back-end which help make this hopefully compelling UI feature actually usable through efficient and comprehensive indexing that does not make you want to throw your computer through a window.

If you use linux or OS X, I just linked you to try server builds.  The windows try server was sadly on fire and so couldn’t attend the build party.  The bug tracking the enhancement is bug 474711 and has repository info if you want to spin your own build.  New try server builds will also be noted there.  Please keep in mind that this is an in-progress development effort; it is not finished, there are bugs.  Accordingly, please direct any feedback/discussion to the dev-apps-thunderbird list / newsgroup rather than the bug.  Please beware that increases in awesomeness require that your gloda database be automatically blown away if you try the new version.  And first you have to turn gloda on if you have not already.

BugXhibit: Exhibit on Bugzilla results

bugxhibit-timeline

I know it has sorta been done before (found via Bugzilla Fixup Wiki Page on a comment by faaborg), and I feel like there has to be another live version somewhere, but here we are.  BugXhibit is an MIT SIMILE Exhibit widget fronting a bugzilla.mozilla.org quicksearch query.

Click here to go to a BugXhibit page where you can enter your own query.  Enter “gloda” if you want to see what the screenshots are based on.  I feel like it would be improper of me to provide a link with a live query though.

Go visit the hg repo.  Or just download the source from the previous link.  Please improve!  (See the SIMILE Exhibit docs for how to do that.  It’s all really easy.)

bugxhibit-tile-view

Notes:

  • This uses bugzilla’s ctype=js for buglist.cgi.  It apparently has been around since 2003 (bug)!  And thanks to Gerv!  Perhaps not too surprisingly, the format of the results is not inert JSON but live JS code that builds a would-be-Array where each bug’s info is stored in an array.  What each element in the array stands for cannot be known from the results.  I find that using ctype=csv is a good way to get the headers.  Rather than doing that every time (cost concerns on the redundant query), I did it once for columnlist=all (which we always use) and stashed it in bugxhibit.js.  This is dangerous because it is brittle; if you try and use bugxhibit against a saved search someone made public, I at least got many fewer columns (despite columnlist=all), and things just don’t match.  Not to mention there is a “cf_blocking_fennec” flag in there that I feel like should not be there.
  • It looks pretty easy to have bugzilla produce more sane JSON output via a template (although the security code that logs you out for a js request still should run, so don’t forget buglist.cgi.)
  • Even with all columns exposed when using buglist.cgi, there are lots of interesting things that are not exposed.  For example, flags are not exposed via buglist.cgi, so faceting on whether things are blockers or wanted can’t be done.  Once you know the bug numbers from the query, you can obviously go fetch additional information, though I think that currently still needs to be XML format, but that’s not that hard.
  • The code is friendly and splits up the whiteboard and keyword things so it does what you would expect and is not stupid.
  • I made sliders for patch count and votes.  They don’t work for me anymore, and I see XUL wrapper anger (on Firefox 3.0.x), so, uh, don’t be surprised if they fall down.
  • The UI obviously sucks.  But it’s a proof of concept, and you are the internet!  You can do anything!

displaying execution traces on a SIMILE timeline

chronimoz-timeline-1

chroniquery can now output JSON for display using the SIMILE timeline widget.  And I am finally done trying to figure out what was going wrong.  Click the pictures to experience the timeline sensation for yourself.

Related interesting things:

  • Supports a fancy if specific constraint mechanism.  For example, PrepareAndDispatch is only displayed in the context of nsTimerImpl::Fire using the following line in the config file:
[func@PrepareAndDispatch]
only_show_if=backtrace,4,nsTimerImpl::Fire
  • Supports displaying arguments in the title using the config file.  For example, displaying the observer service’s topic (plus putting it in its own band and giving it a nice prefix):
[class@nsObserverService]
prefixAlias=Obs:
band=context
list_args=aTopic
  • We actually get the dump() output by logging where _IO_fputs shows up.  We constrain its output by adding an extensible (if currently somewhat specialized) argument-based constraint.
  • Things in red are red because their return codes were exceptional, per my last blog post.  Things in other colors are that way because of the config file.
  • The bubbles that show up when you click on things tell you the return value and arguments for the call in question.  We could include a backtrace, but they are expensive to compute (currently), so I don’t.
  • All layout is using the timeline widget’s layout.  There is no correspondence between stack depth and anything else.

chronimoz-timeline-2

An important limitation is that all functions displayed here were explicitly chosen for display.  Some form of automated mechanism could be used, but unless chronicle-query starts caching more things, it would be really slow.  Here’s the command-line used for the above:

chron-xpc mozrun-9022.db jsontrace -t 1 -f nsObserverService::NotifyObservers -f nsThread::ProcessNextEvent -f nsTimerImpl::Fire -f nsMsgSearchSession::NotifyListenersDone -f nsMsgDBFolder::Shutdown  -f nsMsgLocalMailFolder::AddMessage -f nsMsgDatabase::Open -f nsMsgDatabase::ForceClosed -f nsMsgLocalMailFolder::GetDatabaseWithReparse -f nsMsgDBFolder::OnAnnouncerGoingAway -f nsMsgDBFolder::AddSubfolder -f nsMsgSearchOfflineMail::OpenSummaryFile -f nsMsgSearchSession::TimerCallback -f nsMsgSearchSession::TimeSlice -f nsMsgSearchSession::TimeSliceSerial -f nsMsgSearchScopeTerm::TimeSlice -f nsMsgXFVirtualFolderDBView::Open -f nsMsgXFVirtualFolderDBView::OnNewSearch -f nsMsgXFVirtualFolderDBView::OnSearchDone  -f js_GC -f PrepareAndDispatch -f nsMsgLocalMailFolder::UpdateFolder -f _IO_fputs