<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>java rants &#187; Apple</title>
	<atom:link href="http://www.javarants.com/category/apple/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.javarants.com</link>
	<description>Rants about Java and other internet technologies by Sam Pullara</description>
	<lastBuildDate>Thu, 11 Mar 2010 23:26:27 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Build your own mail analyzer for Mac Mail.app</title>
		<link>http://www.javarants.com/2008/12/26/build-your-own-mail-analyzer-for-mac-mailapp/</link>
		<comments>http://www.javarants.com/2008/12/26/build-your-own-mail-analyzer-for-mac-mailapp/#comments</comments>
		<pubDate>Sat, 27 Dec 2008 03:46:49 +0000</pubDate>
		<dc:creator>Sam Pullara</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[mail]]></category>
		<category><![CDATA[yahoo]]></category>

		<guid isPermaLink="false">http://www.javarants.com/?p=943</guid>
		<description><![CDATA[You&#8217;ve probably read about things like Xoopit and Xobni for analyzing both online mail and your outlook mail.  As it turns out, Apple has done something great in this regard that I think has been mostly overlooked.  Mail.app stores all of the meta-data for you email in a file called ~/Library/Mail/Envelope Index.  [...]]]></description>
			<content:encoded><![CDATA[<p>You&#8217;ve probably read about things like Xoopit and Xobni for analyzing both online mail and your outlook mail.  As it turns out, Apple has done something great in this regard that I think has been mostly overlooked.  Mail.app stores all of the meta-data for you email in a file called <i>~/Library/Mail/Envelope Index</i>.  You might wonder what the format of this file is&#8230; well it is a SQLite3 database.  The contents are pretty easy to see, go to the terminal and type:</p>
<p><code>macpro:~ sam$ sqlite3 ~/Library/Mail/Envelope\ Index<br />
SQLite version 3.6.3<br />
Enter ".help" for instructions<br />
Enter SQL statements terminated with a ";"<br />
sqlite><br />
</code><br />
<span id="more-943"></span><br />
Everything about your mailboxes is stored within this database and the structure of the database is normalized so its very easy to navigate.  The tables of most interest for mail analysis are:</p>
<pre>
sqlite> .tables
<strong>addresses</strong>              <strong>mailboxes</strong>              todo_notes
alarms                 <strong>messages</strong>               todos
associations           properties             todos_deleted_log
<strong>attachments</strong>            <strong>recipients</strong>             todos_server_snapshot
calendars              <strong>subjects</strong>
feeds                  <strong>threads</strong>
</pre>
<p>Fortunately, accessing a SQLite database is quite easy from just about any language that you decide to use. I&#8217;m just going to do all the queries in straight sqlite3 rather than a language, but they could be embedded in your application.  First things first, copy your <em>Envelope Index</em> to another directory:</p>
<pre>macpro:tmp sam$ cp ~/Library/Mail/Envelope\ Index .</pre>
<p>Now you can use that database without worrying about messing up the locking or corrupting data while Mail.app is using it.  Since we might as well do an example that  is interesting rather than merely educational, how about we answer the question: &#8220;Who are my coworkers with whom that I collaborated?&#8221;.  This is going to be a multi-query process to extract the information &#8212; there may be more efficient ways to do it &#8212; but think of this as instructive rather than prescriptive.  First I need to limit the query to only those mailboxes which contain work email:</p>
<pre>
<span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">DROP</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">TABLE</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> coworkermailboxes;
</span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">CREATE</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">TABLE</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> coworkermailboxes(id);
</span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">CREATE</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> INDEX coworkermailboxes_index </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">ON</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> coworkermailboxes(id);
</span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">INSERT</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">INTO</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> coworkermailboxes </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">SELECT</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> rowid </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">FROM</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> mailboxes
</span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">WHERE</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">
url </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">like</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> </span><span style="color: rgb(0,128,0); font-weight: bold; font-style: normal; ">&apos;imap://samp@snv-webmail.corp.yahoo.com/%&apos;</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">OR</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">
url </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">like</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> </span><span style="color: rgb(0,128,0); font-weight: bold; font-style: normal; ">&apos;imap://sam@mail.sampullara.com/Yahoo%20Inc%20Archive&apos;</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">;
</span>
</pre>
<p>That gives us a table with several mailboxes that I have in Mail.app including Sent Messages.  I would peruse the list of mailboxes to ensure that you are grabbing all the correct information. For me I had to also search my archives.  Now I am going to take a series of steps to get to the final out put by iteratively processing successive tables of information.  The first table, is a list of those people that you have both sent and received an email with directly (they were the sender and you were a receiver or you were the sender and they were the receiver):</p>
<pre>
<span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">DROP</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">TABLE</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> coworkers;
</span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">CREATE</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">TABLE</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> coworkers(id);
</span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">CREATE</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> INDEX coworkers_index </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">ON</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> coworkers(id);
</span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">INSERT</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">INTO</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> coworkers </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">SELECT</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> a.rowid </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">FROM</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> addresses a, messages m, recipients r
</span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">WHERE</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">
m.sender = a.rowid </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">AND</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">
m.mailbox </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">IN</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> (</span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">SELECT</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> id </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">FROM</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> coworkermailboxes) </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">AND</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">
r.message_id = m.rowid </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">AND</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> r.address_id = </span><span style="color: rgb(0,0,255); font-weight: normal; font-style: normal; ">4</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">
</span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">INTERSECT</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">
</span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">SELECT</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> a.rowid </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">FROM</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> addresses a, messages m, recipients r
</span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">WHERE</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">
m.sender = </span><span style="color: rgb(0,0,255); font-weight: normal; font-style: normal; ">4</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">AND</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">
m.mailbox </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">IN</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> (</span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">SELECT</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> id </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">FROM</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> coworkermailboxes) </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">AND</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">
r.message_id = m.rowid </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">AND</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> r.address_id = a.rowid
;
</span>
</pre>
<p>Note I have directly inserted my addresses rowid into this query for the sender on the one hand and the receiver on the other.  The next step will be to count the actual number of emails you have received from each of those on the list:</p>
<pre>
<span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">DROP</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">TABLE</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> coworkers2;
</span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">CREATE</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">TABLE</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> coworkers2(id, recv);
</span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">CREATE</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> INDEX coworkers2_index </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">ON</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> coworkers2(id);
</span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">SELECT</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> &quot;Get the received mail&quot;;
</span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">INSERT</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">INTO</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> coworkers2 </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">SELECT</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> w.id, </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">COUNT</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">(*) </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">FROM</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> messages m, recipients r, coworkers w
</span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">WHERE</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> m.sender = </span><span style="color: rgb(0,0,255); font-weight: normal; font-style: normal; ">4</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">AND</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">
m.mailbox </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">IN</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> (</span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">SELECT</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> id </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">FROM</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> coworkermailboxes) </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">AND</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">
r.message_id = m.rowid </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">AND</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> r.address_id = w.id
</span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">GROUP</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">BY</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> w.id </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">ORDER</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">BY</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">COUNT</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">(*)
;</span>
</pre>
<p>Finally, we count the number of sent emails and also derive a ratio of sent/received so we can judge how collaborative the exchanges have been:</p>
<pre>
<span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">DROP</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">TABLE</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> coworkers3;
</span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">CREATE</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">TABLE</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> coworkers3(id, sent </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">float</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">, recv </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">float</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">, ratio </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">float</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">);
</span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">CREATE</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> INDEX coworkers3_index </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">ON</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> coworkers3(id);
</span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">SELECT</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> &quot;Get the sent mail&quot;;
</span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">INSERT</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">INTO</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> coworkers3 </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">SELECT</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> w.id, </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">COUNT</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">(*), w.recv, </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">COUNT</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">(*)*</span><span style="color: rgb(0,0,255); font-weight: normal; font-style: normal; ">1.0</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">/w.recv </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">FROM</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> messages m, recipients r, coworkers2 w
</span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">WHERE</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">
m.sender = w.id </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">AND</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">
m.mailbox </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">IN</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> (</span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">SELECT</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> id </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">FROM</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> coworkermailboxes) </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">AND</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">
r.message_id = m.rowid </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">AND</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> r.address_id = </span><span style="color: rgb(0,0,255); font-weight: normal; font-style: normal; ">4</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">
</span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">GROUP</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">BY</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> w.id </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">ORDER</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">BY</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">COUNT</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">(*)
;</span>
</pre>
<p>You will now have a table named <em>coworkers3</em> that can be mined for information about your level of correspondence with them. For example, here is way to find relatively equal sends and receives:</p>
<pre>
<span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">SELECT</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> a.comment </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">FROM</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> addresses a, coworkers3 w
</span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">WHERE</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">
a.rowid = w.id </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">AND</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">
ratio &gt;= </span><span style="color: rgb(0,0,255); font-weight: normal; font-style: normal; ">.5</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">AND</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">
ratio &lt;=</span><span style="color: rgb(0,0,255); font-weight: normal; font-style: normal; ">2</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">AND</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">
sent &gt; </span><span style="color: rgb(0,0,255); font-weight: normal; font-style: normal; ">10</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">
</span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">ORDER</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">BY</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> sent
LIMIT </span><span style="color: rgb(0,0,255); font-weight: normal; font-style: normal; ">20</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">;</span>
</pre>
<p>When I do this I see the people that either I use to find information or that use me to find information.  Every interaction is usually a request and then a response.  On the other hand, this query will find those that typically made announcements out to the groups that I also worked with:</p>
<pre>
<span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">SELECT</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> a.comment </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">FROM</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> addresses a, coworkers3 w
</span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">WHERE</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">
a.rowid = w.id </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">AND</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">
ratio &lt;= </span><span style="color: rgb(0,0,255); font-weight: normal; font-style: normal; ">1</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">AND</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">
sent &gt; </span><span style="color: rgb(0,0,255); font-weight: normal; font-style: normal; ">10</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">
</span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">ORDER</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> </span><span style="color: rgb(0,0,128); font-weight: bold; font-style: normal; ">BY</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; "> ratio
LIMIT </span><span style="color: rgb(0,0,255); font-weight: normal; font-style: normal; ">20</span><span style="color: rgb(0,0,0); font-weight: normal; font-style: normal; ">;</span>
</pre>
<p>And so on.  Adding more filters on top of this you could easily derive your team at work for a particular time period and other insights.  With the wealth of information contained in this meta-data store you could figure out all kinds of things:</p>
<ul>
<li>Who sent you an email that you didn&#8217;t reply to yet?</li>
<li>Who do you respond to the most quickly?</li>
<li>Who responds to you most quickly?</li>
<li>What are you and your coworkers approximate working hours?</li>
<li>What groups of CCs could be made into aliases?</li>
</ul>
<p>There really is no limit to how far the analysis could go.  Ideally, it would be possible to setup a dashboard in Mail.app that let you cut and slice the data in a far more precise way than smart folders currently allow today.  Maybe they should come out with super-sql-smart folders!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.javarants.com/2008/12/26/build-your-own-mail-analyzer-for-mac-mailapp/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Time Machine vs. ZFS + rsync</title>
		<link>http://www.javarants.com/2008/10/30/time-machine-vs-zfs-rsync/</link>
		<comments>http://www.javarants.com/2008/10/30/time-machine-vs-zfs-rsync/#comments</comments>
		<pubDate>Fri, 31 Oct 2008 03:17:18 +0000</pubDate>
		<dc:creator>Sam Pullara</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[backup]]></category>
		<category><![CDATA[parallels]]></category>
		<category><![CDATA[rsync]]></category>
		<category><![CDATA[time machine]]></category>
		<category><![CDATA[virtualization]]></category>
		<category><![CDATA[vmware]]></category>
		<category><![CDATA[zfs]]></category>

		<guid isPermaLink="false">http://www.javarants.com/?p=916</guid>
		<description><![CDATA[Update: I actually got the fslogger thing at the end of this entry working so I can do incremental backups.  Not really a product yet but it isn&#8217;t hard to do.  Here is the super rough version of it.
I can&#8217;t stand inefficiency.  Time Machine is fundamentally a very inefficient mechanism for backing [...]]]></description>
			<content:encoded><![CDATA[<p><strong>Update</strong>: I actually got the fslogger thing at the end of this entry working so I can do incremental backups.  Not really a product yet but it isn&#8217;t hard to do.  <a href="http://buildandtest.com/files/rlogsync.tar.gz">Here is the super rough version of it.</a></p>
<p>I can&#8217;t stand inefficiency.  Time Machine is fundamentally a very inefficient mechanism for backing up large files that change.  So bad actually that most things like Parallels and VMWare disable backups of your disk images.  Here is the basic algorithm:<br />
<span id="more-916"></span><br />
1) Get the list of files that have changed since the last backup<br />
2) Create new directory in backup store<br />
3) Copy any file that has changed since the last backup<br />
4) Create hard links to any file or even whole directory in the new backup to the last backup for any file that has not changed</p>
<p>Step 1 is pretty efficient for Time Machine as they keep hooks into the filesystem to track those changes as they occur.  Step 2 is obviously easy.  Step 3 is a doosy.  If you change 1 byte in a VMWare image it will copy the several gigs over to the backup store.  Not a great result from such small change and that would quickly consume your disk flushing valuable older changes out of the system.  Step 4 is also very efficient because hard links are trivial to create and use virtually no space, though they did have to make special changes to HFS+ so that you could hard link directories to make Time Machine more efficient.</p>
<p>The obvious big problem here is that in the case that a file changes at all you need to copy the whole thing to you backup device.  Not that viable over the internet or even WiFi for really big files that are updated often like VM images.  You might have wondered why Apple is considering integrating ZFS directly into Mac OS X, now you know why.  ZFS lets you do something very special: create a snapshot of a whole filesystem.  Essentially a copy of that filesystem at a particular point in time and they do this without copying whole files when they change but instead at the block level.  This amazing capability is critical in this more efficient way to backup your system with multi-level snapshots.</p>
<p>Enter <a href="http://en.wikipedia.org/wiki/Rsync">rsync</a>.  Rsync has been around for a long time.  It is used by system adminstrators everywhere to efficiently update files in one location with files from another location, even over the internet.  It does this by comparing them at the block level and only sending diffs when needed to update files on the other end.  Using the right command line options you can essentially make one filesystem look like a carbon copy of another filesystem.  Using this in combination you can make a backup solution that is much better than most out there:</p>
<p>1) Rsync your current filesystem to a ZFS filesystem &#8212; remote or attached storage<br />
2) Take a snapshot of the resulting filesystem to forever capture its state</p>
<p>Those are the two steps.  Nothing more.  Here is the script that I use to backup my Macbook Air to my server at home:</p>
<pre>
#!/bin/sh
cd /Users
time rsync -av --delete sam 192.168.1.90:/Volumes/zdisk/macbookair
ssh 192.168.1.90 sudo zfs snapshot zdisk/macbookair@`date "+%s"`
</pre>
<p>This results in a set of filesytems that looks like this:</p>
<pre>
zdisk/macbookair             14.9G   898G  14.6G  /Volumes/zdisk/macbookair
zdisk/macbookair@1225350709   125M      -  14.6G  -
zdisk/macbookair@1225351248   117M      -  14.6G  -
zdisk/macbookair@1225418584  21.7M      -  14.6G  -
</pre>
<p>This obviously isn&#8217;t as awesome as using Time Machine to recover my files because I don&#8217;t have a great UI, I have to run a script and generally have to know more about the system than a Time Machine user.  However&#8230; I can update a VM without sending gigs of data over the internet to back it up or deal with not having a backup at all.</p>
<p>The only downside is that an empty backup still takes about 8 minutes to go through all my files. Next step would be to integrate into the fslogger into the solution and only look at those files that changed for sure.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.javarants.com/2008/10/30/time-machine-vs-zfs-rsync/feed/</wfw:commentRss>
		<slash:comments>11</slash:comments>
		</item>
		<item>
		<title>Macworld 2008 predictions</title>
		<link>http://www.javarants.com/2008/01/13/macworld-2008-predictions/</link>
		<comments>http://www.javarants.com/2008/01/13/macworld-2008-predictions/#comments</comments>
		<pubDate>Sun, 13 Jan 2008 17:47:39 +0000</pubDate>
		<dc:creator>Sam Pullara</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[appletv]]></category>
		<category><![CDATA[intel]]></category>
		<category><![CDATA[isight]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[macworld]]></category>
		<category><![CDATA[monitors]]></category>

		<guid isPermaLink="false">http://www.javarants.com/2008/01/11/macworld-2008-predictions/</guid>
		<description><![CDATA[UPDATE 1/13/08: This looks like confirmation of a new ultralight portable with some sort of wireless connectivity.
Might as well put up my predictions for what will be announced at Macworld this year.  I think it will be a good one.

iMac, Mac Mini, Macbook and Macbook Pro lines upgraded to Penryn processors

Same prices, better specs


Ultra [...]]]></description>
			<content:encoded><![CDATA[<p>UPDATE 1/13/08: This looks like <a href="http://forums.macrumors.com/showthread.php?t=413381">confirmation</a> of a new ultralight portable with some sort of wireless connectivity.</p>
<p>Might as well put up my predictions for what will be announced at Macworld this year.  I think it will be a good one.</p>
<ul>
<li>iMac, Mac Mini, Macbook and Macbook Pro lines upgraded to Penryn processors
<ul>
<li>Same prices, better specs</li>
</ul>
</li>
<li>Ultra portable MacBook Pro ($2-3K)
<ul>
<li>64G SSD drive standard (32G and 128G available), no DVD drive</li>
<li>12&#8243; OLED screen</li>
<li>8-12 hour battery life</li>
</ul>
</li>
<li> iPhone
<ul>
<li>SDK: Still WebKit-based but with native Javascript APIs for the phone</li>
</ul>
<ul>
<li>Better connectivity</li>
<li>Video recording</li>
</ul>
</li>
<li>Monitors
<ul>
<li>Same panel as the new 30&#8243; dell</li>
<li>Built-in iSights</li>
<li>Same prices</li>
</ul>
</li>
<li>Blu-ray
<ul>
<li>Added as an option for MacPro and MacbookPro</li>
<li>Support for playing Blu-ray movies added to 10.5.2</li>
</ul>
</li>
<li>AppleTV / iTunes
<ul>
<li> Movie rentals</li>
<li>Software upgrade for current devices</li>
<li>Possibly a new version with a blu-ray player</li>
</ul>
</li>
</ul>
<p>All these I consider relatively expected and if they don&#8217;t show up, some people will be disappointed.  Now for the truly outrageous prediction:</p>
<p><strong>APPLE WILL WIMAX ENABLE THEIR LAPTOPS AND IPHONE BY PLACING NODES IN THEIR APPLE STORES AND STARBUCKS. </strong></p>
<p>That would be the most awesome thing ever and hopefully that is what is implied with &#8220;Something is in the air&#8230;&#8221;. The other possibility is just 3G enabled systems or both for those times when you are out of range <img src='http://www.javarants.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.javarants.com/2008/01/13/macworld-2008-predictions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Applescript is pretty cool</title>
		<link>http://www.javarants.com/2003/10/21/applescript-is-pretty-cool/</link>
		<comments>http://www.javarants.com/2003/10/21/applescript-is-pretty-cool/#comments</comments>
		<pubDate>Tue, 21 Oct 2003 22:39:29 +0000</pubDate>
		<dc:creator>Sam Pullara</dc:creator>
				<category><![CDATA[Apple]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://www.javarants.com/?p=1083</guid>
		<description><![CDATA[Applescript is pretty cool ]]></description>
			<content:encoded><![CDATA[<div><span style="font-family: Helvetica;">A friend of mine was saying that a certain person he works with was like an Eliza program because he responds to email so fast.  I thought I would see how easy that was in AppleScript&#8230;</span></div>
<div><span style="font-family: Helvetica;">First I needed an Eliza program.  I picked a webservice because I heard that AppleScript can call webservices without a problem and that would let me learn two things at once.  Google gave me <a href="http://www34.brinkster.com/4xws/eliza.asmx">one</a> right away.  So I loaded up the Script Editor and started hacking.</span></p>
<p><span style="font-family: Helvetica;">First I cut and pasted some AppleScript Mail code to get the perform_mail_action callback information that I needed.  Then I looked at the examples for how to call SOAP services.  AppleScript won&#8217;t parse WSDL out of the box so I had to do that myself to come up with:</span></p>
<pre> on perform_mail_action(info)
 	tell application "Mail"
 		set NewMail to |SelectedMessages| of info
 		repeat with CurrentMessage in NewMail
 			set NewMessage to reply CurrentMessage
 			set MessageSubject to subject of CurrentMessage as string
 			set MessageContent to content of CurrentMessage as string
 			tell application "http://www34.brinkster.com/4xws/eliza.asmx"
 				set MySubject to call soap {method name:"CHAT", method namespace uri:"http://xws.webservice.net/xws", SOAPAction:"http://xws.webservice.net/xws/CHAT", parameters:{|Say|:MessageSubject}}
 			end tell
 			set subject of NewMessage to "Re: " &amp; MySubject
 			tell application "http://www34.brinkster.com/4xws/eliza.asmx"
 				set MyContent to call soap {method name:"CHAT", method namespace uri:"http://xws.webservice.net/xws", SOAPAction:"http://xws.webservice.net/xws/CHAT", parameters:{|Say|:MessageContent}}
 			end tell
 			set content of NewMessage to MyContent
 			send NewMessage
 		end repeat
 	end tell end perform_mail_action</pre>
<p><span style="font-family: Verdana;">If you have never seen AppleScript before you&#8217;re probably pretty surprised at the syntax.  It is sort of like English and it does understand quite an array of little words for doing things.  Some of them you can leave out.  The only really hairy thing I ran into was that &#8220;Say&#8221; is a reserved word or something so I couldn&#8217;t use it as a parameter at first until I figured out how to quote it with the |Say|.  That&#8217;s really all there is to it.  I&#8217;m not sure there is any language where it is easier without a lot of setup.  This is with no imports, no adding libraries, no installation, really just a little text editor that can dynamically look things up that are already on the system.</span></div>
]]></content:encoded>
			<wfw:commentRss>http://www.javarants.com/2003/10/21/applescript-is-pretty-cool/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
