<?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>A Brundage Web-log &#187; Enterprise Software</title>
	<atom:link href="http://blog.deanandadie.net/category/dean/code/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.deanandadie.net</link>
	<description>Things Adrienne &#38; Dean Do, Think and Write</description>
	<lastBuildDate>Sun, 08 Jan 2012 21:56:28 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Easy Thunderbird Account Management Using MCD</title>
		<link>http://blog.deanandadie.net/2010/06/easy-thunderbird-account-management-using-mcd/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=easy-thunderbird-account-management-using-mcd</link>
		<comments>http://blog.deanandadie.net/2010/06/easy-thunderbird-account-management-using-mcd/#comments</comments>
		<pubDate>Sun, 13 Jun 2010 20:47:33 +0000</pubDate>
		<dc:creator>Dean</dc:creator>
				<category><![CDATA[Enterprise Software]]></category>
		<category><![CDATA[autoconfig]]></category>
		<category><![CDATA[enterprise]]></category>
		<category><![CDATA[mcd]]></category>
		<category><![CDATA[mission control desktop]]></category>
		<category><![CDATA[thunderbird]]></category>

		<guid isPermaLink="false">http://blog.deanandadie.net/?p=1058</guid>
		<description><![CDATA[Continuing my series on Mission Control Desktop, this post covers some enhancements I made for configuring email accounts in Thunderbird.&#160; The mail.* branch is one of the largest group of preferences you can manipulate using autoconfig.&#160; Setting up the right combination of mail.account,&#160; mail.server, mail.identity and mail.smtpserver is just a little tricky. With the exception [...]<h3>You may also like these:</h3><ul>
<li><a href='http://blog.deanandadie.net/2010/05/manufacturing-user-preferences-for-mcd/' rel='bookmark' title='Manufacturing User Preferences For MCD'>Manufacturing User Preferences For MCD</a> <small>Nobody likes boring code Mozilla products like Thunderbird and Firefox...</small></li>
<li><a href='http://blog.deanandadie.net/2010/04/ldap-queries-in-mission-control-desktop/' rel='bookmark' title='LDAP Queries in Mission Control Desktop'>LDAP Queries in Mission Control Desktop</a> <small>Previously, we saw that Mozilla MCD can inspect a user&#8217;s...</small></li>
<li><a href='http://blog.deanandadie.net/2010/04/setting-user-preferences-with-mission-control-desktop/' rel='bookmark' title='Setting User Preferences with Mission Control Desktop'>Setting User Preferences with Mission Control Desktop</a> <small>A challenge with software Managing software for thousands of users...</small></li>
</ul>

Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<div id="attachment_1059" class="wp-caption aligncenter" style="width: 600px"><a href="http://www.flickr.com/photos/myoldpostcards/3879397340/"><img class="size-full wp-image-1059" title="Thunderbird Console" src="http://blog.deanandadie.net/wp-content/uploads/2010/06/3879397340_91ca6ee21b_b.jpg" alt="Ford Thunderbird Console" height="306" width="590"></a><p class="wp-caption-text">From myoldpostcards</p></div>
<p>Continuing <a href="http://blog.deanandadie.net/tag/mission-control-desktop">my series on Mission Control Desktop</a>, this post covers some enhancements I made for configuring email accounts in Thunderbird.&nbsp; The <code>mail.*</code> branch is one of the largest group of preferences you can manipulate using autoconfig.&nbsp; Setting up the right combination of <code>mail.account</code>,&nbsp; <code>mail.server</code>, <code>mail.identity</code> and <code>mail.smtpserver</code> is just a little tricky.</p>
<p>With the exception of the special &#8220;local folders&#8221; account, an email account in Thunderbird has four components: an <em>account</em>, a <em>server</em>, one or more <em>identities</em>, and an <em>smtp server</em>.&nbsp; There are a few preference strings gluing each of these elements together.  Each account you create is differentiated from the others by a <strong>unique label</strong>, defaulting to account&lt;num&gt;, with incrementing numbers. You can also use your own, more meaningful labels, such as <code>mail.account.<strong>work-email</strong></code> and <code>mail.account.<strong>gmail</strong></code>.</p>
<table width="100%">
<tbody>
<tr>
<th>Element</th>
<th>Branch</th>
<th></th>
</tr>
<tr>
<td>Account</td>
<td><code>mail.account.accountN</code></td>
<td>Glues POP/IMAP, SMTP servers and identities together</td>
</tr>
<tr>
<td>Server</td>
<td><code>mail.server.serverN</code></td>
<td>Settings for the IMAP or POP server</td>
</tr>
<tr>
<td>Identity</td>
<td><code>mail.identity.idN</code></td>
<td>Name, email address, drafts &amp; stationery folders</td>
</tr>
<tr>
<td>SMTP Server</td>
<td><code>mail.smtpserver.smtpN</code></td>
<td>Settings for the SMTP server</td>
</tr>
<tr>
<th colspan="3">Glue settings</th>
</tr>
<tr>
<td>Accounts list</td>
<td><code>mail.accountmanager.accounts</code></td>
<td>Comma-separated list of <code>mail.account</code> labels</td>
</tr>
<tr>
<td>Default account</td>
<td><code>mail.accountmanager.defaultaccount</code></td>
<td>The label of the default mail account</td>
</tr>
<tr>
<td>SMTP servers</td>
<td><code>mail.smtpservers</code></td>
<td>Comma-separated list of <code>mail.smtpserver</code> server labels</td>
</tr>
<tr>
<td>Default SMTP</td>
<td><code>mail.smtp.defaultserver</code></td>
<td>The label of the default SMTP server</td>
</tr>
</tbody>
</table>
<p>Here is a quick example:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Identity</span>
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mail.identity.id1.fullName&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;Dean Brundage&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mail.identity.id1.draft_folder&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;imap://dean.brundage@example.com@mail.example.com/Drafts&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mail.identity.id1.smtpServer&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;smtp1&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// IMAP server settings</span>
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mail.server.server1.type&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;imap&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mail.server.server1.hostname&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;mail.example.com&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">// etc</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// SMTP server settings</span>
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mail.smtpserver.smtp1.auth_method&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mail.smtpserver.smtp1.hostname&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;smtp.example.com&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">// etc</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Glue it all together</span>
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mail.account.account1.identities&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;id1&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mail.account.account1.server&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;server1&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mail.accountmanager.accounts&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;account1&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mail.accountmanager.defaultaccount&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;account1&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mail.smtp.defaultserver&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;smtp1&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mail.smtpservers&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;smtp1&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>As you add more email accounts the code can get unmanageable when you try to remember to twiddle the right branches so all the accounts, their identities and smtp servers show up.  I would like to present an alternative.</p>
<p>This code builds upon the <code>PreferenceFactory</code> prototype <a href="http://blog.deanandadie.net/2010/05/manufacturing-user-preferences-for-mcd/">covered earlier</a>.&nbsp; I put together an object prototype for an account, containing a server, one or more identities, and an smtp server.&nbsp; There is also a singleton for the account manager.&nbsp; Now you can instantiate an object and call preference setters on it.&nbsp; The code is more readable and less error prone.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">   <span style="color: #006600; font-style: italic;">// Create an email account</span>
   <span style="color: #003366; font-weight: bold;">var</span> workAccount <span style="color: #339933;">=</span> AccountManager.<span style="color: #660066;">newAccount</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> isDefault<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span>
                                                 label<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;work&quot;</span><span style="color: #339933;">,</span>
                                                 type<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;imap&quot;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #006600; font-style: italic;">// Lock Preferences on the IMAP server</span>
   workAccount.<span style="color: #660066;">server</span>.<span style="color: #660066;">setPrefs</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> hostname<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;mail.example.com&quot;</span><span style="color: #339933;">,</span>
                                 type<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;imap&quot;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;lock&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #006600; font-style: italic;">// Default Preferences</span>
   workAccount.<span style="color: #660066;">server</span>.<span style="color: #660066;">setPrefs</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> check_new_mail<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span>
                                 <span style="color: #000066;">name</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Corporate eMail&quot;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// Lock Preferences on the SMTP server</span>
  workAccount.<span style="color: #660066;">smtpServer</span>.<span style="color: #660066;">setPrefs</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> auth_method<span style="color: #339933;">:</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">,</span>    <span style="color: #006600; font-style: italic;">/* User/pass */</span>
                                    username<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;dean.brundage@example.com&quot;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;lock&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #006600; font-style: italic;">// Default Preferences</span>
  workAccount.<span style="color: #660066;">smtpServer</span>.<span style="color: #660066;">setPrefs</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> description<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Corporate SMTP server&quot;</span><span style="color: #339933;">,</span>
                                     hostname<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;mail.example.com&quot;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// And now a personal account</span>
  <span style="color: #003366; font-weight: bold;">var</span> myGmailAccount <span style="color: #339933;">=</span> AccountManager.<span style="color: #660066;">newAccount</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> label<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;gmail&quot;</span><span style="color: #339933;">,</span> type<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;imap&quot;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #006600; font-style: italic;">// Go about setting preferences on myGmailAccount as before</span></pre></div></div>

<h1><a href="http://blog.deanandadie.net/wp-content/uploads/2010/06/thunderbird_accounts.js.txt">Download the source</a></h1>
<p>That block of code replaces the tedious series of <code>defaultPref</code> and <code>lockPref</code> required to set up an email account.&nbsp; It produces preference settings like these:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mail.accountmanager.accounts&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;work-account1,gmail-account2&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mail.accountmanager.defaultaccount&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;work-account1&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mail.account.work-account1.identities&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;work-id1&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mail.account.work-account1.server&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;work-server1&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
lockPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mail.server.work-server1.type&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;imap&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mail.server.gmail-server2.type&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;imap&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">// etc</span>
&nbsp;
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mail.smtp.defaultserver&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;work-smtp1&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mail.smtpservers&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;work-smtp1&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h1><a href="http://blog.deanandadie.net/wp-content/uploads/2010/06/thunderbird_accounts.js.txt">Download the source</a></h1>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">/**
   By Dean Brundage
   Originally published here:
     http://blog.deanandadie.net/2010/06/easy-thunderbird-account-management-using-mcd/
*/</span>
&nbsp;
&nbsp;
<span style="color: #006600; font-style: italic;">/* &quot;Inheritance&quot; helper
   http://www.sitepoint.com/blogs/2006/01/17/javascript-inheritance/
   copy all of parent's prototype functions to descendant
*/</span>
<span style="color: #003366; font-weight: bold;">function</span> copyPrototype<span style="color: #009900;">&#40;</span>parent<span style="color: #339933;">,</span> descendant<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #003366; font-weight: bold;">var</span> sConstructor <span style="color: #339933;">=</span> parent.<span style="color: #660066;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
   <span style="color: #003366; font-weight: bold;">var</span> aMatch <span style="color: #339933;">=</span> sConstructor.<span style="color: #660066;">match</span><span style="color: #009900;">&#40;</span> <span style="color: #009966; font-style: italic;">/\s*function (.*)\(/</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> 
   <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> aMatch <span style="color: #339933;">!=</span> <span style="color: #003366; font-weight: bold;">null</span> <span style="color: #009900;">&#41;</span>
   <span style="color: #009900;">&#123;</span>  descendant.<span style="color: #660066;">prototype</span><span style="color: #009900;">&#91;</span>aMatch<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> parent<span style="color: #339933;">;</span>  <span style="color: #009900;">&#125;</span> 
   <span style="color: #000066; font-weight: bold;">for</span> <span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">var</span> m <span style="color: #000066; font-weight: bold;">in</span> parent.<span style="color: #660066;">prototype</span><span style="color: #009900;">&#41;</span>
   <span style="color: #009900;">&#123;</span>  descendant.<span style="color: #660066;">prototype</span><span style="color: #009900;">&#91;</span>m<span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> parent.<span style="color: #660066;">prototype</span><span style="color: #009900;">&#91;</span>m<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>  <span style="color: #009900;">&#125;</span> 
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
<span style="color: #006600; font-style: italic;">/* &quot;Base&quot; for the Mail.xxxx objects
&nbsp;
   This requires the PreferenceFactory prototype covered in a previous post:
     http://blog.deanandadie.net/2010/05/manufacturing-user-preferences-for-mcd/
*/</span>
<span style="color: #003366; font-weight: bold;">function</span> Mail<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">PreferenceFactory</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #006600; font-style: italic;">// super</span>
   <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">addPrefBranch</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mail&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
copyPrototype<span style="color: #009900;">&#40;</span> PreferenceFactory<span style="color: #339933;">,</span> Mail <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
Mail.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">joinIds</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>collection<span style="color: #339933;">,</span>separator<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> separator <span style="color: #009900;">&#41;</span>
      separator <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;,&quot;</span><span style="color: #339933;">;</span>
   <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> collection <span style="color: #009900;">&#41;</span>
   <span style="color: #009900;">&#123;</span>  ret <span style="color: #339933;">=</span> collection<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">id</span>
      <span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> collection.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span>
         ret <span style="color: #339933;">=</span> ret <span style="color: #339933;">+</span> separator <span style="color: #339933;">+</span> collection<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">id</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
   <span style="color: #000066; font-weight: bold;">return</span> ret<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
<span style="color: #006600; font-style: italic;">/* A thunderbird email &quot;account&quot; consists of
      Mail.Server -- A mail server (IMAP or POP)
      Mail.SMTPServer -- A SMTP server
      One or more Mail.Identities -- Email address and name
&nbsp;
   A thunderbird local folders &quot;account&quot; has only one Mail.Server, nothing else
      Yup, local folders are &quot;servers&quot;
*/</span>
&nbsp;
<span style="color: #006600; font-style: italic;">/* Object to manage accounts
      I recommend managing mail accounts with the AccountManager unless you
      know what you are doing.
   var myAccount = AccountManager.newAccount();
   myAccount.doStuff();
&nbsp;
*/</span>
<span style="color: #003366; font-weight: bold;">var</span> AccountManager <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Mail<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
AccountManager.<span style="color: #660066;">accounts</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
AccountManager.<span style="color: #660066;">addPrefBranch</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;accountmanager&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">/* Create a new account
   Alerts Thunderbird to the presence of the new account
   See Mail.Account for valid options
*/</span>
AccountManager.<span style="color: #660066;">newAccount</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>opts<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> opts <span style="color: #009900;">&#41;</span>
      opts <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
   acct <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Mail.<span style="color: #660066;">Account</span><span style="color: #009900;">&#40;</span>opts<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> opts.<span style="color: #660066;">isDefault</span> <span style="color: #009900;">&#41;</span>
   <span style="color: #009900;">&#123;</span>  acct.<span style="color: #660066;">useSMTPServer</span><span style="color: #009900;">&#40;</span> <span style="color: #003366; font-weight: bold;">new</span> Mail.<span style="color: #660066;">SMTPServer</span><span style="color: #009900;">&#40;</span>opts<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">setDefaultAccount</span><span style="color: #009900;">&#40;</span>acct<span style="color: #339933;">,</span>opts.<span style="color: #660066;">lockLevel</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span>
   <span style="color: #009900;">&#123;</span>  acct.<span style="color: #660066;">useSMTPServer</span><span style="color: #009900;">&#40;</span> Mail.<span style="color: #660066;">SMTPServer</span>.<span style="color: #660066;">defaultServer</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
&nbsp;
   <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">accounts</span>.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>acct<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">setPref</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&quot;accounts&quot;</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">joinIds</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">accounts</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #000066; font-weight: bold;">return</span> acct<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
AccountManager.<span style="color: #660066;">setDefaultAccount</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>account<span style="color: #339933;">,</span>lockLevel<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  
   <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">setPref</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;defaultaccount&quot;</span><span style="color: #339933;">,</span> account.<span style="color: #660066;">id</span><span style="color: #339933;">,</span> lockLevel <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #006600; font-style: italic;">/* It's possible to create an account before setting the default
      SMTP server.  Clean them up if this new account is the default
      (Expect Mail.Account to inform Mail.SMTPServer of the new default)
   */</span>
   <span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">accounts</span>.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span>
      <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">accounts</span><span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">useSMTPServer</span><span style="color: #009900;">&#40;</span>Mail.<span style="color: #660066;">SMTPServer</span>.<span style="color: #660066;">defaultServer</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
AccountManager.<span style="color: #660066;">setLocalFolders</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>folders<span style="color: #339933;">,</span>lockLevel<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">setPref</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;localfoldersserver&quot;</span><span style="color: #339933;">,</span> folders.<span style="color: #660066;">id</span><span style="color: #339933;">,</span> lockLevel<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
<span style="color: #006600; font-style: italic;">/* Creates a new generic mail account (identity, server, smtp)
   Arguments
     opts: A hash of options. Valid options are:
           &quot;isDefault&quot;: true | false (default false)
           &quot;label&quot;: string - A unique label for this account, server &amp; identity
           &quot;lockLevel&quot;: &quot;default&quot; | &quot;lock&quot; | &quot;pref&quot; (default &quot;default&quot;)
           &quot;type&quot;: imap | pop | localFolder
&nbsp;
   This prototype creates an object representing an email account
   It exposes some objects:
      myAccount.directoryServer  // The (optional) LDAP2Server object
      myAccount.identities       // An array of identites
      myAccount.server           // The IMAP/POP/LocalFolder Mail.Server object
      myAccount.smtpServer       // The Mail.SMTPServer object
&nbsp;
   (The LDAP2Server object is detailed in a separate post on http://blog.deanandadie.net/)
*/</span>
Mail.<span style="color: #660066;">Account</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>opts<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> opts <span style="color: #009900;">&#41;</span>
     opts <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> opts.<span style="color: #660066;">type</span> <span style="color: #009900;">&#41;</span>
      <span style="color: #000066; font-weight: bold;">throw</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;What's my type?&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">Mail</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #006600; font-style: italic;">// &quot;super&quot;</span>
&nbsp;
   <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">id</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;account&quot;</span> <span style="color: #339933;">+</span> <span style="color: #339933;">++</span>Mail.<span style="color: #660066;">Account</span>.<span style="color: #660066;">count</span><span style="color: #339933;">;</span>
   <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> opts.<span style="color: #660066;">label</span> <span style="color: #009900;">&#41;</span>
   <span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">id</span> <span style="color: #339933;">=</span> opts.<span style="color: #660066;">label</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;-&quot;</span> <span style="color: #339933;">+</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">id</span><span style="color: #339933;">;</span>  <span style="color: #009900;">&#125;</span>
&nbsp;
   <span style="color: #006600; font-style: italic;">// Our preference branch is mail.account.accountN</span>
   <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">addPrefBranch</span><span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#91;</span> <span style="color: #3366CC;">&quot;account&quot;</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">id</span> <span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">identities</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">server</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Mail.<span style="color: #660066;">Server</span><span style="color: #009900;">&#40;</span>opts<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #006600; font-style: italic;">// Need this either way</span>
&nbsp;
   <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> opts.<span style="color: #660066;">type</span>.<span style="color: #660066;">match</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/^^imap$|^pop$/i</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>
   <span style="color: #009900;">&#123;</span>
      <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">server</span>.<span style="color: #660066;">setPref</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;type&quot;</span><span style="color: #339933;">,</span> opts.<span style="color: #660066;">type</span><span style="color: #339933;">,</span> opts.<span style="color: #660066;">lockLevel</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #006600; font-style: italic;">// Important that addIdentity be before the SMTP server is set up</span>
      <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">addIdentity</span><span style="color: #009900;">&#40;</span> <span style="color: #003366; font-weight: bold;">new</span> Mail.<span style="color: #660066;">Identity</span><span style="color: #009900;">&#40;</span>opts<span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> opts.<span style="color: #660066;">lockLevel</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> opts.<span style="color: #660066;">type</span>.<span style="color: #660066;">match</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/^localFolders?$/i</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>
   <span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">folders</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">server</span><span style="color: #339933;">;</span>
      AccountManager.<span style="color: #660066;">setLocalFolders</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">folders</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">folders</span>.<span style="color: #660066;">setPref</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;type&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;none&quot;</span><span style="color: #339933;">,</span> opts.<span style="color: #660066;">lockLevel</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span>
   <span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">throw</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;unrecognized Mail.Account type: &quot;</span> <span style="color: #339933;">+</span> opts.<span style="color: #660066;">type</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #009900;">&#125;</span>
&nbsp;
   <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">useServer</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">server</span><span style="color: #339933;">,</span> opts.<span style="color: #660066;">lockLevel</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span>
&nbsp;
copyPrototype<span style="color: #009900;">&#40;</span> Mail<span style="color: #339933;">,</span> Mail.<span style="color: #660066;">Account</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
Mail.<span style="color: #660066;">Account</span>.<span style="color: #660066;">count</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>                                   <span style="color: #006600; font-style: italic;">// Fake class variable</span>
&nbsp;
&nbsp;
<span style="color: #006600; font-style: italic;">// Expects a Mail.Identity object and, optionally, the preference locking level</span>
Mail.<span style="color: #660066;">Account</span>.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">addIdentity</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>identity<span style="color: #339933;">,</span>lockLevel<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> identity <span style="color: #009900;">&#41;</span>
   <span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">identities</span>.<span style="color: #660066;">contains</span><span style="color: #009900;">&#40;</span>identity<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">identities</span>.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>identity<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
         <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">setPref</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;identities&quot;</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">joinIds</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">identities</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> lockLevel <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
   <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
<span style="color: #006600; font-style: italic;">/* Helper to set the SMTP server
   Expects a Mail.SMTPServer object &amp; optionally, an options hash
   Valid options:
     lockLevel: lock | default | pref
     force: true | false
*/</span>
Mail.<span style="color: #660066;">Account</span>.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">useDirectory</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>directory<span style="color: #339933;">,</span> opts<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> opts <span style="color: #009900;">&#41;</span>
      opts <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
   <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> directory <span style="color: #009900;">&#41;</span>
   <span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> opts.<span style="color: #660066;">force</span> <span style="color: #339933;">||</span> <span style="color: #000066; font-weight: bold;">typeof</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">directoryServer</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #3366CC;">&quot;undefined&quot;</span> <span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">directoryServer</span> <span style="color: #339933;">=</span> directory<span style="color: #339933;">;</span>
         <span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">identities</span>.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span>
            <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">identities</span><span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">useDirectory</span><span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">directoryServer</span><span style="color: #339933;">,</span> opts <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
   <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">/* Helper to set the SMTP server
   Expects a Mail.SMTPServer object &amp; optionally, an options hash
   Valid options:
     lockLevel: lock | default | pref
     force: true | false
*/</span>
Mail.<span style="color: #660066;">Account</span>.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">useSMTPServer</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>smtp<span style="color: #339933;">,</span>opts<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> opts <span style="color: #009900;">&#41;</span>
      opts <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
   <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> smtp <span style="color: #009900;">&#41;</span>
   <span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> opts.<span style="color: #660066;">force</span> <span style="color: #339933;">||</span> <span style="color: #000066; font-weight: bold;">typeof</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">smtpServer</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #3366CC;">&quot;undefined&quot;</span> <span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">smtpServer</span> <span style="color: #339933;">=</span> smtp<span style="color: #339933;">;</span>
         <span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">identities</span>.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span>
            <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">identities</span><span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span>.<span style="color: #660066;">useSMTPServer</span><span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">smtpServer</span><span style="color: #339933;">,</span> opts <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
   <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
<span style="color: #006600; font-style: italic;">// Expects a Mail.Server object and, optionally, the preference locking level</span>
Mail.<span style="color: #660066;">Account</span>.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">useServer</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>server<span style="color: #339933;">,</span>lockLevel<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> server <span style="color: #009900;">&#41;</span>
      <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">setPref</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;server&quot;</span><span style="color: #339933;">,</span> server.<span style="color: #660066;">id</span><span style="color: #339933;">,</span> lockLevel <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
<span style="color: #006600; font-style: italic;">/* Creates a new generic mail server
   Arguments
     opts: A hash of options. Valid options are:
           label: string - A unique label for this account, server &amp; identity
*/</span>
Mail.<span style="color: #660066;">Server</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>opts<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> opts <span style="color: #009900;">&#41;</span>
     opts <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">Mail</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">id</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;server&quot;</span> <span style="color: #339933;">+</span> <span style="color: #339933;">++</span>Mail.<span style="color: #660066;">Server</span>.<span style="color: #660066;">count</span><span style="color: #339933;">;</span>
   <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> opts.<span style="color: #660066;">label</span> <span style="color: #009900;">&#41;</span>
   <span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">id</span> <span style="color: #339933;">=</span> opts.<span style="color: #660066;">label</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;-&quot;</span> <span style="color: #339933;">+</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">id</span><span style="color: #339933;">;</span>  <span style="color: #009900;">&#125;</span>
&nbsp;
   <span style="color: #006600; font-style: italic;">// Our preference branch is mail.server.serverN</span>
   <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">addPrefBranch</span><span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#91;</span> <span style="color: #3366CC;">&quot;server&quot;</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">id</span> <span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
copyPrototype<span style="color: #009900;">&#40;</span> Mail<span style="color: #339933;">,</span> Mail.<span style="color: #660066;">Server</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
Mail.<span style="color: #660066;">Server</span>.<span style="color: #660066;">count</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>  <span style="color: #006600; font-style: italic;">// Fake class variable</span>
&nbsp;
&nbsp;
<span style="color: #006600; font-style: italic;">/* Creates a new mail identity. (name, email address, etc)
   Arguments
     opts: A hash of options. Valid options are:
           &quot;label&quot;: string - A unique label for this account, server &amp; identity
*/</span>
Mail.<span style="color: #660066;">Identity</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>opts<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> opts <span style="color: #009900;">&#41;</span>
     opts <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">Mail</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">id</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;id&quot;</span> <span style="color: #339933;">+</span> <span style="color: #339933;">++</span>Mail.<span style="color: #660066;">Identity</span>.<span style="color: #660066;">count</span><span style="color: #339933;">;</span>
   <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> opts.<span style="color: #660066;">label</span> <span style="color: #009900;">&#41;</span>
   <span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">id</span> <span style="color: #339933;">=</span> opts.<span style="color: #660066;">label</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;-&quot;</span> <span style="color: #339933;">+</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">id</span><span style="color: #339933;">;</span>  <span style="color: #009900;">&#125;</span>
&nbsp;
   <span style="color: #006600; font-style: italic;">// Our preference branch is mail.identity.idN</span>
   <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">addPrefBranch</span><span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#91;</span> <span style="color: #3366CC;">&quot;identity&quot;</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">id</span> <span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">hasSMTPServer</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
copyPrototype<span style="color: #009900;">&#40;</span>Mail<span style="color: #339933;">,</span> Mail.<span style="color: #660066;">Identity</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
Mail.<span style="color: #660066;">Identity</span>.<span style="color: #660066;">count</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>  <span style="color: #006600; font-style: italic;">// Fake class variable</span>
&nbsp;
&nbsp;
<span style="color: #006600; font-style: italic;">/* Expects a LDAP2Server object and a hash of options
   Valid options:
      lockLevel: lock | default | pref
*/</span>
Mail.<span style="color: #660066;">Identity</span>.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">useDirectory</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>ldap2Server<span style="color: #339933;">,</span>opts<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> opts <span style="color: #009900;">&#41;</span>
      opts <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> ldap2Server <span style="color: #009900;">&#41;</span>
   <span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">setPref</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;directoryServer&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;ldap_2.servers.&quot;</span> <span style="color: #339933;">+</span> ldap2Server.<span style="color: #660066;">id</span><span style="color: #339933;">,</span> opts.<span style="color: #660066;">lockLevel</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">setPref</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;overrideGlobal_Pref&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span> opts.<span style="color: #660066;">lockLevel</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
<span style="color: #006600; font-style: italic;">/* Expects a SMTPServer object and a hash of options
   Valid options:
      force: true | false
      lockLevel: lock | default | pref
*/</span>
Mail.<span style="color: #660066;">Identity</span>.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">useSMTPServer</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>smtpServer<span style="color: #339933;">,</span>opts<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> opts <span style="color: #009900;">&#41;</span>
      opts <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span>
   <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> smtpServer <span style="color: #009900;">&#41;</span>
   <span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> opts.<span style="color: #660066;">force</span> <span style="color: #339933;">||</span> <span style="color: #339933;">!</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">hasSMTPServer</span> <span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">setPref</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;smtpServer&quot;</span><span style="color: #339933;">,</span> smtpServer.<span style="color: #660066;">id</span><span style="color: #339933;">,</span> opts.<span style="color: #660066;">lockLevel</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
         <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">hasSMTPServer</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
   <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
<span style="color: #006600; font-style: italic;">/* Creates a new smtp server
   Artuments:
     opts: A hash of options. Valid options are:
       isDefault: true | false (default)
       label: A unique label for this smtp server
   Throws an error if there is already a default smtp server
*/</span>
Mail.<span style="color: #660066;">SMTPServer</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>opts<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> opts <span style="color: #009900;">&#41;</span>
     opts <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">Mail</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">id</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;smtp&quot;</span> <span style="color: #339933;">+</span> <span style="color: #339933;">++</span>Mail.<span style="color: #660066;">SMTPServer</span>.<span style="color: #660066;">count</span><span style="color: #339933;">;</span>
   <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> opts.<span style="color: #660066;">label</span> <span style="color: #009900;">&#41;</span>
   <span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">id</span> <span style="color: #339933;">=</span> opts.<span style="color: #660066;">label</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;-&quot;</span> <span style="color: #339933;">+</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">id</span><span style="color: #339933;">;</span>  <span style="color: #009900;">&#125;</span>
&nbsp;
   <span style="color: #006600; font-style: italic;">// Our perference branch is mail.smtpserver.smtpN</span>
   <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">addPrefBranch</span><span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#91;</span> <span style="color: #3366CC;">&quot;smtpserver&quot;</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">id</span> <span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> opts.<span style="color: #660066;">isDefault</span> <span style="color: #339933;">&amp;&amp;</span> Mail.<span style="color: #660066;">SMTPServer</span>.<span style="color: #660066;">defaultServer</span> <span style="color: #009900;">&#41;</span>
      <span style="color: #000066; font-weight: bold;">throw</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Default smtp server already configured to &quot;</span> <span style="color: #339933;">+</span> Mail.<span style="color: #660066;">SMTPServer</span>.<span style="color: #660066;">defaultServer</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> opts.<span style="color: #660066;">isDefault</span> <span style="color: #009900;">&#41;</span>
      <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">setDefault</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #006600; font-style: italic;">// Register this SMTP server</span>
   <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> Mail.<span style="color: #660066;">SMTPServer</span>.<span style="color: #660066;">servers</span>.<span style="color: #660066;">contains</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>
      Mail.<span style="color: #660066;">SMTPServer</span>.<span style="color: #660066;">servers</span>.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #006600; font-style: italic;">// Update mail.smtpservers to include the new one</span>
   defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mail.smtpservers&quot;</span><span style="color: #339933;">,</span>  <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">joinIds</span><span style="color: #009900;">&#40;</span>Mail.<span style="color: #660066;">SMTPServer</span>.<span style="color: #660066;">servers</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
copyPrototype<span style="color: #009900;">&#40;</span>Mail<span style="color: #339933;">,</span> Mail.<span style="color: #660066;">SMTPServer</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Some &quot;class&quot; variables</span>
Mail.<span style="color: #660066;">SMTPServer</span>.<span style="color: #660066;">count</span> <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
Mail.<span style="color: #660066;">SMTPServer</span>.<span style="color: #660066;">defaultServer</span> <span style="color: #339933;">=</span> undefined<span style="color: #339933;">;</span>
Mail.<span style="color: #660066;">SMTPServer</span>.<span style="color: #660066;">servers</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
Mail.<span style="color: #660066;">SMTPServer</span>.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">setDefault</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  Mail.<span style="color: #660066;">SMTPServer</span>.<span style="color: #660066;">defaultServer</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">;</span>
   defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mail.smtp.defaultserver&quot;</span><span style="color: #339933;">,</span> Mail.<span style="color: #660066;">SMTPServer</span>.<span style="color: #660066;">defaultServer</span>.<span style="color: #660066;">id</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h3>You may also like these:</h3><ul>
<li><a href='http://blog.deanandadie.net/2010/05/manufacturing-user-preferences-for-mcd/' rel='bookmark' title='Manufacturing User Preferences For MCD'>Manufacturing User Preferences For MCD</a> <small>Nobody likes boring code Mozilla products like Thunderbird and Firefox...</small></li>
<li><a href='http://blog.deanandadie.net/2010/04/ldap-queries-in-mission-control-desktop/' rel='bookmark' title='LDAP Queries in Mission Control Desktop'>LDAP Queries in Mission Control Desktop</a> <small>Previously, we saw that Mozilla MCD can inspect a user&#8217;s...</small></li>
<li><a href='http://blog.deanandadie.net/2010/04/setting-user-preferences-with-mission-control-desktop/' rel='bookmark' title='Setting User Preferences with Mission Control Desktop'>Setting User Preferences with Mission Control Desktop</a> <small>A challenge with software Managing software for thousands of users...</small></li>
</ul>
<p>Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.deanandadie.net/2010/06/easy-thunderbird-account-management-using-mcd/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Quick diff of Solaris patch levels</title>
		<link>http://blog.deanandadie.net/2010/06/quick-diff-of-solaris-patch-levels/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=quick-diff-of-solaris-patch-levels</link>
		<comments>http://blog.deanandadie.net/2010/06/quick-diff-of-solaris-patch-levels/#comments</comments>
		<pubDate>Wed, 02 Jun 2010 17:36:08 +0000</pubDate>
		<dc:creator>Dean</dc:creator>
				<category><![CDATA[Enterprise Software]]></category>
		<category><![CDATA[diff]]></category>
		<category><![CDATA[patch]]></category>
		<category><![CDATA[showrev]]></category>
		<category><![CDATA[solaris]]></category>
		<category><![CDATA[system administration]]></category>
		<category><![CDATA[troubleshooting]]></category>

		<guid isPermaLink="false">http://blog.deanandadie.net/?p=1038</guid>
		<description><![CDATA[Suppose you have two Solaris machines and you want to bring them to the same patch level.  Or you are troubleshooting issues on two machines that are supposed to be identical.  I wrote a perl script that compares patch levels on two machines. It shows something like this: malfunction % patch_diff sr-host-01 sr-host-02 &#160; Patches [...]
No related posts.

Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>Suppose you have two Solaris machines and you want to bring them to the same patch level.  Or you are troubleshooting issues on two machines that are supposed to be identical.  I wrote a perl script that compares patch levels on two machines.</p>
<p>It shows something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="bourne" style="font-family:monospace;">malfunction % patch_diff sr-host-01 sr-host-02
&nbsp;
Patches on each system that are missing from the other.
                        sr-host-01  |  sr-host-02
          Wed Jun  2 11:40:40 2010  |  Wed Jun  2 11:40:59 2010
------------------------------------+-------------------------------------
                         118814-01  |  123252-01
                         118959-03  |  127752-01
                         119090-31  |  137110-01
                                    |  142430-01
                                    |  142436-01
&nbsp;
Patches on each system that are downrev on the other.
                        sr-host-01  |  sr-host-02
          Wed Jun  2 11:40:40 2010  |  Wed Jun  2 11:40:59 2010
------------------------------------+-------------------------------------
                         137147-04  |  137147-05
                         137000-03  |  137000-06
                         125952-18  |  125952-19</pre></div></div>

<p><a href="http://blog.deanandadie.net/wp-content/uploads/2010/06/patch_diff.txt">Download patch_diff</a></p>
<p>First it shows all the patches <code>sr-host-01</code> has that <code>sr-host-02</code> does not have and vice-versa.  In this simplified case <code>sr-host-01</code> has 3 patches <code>sr-host-02</code> does not have and <code>sr-host-02</code> has 5 patches <code>sr-host-01</code> does not have.  It also compares patch revisions and shows the different levels on each host.  The machines share 3 patches that are at different revision levels.</p>
<p>To use <code>patch_diff</code> you must first generate a patch list on each machine.</p>

<div class="wp_syntax"><div class="code"><pre class="bourne" style="font-family:monospace;">0 sr-host-01 % patch_diff -g</pre></div></div>

<p>This makes a directory with a NDBM file containing the patches on <code>sr-host-01</code>.  Do the same for <code>sr-host-02</code> and bring the NDBM files together. (It helps if your home directory is shared between the machines.)</p>

<div class="wp_syntax"><div class="code"><pre class="bourne" style="font-family:monospace;">0 malfunction % ls patch_diff
sr-host-01.dir  sr-host-02.dir
sr-host-01.pag  sr-host-02.pag</pre></div></div>

<p><a href="http://blog.deanandadie.net/wp-content/uploads/2010/06/patch_diff.txt">Download patch_diff</a></p>
<p>No related posts.</p>
<p>Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.deanandadie.net/2010/06/quick-diff-of-solaris-patch-levels/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Manufacturing User Preferences For MCD</title>
		<link>http://blog.deanandadie.net/2010/05/manufacturing-user-preferences-for-mcd/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=manufacturing-user-preferences-for-mcd</link>
		<comments>http://blog.deanandadie.net/2010/05/manufacturing-user-preferences-for-mcd/#comments</comments>
		<pubDate>Mon, 10 May 2010 01:02:02 +0000</pubDate>
		<dc:creator>Dean</dc:creator>
				<category><![CDATA[Enterprise Software]]></category>
		<category><![CDATA[autoconfig]]></category>
		<category><![CDATA[enterprise]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mission control desktop]]></category>
		<category><![CDATA[preferences]]></category>
		<category><![CDATA[thunderbird]]></category>

		<guid isPermaLink="false">http://blog.deanandadie.net/?p=964</guid>
		<description><![CDATA[Nobody likes boring code Mozilla products like Thunderbird and Firefox represent setting choices in a textual &#8220;tree&#8221; system. (Read the intro.)&#160; Preferences that begin with print. live on the tree branch dealing with printing while those that begin with app.update. are on the auto-update system&#8217;s branch.&#160; An easy concept to grasp. In practice, however, the [...]<h3>You may also like these:</h3><ul>
<li><a href='http://blog.deanandadie.net/2010/04/setting-user-preferences-with-mission-control-desktop/' rel='bookmark' title='Setting User Preferences with Mission Control Desktop'>Setting User Preferences with Mission Control Desktop</a> <small>A challenge with software Managing software for thousands of users...</small></li>
<li><a href='http://blog.deanandadie.net/2010/06/easy-thunderbird-account-management-using-mcd/' rel='bookmark' title='Easy Thunderbird Account Management Using MCD'>Easy Thunderbird Account Management Using MCD</a> <small>Continuing my series on Mission Control Desktop, this post covers...</small></li>
<li><a href='http://blog.deanandadie.net/2010/05/reading-local-files-with-javascript/' rel='bookmark' title='Reading Local Files With Javascript'>Reading Local Files With Javascript</a> <small>Security Conscious Javascript Normally, javascript does not have access to...</small></li>
</ul>

Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<div id="attachment_965" class="wp-caption aligncenter" style="width: 600px"><a href="http://www.flickr.com/photos/vissago/4161281805/"><img class="size-full wp-image-965" title="Bottling Line" src="http://blog.deanandadie.net/wp-content/uploads/2010/05/4161281805_b8dcd6c3d0_b.jpg" alt="Bottling Line" height="392" width="590"></a><p class="wp-caption-text">From vissago</p></div>
<h1>Nobody likes boring code</h1>
<p>Mozilla products like Thunderbird and Firefox represent setting choices in a textual &#8220;tree&#8221; system. (<a href="http://blog.deanandadie.net/2010/04/an-introduction-to-mission-control-desktop/">Read the intro</a>.)&nbsp; Preferences that begin with <em>print.</em> live on the tree branch dealing with printing while those that begin with <em>app.update.</em> are on the auto-update system&#8217;s branch.&nbsp; An easy concept to grasp.  In practice, however, the simplicity will easily become a drone of <em>defalutPref(&#8220;app.update.auto&#8221;, false);</em> if you are not careful.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// This is a boring autoconfig script</span>
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;browser.dom.window.dump.enabled&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;browser.download.manager.retention&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;browser.download.manager.showAlertOnComplete&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;browser.download.manager.showWhenStarting&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;browser.download.save_converter_index&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;browser.feeds.handler&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;reader&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;browser.feeds.handler.default&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;web&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;browser.feeds.showFirstRunUI&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;browser.history_expire_days.mirror&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">180</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">// and so on....</span></pre></div></div>

<h1>Working at The Preference Factory</h1>
<p>Instead of hand-cranking preferences I developed an object prototype to mechanize large blocks of related settings.&nbsp; The resulting code is more readable and easier to maintain when it looks something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Some hypothetical printing preferences</span>
<span style="color: #003366; font-weight: bold;">var</span> printPrefs <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> PreferenceFactory<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;print&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Lock out printing background or in color and don't allow font download</span>
printPrefs.<span style="color: #660066;">setPrefs</span><span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#123;</span> print_bgcolor<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span>
                       print_bgimages<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span>
                       print_downoadfonts<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span>
                       print_in_color<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;lock&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Make some sensible defaults</span>
printPrefs.<span style="color: #660066;">setPrefs</span><span style="color: #009900;">&#40;</span> <span style="color: #009900;">&#123;</span> print_orientation<span style="color: #339933;">:</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span>  <span style="color: #006600; font-style: italic;">// Letter</span>
                       print_to_file<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span> <span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Whitespace focuses your attention on the block and the object eliminates monotonous pref-branch statement repetition.  For the experienced programmer this approach is the familiar object-oriented one of sending messages to receivers.  One goal behind this prototype was to help create elegant code, which can be difficult to do in javascript.  There is another purpose to <code>PreferenceFactory</code> which I will cover in a later post.</p>
<h1>The Bottling Line</h1>
<p>The heart of <code>PreferenceFactory</code> is a wrapper around the autoconfig API.&nbsp; It performs <code>lockPref()</code>, <code>defaultPref()</code>, <code>pref()</code> and <code>getPref()</code> on a branch of the preference tree that you specify when creating the object.  Here is the engine driving the factory:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span> PreferenceFactory<span style="color: #009900;">&#40;</span>arg<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">prefNodes</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>   <span style="color: #006600; font-style: italic;">// Nodes in the preference tree</span>
   <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">prefBranch</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #339933;">;</span>  <span style="color: #006600; font-style: italic;">// String representation of the branch</span>
   <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>arg<span style="color: #009900;">&#41;</span>
      <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">addPrefBranch</span><span style="color: #009900;">&#40;</span>arg<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>   <span style="color: #006600; font-style: italic;">// Add nodes to the tree and update the string representation</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">/* Preference setting helper function
   myServer.setPref(&quot;type&quot;, &quot;imap&quot;, &quot;lock&quot;);
   Arguments
     key: The preference string to set
     value: Value to assign to key
     lockLevel: Locking level.
            Valid values are &quot;default&quot;, &quot;lock&quot; and &quot;pref&quot;
            Default level is &quot;defulat&quot;
*/</span>
PreferenceFactory.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">setPref</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>key<span style="color: #339933;">,</span>value<span style="color: #339933;">,</span>lockLevel<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> lockLevel <span style="color: #009900;">&#41;</span>
   <span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">switch</span><span style="color: #009900;">&#40;</span> lockLevel.<span style="color: #660066;">toLowerCase</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">&quot;default&quot;</span><span style="color: #339933;">:</span>
            <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">defaultPref</span><span style="color: #009900;">&#40;</span>key<span style="color: #339933;">,</span>value<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
         <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">&quot;lock&quot;</span><span style="color: #339933;">:</span>
            <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">lockPref</span><span style="color: #009900;">&#40;</span>key<span style="color: #339933;">,</span>value<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
         <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">&quot;pref&quot;</span><span style="color: #339933;">:</span>
            <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">pref</span><span style="color: #009900;">&#40;</span>key<span style="color: #339933;">,</span>value<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
         <span style="color: #003366; font-weight: bold;">default</span><span style="color: #339933;">:</span>
            <span style="color: #000066; font-weight: bold;">throw</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Unrecognized locking level: &quot;</span> <span style="color: #339933;">+</span> lockLevel <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
   <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span>
   <span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">defaultPref</span><span style="color: #009900;">&#40;</span>key<span style="color: #339933;">,</span>value<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
PreferenceFactory.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">defaultPref</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>key<span style="color: #339933;">,</span>value<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> key <span style="color: #009900;">&#41;</span>
      defaultPref<span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">prefBranch</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;.&quot;</span> <span style="color: #339933;">+</span> key<span style="color: #339933;">,</span> value <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
PreferenceFactory.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">getPref</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>key<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> key <span style="color: #009900;">&#41;</span>
      getPref<span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">prefBranch</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;.&quot;</span> <span style="color: #339933;">+</span> key <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
PreferenceFactory.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">lockPref</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>key<span style="color: #339933;">,</span>value<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> key <span style="color: #009900;">&#41;</span>
      lockPref<span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">prefBranch</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;.&quot;</span> <span style="color: #339933;">+</span> key<span style="color: #339933;">,</span> value <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
PreferenceFactory.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">pref</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>key<span style="color: #339933;">,</span>value<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> key <span style="color: #009900;">&#41;</span>
      pref<span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">prefBranch</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;.&quot;</span> <span style="color: #339933;">+</span> key<span style="color: #339933;">,</span> value <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>The <em>&#8220;hypothetical print&#8221;</em> code example gets its readability from a final function to set multiple preferences.&nbsp; It uses a function I copied from JsUnit called <a href="http://github.com/pivotal/jsunit/blob/master/app/jsUnitCore.js"><code>trueTypeOf()</code></a>.&nbsp; Its function is much like javascript&#8217;s <code>typeof</code>, but handles more than just the built-in data types.&nbsp; <code>setPrefs()</code> accepts an array or &#8220;hash&#8221; and iterates over its elements, calling the above <code>setPref()</code> on each 2-tuple.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">/* Sets multiple preferences
   Accepts an array or object &quot;hash&quot; and an optional locking level
*/</span>
PreferenceFactory.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">setPrefs</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>prefs<span style="color: #339933;">,</span>lockLevel<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">switch</span><span style="color: #009900;">&#40;</span> trueTypeOf<span style="color: #009900;">&#40;</span>prefs<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>
   <span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">&quot;Object&quot;</span><span style="color: #339933;">:</span>
         <span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span> thing <span style="color: #000066; font-weight: bold;">in</span> prefs <span style="color: #009900;">&#41;</span>
         <span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">setPref</span><span style="color: #009900;">&#40;</span>thing<span style="color: #339933;">,</span> prefs<span style="color: #009900;">&#91;</span>thing<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> lockLevel<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #009900;">&#125;</span>
         <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
      <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">&quot;Array&quot;</span><span style="color: #339933;">:</span>
         <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> prefs.<span style="color: #660066;">length</span> <span style="color: #339933;">%</span> <span style="color: #CC0000;">2</span> <span style="color: #339933;">!=</span> <span style="color: #CC0000;">0</span> <span style="color: #009900;">&#41;</span>
         <span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">throw</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Need an even number of strings to set multiple preferences with an array&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #009900;">&#125;</span>
         <span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> prefs.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i <span style="color: #339933;">=</span> i <span style="color: #339933;">+</span> <span style="color: #CC0000;">2</span> <span style="color: #009900;">&#41;</span>
         <span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">setPref</span><span style="color: #009900;">&#40;</span>prefs<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> prefs<span style="color: #009900;">&#91;</span>i<span style="color: #339933;">+</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> lockLevel<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #009900;">&#125;</span>
         <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
      <span style="color: #003366; font-weight: bold;">default</span><span style="color: #339933;">:</span>
         <span style="color: #000066; font-weight: bold;">throw</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;I don't know how to set multiple prefs with a &quot;</span> <span style="color: #339933;">+</span> trueTypeOf<span style="color: #009900;">&#40;</span>prefs<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h1><a href="http://blog.deanandadie.net/wp-content/uploads/2010/05/preference_factory.js">Download the full source</a></h1>
<h1>Scene from an upcoming post</h1>
<p>I alluded to another purpose for this prototype and this is a glimpse of how I use it with Thunderbird in the real world.&nbsp; Stay tuned.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">   <span style="color: #006600; font-style: italic;">// Create an email account</span>
   <span style="color: #003366; font-weight: bold;">var</span> brewingAccount <span style="color: #339933;">=</span> AccountManager.<span style="color: #660066;">newAccount</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> isDefault<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span> type<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;imap&quot;</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #006600; font-style: italic;">// Lock Preferences on the IMAP server</span>
   brewingAccount.<span style="color: #660066;">server</span>.<span style="color: #660066;">setPrefs</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> capability<span style="color: #339933;">:</span> <span style="color: #CC0000;">81</span><span style="color: #339933;">,</span>
                                    hostname<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;mail.example.com&quot;</span><span style="color: #339933;">,</span>
                                    port<span style="color: #339933;">:</span> <span style="color: #CC0000;">993</span><span style="color: #339933;">,</span>
                                    realhostname<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;mail.example.com&quot;</span><span style="color: #339933;">,</span>
                                    realusername<span style="color: #339933;">:</span> brewingMail<span style="color: #339933;">,</span>
                                    remember_password<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span>
                                    socketType<span style="color: #339933;">:</span> <span style="color: #CC0000;">3</span><span style="color: #339933;">,</span>
                                    type<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;imap&quot;</span><span style="color: #339933;">,</span>
                                    userName<span style="color: #339933;">:</span> brewingMail <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;lock&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #006600; font-style: italic;">// Default Preferences</span>
   brewingAccount.<span style="color: #660066;">server</span>.<span style="color: #660066;">setPrefs</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> check_new_mail<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span>
                                    check_time<span style="color: #339933;">:</span> <span style="color: #CC0000;">10</span><span style="color: #339933;">,</span>
                                    cleanup_inbox_on_exit<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span>
                                    delete_model<span style="color: #339933;">:</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">,</span>   <span style="color: #009966; font-style: italic;">/* Move to trash */</span>
                                    directory<span style="color: #339933;">:</span> userInfo.<span style="color: #660066;">env_home</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;/Mail&quot;</span><span style="color: #339933;">,</span>
                                    <span style="color: #3366CC;">&quot;directory-rel&quot;</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;[ProfD]../../Mail&quot;</span><span style="color: #339933;">,</span>
                                    empty_trash_on_exit<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span>
                                    empty_trash_threshhold<span style="color: #339933;">:</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">,</span>
                                    <span style="color: #000066;">name</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Brewing Mail&quot;</span><span style="color: #339933;">,</span>
                                    login_at_startup<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span>
                                    using_subscription<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #006600; font-style: italic;">// Lock Preferences on the SMTP server</span>
  brewingAccount.<span style="color: #660066;">smtpServer</span>.<span style="color: #660066;">setPrefs</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> auth_method<span style="color: #339933;">:</span> <span style="color: #CC0000;">1</span><span style="color: #339933;">,</span>    <span style="color: #006600; font-style: italic;">/* User/pass */</span>
                                       port<span style="color: #339933;">:</span> <span style="color: #CC0000;">465</span><span style="color: #339933;">,</span>
                                       username<span style="color: #339933;">:</span> brewingMail <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;lock&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #006600; font-style: italic;">// Default Preferences</span>
  brewingAccount.<span style="color: #660066;">smtpServer</span>.<span style="color: #660066;">setPrefs</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> description<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;Brewing SMTP server&quot;</span><span style="color: #339933;">,</span>
                                       hostname<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;mail.example.com&quot;</span><span style="color: #339933;">,</span>
                                       try_ssl<span style="color: #339933;">:</span> <span style="color: #CC0000;">3</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h1>The source</h1>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">/**
   By Dean Brundage
   Originally published here:
     http://blog.deanandadie.net/2010/05/manufacturing-user-preferences-for-mcd/
&nbsp;
   Mix-in prototype for other objects that want to set defaultPref, lockPref
     or just plain old pref().
   Use the utility function copyPrototype() to copy this object's prototype
     functions to other objects.  This can also be used as a stand-alone object.
     Pass the prefix string to the constructor
   Example [mix-in]:
      function Mail.Server()
      {  // It's very important to update the object's preference path
         this.Mail();
         this.addPrefBranch(&quot;server&quot;);
         // Continue to define Mail.Server
      }
      copyPrototype(Mail.Server, PreferenceFactory);
      // Define the rest of Mail.Server's prototypes
&nbsp;
      // Then you can set preferences on your Mail.Server object
      myServer = new Mail.Server();
      myServer.setPref(&quot;type&quot;, &quot;imap&quot;, &quot;lock&quot;);  // Lock the type of server to IMAP
&nbsp;
   Example [stand-alone]:
      var prefFact = new PreferenceFactory( [&quot;mail&quot;, &quot;accountmanager&quot;] );
      prefFact.setPref(&quot;localfoldersserver&quot;, &quot;server2&quot; );
&nbsp;
*/</span>
<span style="color: #003366; font-weight: bold;">function</span> PreferenceFactory<span style="color: #009900;">&#40;</span>arg<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">prefNodes</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
   <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">prefBranch</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #339933;">;</span>
   <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>arg<span style="color: #009900;">&#41;</span>
      <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">addPrefBranch</span><span style="color: #009900;">&#40;</span>arg<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
<span style="color: #006600; font-style: italic;">// Add a string or many strings to the preference branch</span>
PreferenceFactory.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">addPrefBranch</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>nodes<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">switch</span><span style="color: #009900;">&#40;</span> trueTypeOf<span style="color: #009900;">&#40;</span>nodes<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>
   <span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">&quot;String&quot;</span><span style="color: #339933;">:</span>
         <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">prefNodes</span>.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>nodes<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
         <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
      <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">&quot;Array&quot;</span><span style="color: #339933;">:</span>
         <span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> nodes.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i<span style="color: #339933;">++</span> <span style="color: #009900;">&#41;</span>
            <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">prefNodes</span>.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>nodes<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
         <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
      <span style="color: #003366; font-weight: bold;">default</span><span style="color: #339933;">:</span>
         <span style="color: #000066; font-weight: bold;">throw</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Don't know how to addPrefBranch for a &quot;</span> <span style="color: #339933;">+</span> trueTypeOf<span style="color: #009900;">&#40;</span>nodes<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
         <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
   <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">prefBranch</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">prefNodes</span>.<span style="color: #660066;">join</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;.&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
PreferenceFactory.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">defaultPref</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>key<span style="color: #339933;">,</span>value<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> key <span style="color: #009900;">&#41;</span>
      defaultPref<span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">prefBranch</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;.&quot;</span> <span style="color: #339933;">+</span> key<span style="color: #339933;">,</span> value <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
PreferenceFactory.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">getPref</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>key<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> key <span style="color: #009900;">&#41;</span>
      getPref<span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">prefBranch</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;.&quot;</span> <span style="color: #339933;">+</span> key <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
PreferenceFactory.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">lockPref</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>key<span style="color: #339933;">,</span>value<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> key <span style="color: #009900;">&#41;</span>
      lockPref<span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">prefBranch</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;.&quot;</span> <span style="color: #339933;">+</span> key<span style="color: #339933;">,</span> value <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
PreferenceFactory.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">pref</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>key<span style="color: #339933;">,</span>value<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> key <span style="color: #009900;">&#41;</span>
      pref<span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">prefBranch</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;.&quot;</span> <span style="color: #339933;">+</span> key<span style="color: #339933;">,</span> value <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
<span style="color: #006600; font-style: italic;">/*
   Preference setting helper function
   myServer.setPref(&quot;type&quot;, &quot;imap&quot;, &quot;lock&quot;);
   Arguments
     key: The preference string to set
     value: Value to assign to key
     lockLevel: Locking level.
            Valid values are &quot;default&quot;, &quot;lock&quot; and &quot;pref&quot;
            Default level is &quot;defulat&quot;
*/</span>
PreferenceFactory.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">setPref</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>key<span style="color: #339933;">,</span>value<span style="color: #339933;">,</span>lockLevel<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> lockLevel <span style="color: #009900;">&#41;</span>
   <span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">switch</span><span style="color: #009900;">&#40;</span>lockLevel.<span style="color: #660066;">toLowerCase</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">&quot;default&quot;</span><span style="color: #339933;">:</span>
            <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">defaultPref</span><span style="color: #009900;">&#40;</span>key<span style="color: #339933;">,</span>value<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
         <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">&quot;lock&quot;</span><span style="color: #339933;">:</span>
            <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">lockPref</span><span style="color: #009900;">&#40;</span>key<span style="color: #339933;">,</span>value<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
         <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">&quot;pref&quot;</span><span style="color: #339933;">:</span>
            <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">pref</span><span style="color: #009900;">&#40;</span>key<span style="color: #339933;">,</span>value<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
            <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
         <span style="color: #003366; font-weight: bold;">default</span><span style="color: #339933;">:</span>
            <span style="color: #000066; font-weight: bold;">throw</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Unrecognized locking level: &quot;</span> <span style="color: #339933;">+</span> lockLevel <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
   <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span>
   <span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">defaultPref</span><span style="color: #009900;">&#40;</span>key<span style="color: #339933;">,</span>value<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
&nbsp;
<span style="color: #006600; font-style: italic;">/* Sets multiple preferences
   Accepts an array or object &quot;hash&quot; and an optional locking level
*/</span>
PreferenceFactory.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">setPrefs</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>prefs<span style="color: #339933;">,</span>lockLevel<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">switch</span><span style="color: #009900;">&#40;</span> trueTypeOf<span style="color: #009900;">&#40;</span>prefs<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>
   <span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">&quot;Object&quot;</span><span style="color: #339933;">:</span>
         <span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span> thing <span style="color: #000066; font-weight: bold;">in</span> prefs <span style="color: #009900;">&#41;</span>
         <span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">setPref</span><span style="color: #009900;">&#40;</span>thing<span style="color: #339933;">,</span> prefs<span style="color: #009900;">&#91;</span>thing<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> lockLevel<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #009900;">&#125;</span>
         <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
      <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">&quot;Array&quot;</span><span style="color: #339933;">:</span>
         <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> prefs.<span style="color: #660066;">length</span> <span style="color: #339933;">%</span> <span style="color: #CC0000;">2</span> <span style="color: #339933;">!=</span> <span style="color: #CC0000;">0</span> <span style="color: #009900;">&#41;</span>
         <span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">throw</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Need an even number of strings to set multiple preferences with an array&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #009900;">&#125;</span>
         <span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span> i <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span> i <span style="color: #339933;">&lt;</span> prefs.<span style="color: #660066;">length</span><span style="color: #339933;">;</span> i <span style="color: #339933;">=</span> i <span style="color: #339933;">+</span> <span style="color: #CC0000;">2</span> <span style="color: #009900;">&#41;</span>
         <span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">setPref</span><span style="color: #009900;">&#40;</span>prefs<span style="color: #009900;">&#91;</span>i<span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> prefs<span style="color: #009900;">&#91;</span>i<span style="color: #339933;">+</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> lockLevel<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #009900;">&#125;</span>
         <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
      <span style="color: #003366; font-weight: bold;">default</span><span style="color: #339933;">:</span>
         <span style="color: #000066; font-weight: bold;">throw</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;I don't know how to set multiple prefs with a &quot;</span> <span style="color: #339933;">+</span> trueTypeOf<span style="color: #009900;">&#40;</span>prefs<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> trueTypeOf<span style="color: #009900;">&#40;</span>something<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #006600; font-style: italic;">// Borrowed from jsUnitCore.js.  Thank you.</span>
   <span style="color: #006600; font-style: italic;">// http://github.com/pivotal/jsunit/blob/master/app/jsUnitCore.js</span>
   <span style="color: #003366; font-weight: bold;">var</span> result <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">typeof</span> something<span style="color: #339933;">;</span>
   <span style="color: #000066; font-weight: bold;">try</span>
   <span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">switch</span> <span style="color: #009900;">&#40;</span>result<span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'string'</span><span style="color: #339933;">:</span>
            <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
         <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'boolean'</span><span style="color: #339933;">:</span>
            <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
         <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'number'</span><span style="color: #339933;">:</span>
            <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
         <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'object'</span><span style="color: #339933;">:</span>
         <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #3366CC;">'function'</span><span style="color: #339933;">:</span>
            <span style="color: #000066; font-weight: bold;">switch</span> <span style="color: #009900;">&#40;</span>something.<span style="color: #660066;">constructor</span><span style="color: #009900;">&#41;</span>
            <span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #003366; font-weight: bold;">new</span> String<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">constructor</span><span style="color: #339933;">:</span>
                        result <span style="color: #339933;">=</span> <span style="color: #3366CC;">'String'</span><span style="color: #339933;">;</span>
                        <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
               <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #003366; font-weight: bold;">new</span> Boolean<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">constructor</span><span style="color: #339933;">:</span>
                        result <span style="color: #339933;">=</span> <span style="color: #3366CC;">'Boolean'</span><span style="color: #339933;">;</span>
                        <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
               <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #003366; font-weight: bold;">new</span> Number<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">constructor</span><span style="color: #339933;">:</span>
                        result <span style="color: #339933;">=</span> <span style="color: #3366CC;">'Number'</span><span style="color: #339933;">;</span>
                        <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
               <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #003366; font-weight: bold;">new</span> Array<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">constructor</span><span style="color: #339933;">:</span>
                        result <span style="color: #339933;">=</span> <span style="color: #3366CC;">'Array'</span><span style="color: #339933;">;</span>
                        <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
               <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #003366; font-weight: bold;">new</span> RegExp<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">constructor</span><span style="color: #339933;">:</span>
                        result <span style="color: #339933;">=</span> <span style="color: #3366CC;">'RegExp'</span><span style="color: #339933;">;</span>
                        <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
               <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #003366; font-weight: bold;">new</span> Date<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">constructor</span><span style="color: #339933;">:</span>
                        result <span style="color: #339933;">=</span> <span style="color: #3366CC;">'Date'</span><span style="color: #339933;">;</span>
                        <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
               <span style="color: #000066; font-weight: bold;">case</span> <span style="color: #003366; font-weight: bold;">Function</span><span style="color: #339933;">:</span>
                        result <span style="color: #339933;">=</span> <span style="color: #3366CC;">'Function'</span><span style="color: #339933;">;</span>
                        <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
               <span style="color: #003366; font-weight: bold;">default</span><span style="color: #339933;">:</span>
                  <span style="color: #003366; font-weight: bold;">var</span> m <span style="color: #339933;">=</span> something.<span style="color: #660066;">constructor</span>.<span style="color: #660066;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">match</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/function\s*([^( ]+)\(/</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
                  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>m<span style="color: #009900;">&#41;</span>
                     result <span style="color: #339933;">=</span> m<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
                  <span style="color: #000066; font-weight: bold;">else</span>
                     <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
            <span style="color: #009900;">&#125;</span>
            <span style="color: #000066; font-weight: bold;">break</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
   <span style="color: #009900;">&#125;</span>
   <span style="color: #000066; font-weight: bold;">finally</span>
   <span style="color: #009900;">&#123;</span>  result <span style="color: #339933;">=</span> result.<span style="color: #660066;">substr</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">toUpperCase</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> result.<span style="color: #660066;">substr</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000066; font-weight: bold;">return</span> result<span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h3>You may also like these:</h3><ul>
<li><a href='http://blog.deanandadie.net/2010/04/setting-user-preferences-with-mission-control-desktop/' rel='bookmark' title='Setting User Preferences with Mission Control Desktop'>Setting User Preferences with Mission Control Desktop</a> <small>A challenge with software Managing software for thousands of users...</small></li>
<li><a href='http://blog.deanandadie.net/2010/06/easy-thunderbird-account-management-using-mcd/' rel='bookmark' title='Easy Thunderbird Account Management Using MCD'>Easy Thunderbird Account Management Using MCD</a> <small>Continuing my series on Mission Control Desktop, this post covers...</small></li>
<li><a href='http://blog.deanandadie.net/2010/05/reading-local-files-with-javascript/' rel='bookmark' title='Reading Local Files With Javascript'>Reading Local Files With Javascript</a> <small>Security Conscious Javascript Normally, javascript does not have access to...</small></li>
</ul>
<p>Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.deanandadie.net/2010/05/manufacturing-user-preferences-for-mcd/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Reading Local Files With Javascript</title>
		<link>http://blog.deanandadie.net/2010/05/reading-local-files-with-javascript/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=reading-local-files-with-javascript</link>
		<comments>http://blog.deanandadie.net/2010/05/reading-local-files-with-javascript/#comments</comments>
		<pubDate>Tue, 04 May 2010 22:03:14 +0000</pubDate>
		<dc:creator>Dean</dc:creator>
				<category><![CDATA[Enterprise Software]]></category>
		<category><![CDATA[autoconfig]]></category>
		<category><![CDATA[enterprise]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[mcd]]></category>
		<category><![CDATA[mission control desktop]]></category>
		<category><![CDATA[thunderbird]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://blog.deanandadie.net/?p=919</guid>
		<description><![CDATA[Security Conscious Javascript Normally, javascript does not have access to local files.  Rightfully so because almost every web server should be untrusted and allowing anybody to read your files is a large security risk.  Mission Control Desktop, however is a javascript application with access to XPCOM, Mozilla&#8217;s component object model. This article is an example [...]<h3>You may also like these:</h3><ul>
<li><a href='http://blog.deanandadie.net/2010/05/manufacturing-user-preferences-for-mcd/' rel='bookmark' title='Manufacturing User Preferences For MCD'>Manufacturing User Preferences For MCD</a> <small>Nobody likes boring code Mozilla products like Thunderbird and Firefox...</small></li>
<li><a href='http://blog.deanandadie.net/2010/04/ldap-queries-in-mission-control-desktop/' rel='bookmark' title='LDAP Queries in Mission Control Desktop'>LDAP Queries in Mission Control Desktop</a> <small>Previously, we saw that Mozilla MCD can inspect a user&#8217;s...</small></li>
<li><a href='http://blog.deanandadie.net/2010/04/an-introduction-to-mission-control-desktop/' rel='bookmark' title='An Introduction To Mission Control Desktop'>An Introduction To Mission Control Desktop</a> <small>What is MCD? MCD (aka AutoConfig) is a script used...</small></li>
</ul>

Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<h1>Security Conscious Javascript</h1>
<p>Normally, javascript does not have access to local files.  Rightfully so because almost every web server should be untrusted and allowing anybody to read your files is a large security risk.  <a href="http://blog.deanandadie.net/2010/04/an-introduction-to-mission-control-desktop/">Mission Control Desktop</a>, however is a javascript application with access to <a href="https://developer.mozilla.org/en/XPCOM">XPCOM</a>, Mozilla&#8217;s component object model.  This article is an example of how to use it to read local files.</p>
<h1>Solaris Printing Configuration</h1>
<p>I use <abbr title="Mission Control Desktop">MCD</abbr> to configure thousands of users&#8217; browser and mail clients.  In Solaris, <a href="http://docs.sun.com/app/docs/doc/806-0249/6j9k9022a?a=view">printer preferences</a> are set according to the <a href="http://kb.mozillazine.org/PostScript_Module">Mozilla Postscript subsystem</a> in a <code>.printers</code> file in the home directory.  Firefox and Thunderbird do not support this file interface so I use autoconfig to read the file and set printer preferences accordingly.</p>
<p>I wrote an object prototype to read and parse <code>$HOME/.printers</code> which the autoconfig uses to set the <code>print.printer_list</code> preference.  The prototype searches the file for a string indicating the list of printers to use:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;"># $HOME/.printers</span>
<span style="color: #666666; font-style: italic;"># Set the default printer to riemann</span>
_default riemann
<span style="color: #666666; font-style: italic;"># Display a chooser for three printers, ignoring all others.</span>
_all newton,poincare,riemann</pre></div></div>

<p>The line beginning with <code>_all</code> is quite important in my environment with 1,700 printers configured through LDAP.  If Thunderbird or Firefox were to try to load the entire printer list, it would become overwhelmed and crash.</p>
<h1>extract_allPrinters utility</h1>
<p>First, a look at the utility function I use to find the right line.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">typeof</span><span style="color: #009900;">&#40;</span>FileInterface<span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #3366CC;">&quot;undefined&quot;</span> <span style="color: #009900;">&#41;</span>  <span style="color: #006600; font-style: italic;">// Barf if the object prototype is undefined</span>
   <span style="color: #000066; font-weight: bold;">throw</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;autoconfig constructed improperly: need classes/file_interface.js before extract_all_printers.js&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">function</span> extract_allPrinters<span style="color: #009900;">&#40;</span>path<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">typeof</span><span style="color: #009900;">&#40;</span>path<span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #3366CC;">&quot;undefined&quot;</span> <span style="color: #009900;">&#41;</span>
      path <span style="color: #339933;">=</span> env_home <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;/.printers&quot;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #006600; font-style: italic;">// Regular expression to search .printers for _all</span>
   re <span style="color: #339933;">=</span> <span style="color: #009966; font-style: italic;">/^\s*_all\s+(.+)\s*/i</span><span style="color: #339933;">;</span>
   lines <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> FileInterface<span style="color: #009900;">&#40;</span>path<span style="color: #009900;">&#41;</span>.<span style="color: #660066;">grep</span><span style="color: #009900;">&#40;</span>re<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">typeof</span><span style="color: #009900;">&#40;</span>lines<span style="color: #009900;">&#41;</span> <span style="color: #339933;">!=</span> <span style="color: #3366CC;">&quot;undefined&quot;</span> <span style="color: #009900;">&#41;</span>
   <span style="color: #009900;">&#123;</span>  <span style="color: #006600; font-style: italic;">// Take the first match</span>
      allPrinters <span style="color: #339933;">=</span> re.<span style="color: #660066;">exec</span><span style="color: #009900;">&#40;</span> lines<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">replace</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">/,\s*/g</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot; &quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
   <span style="color: #000066; font-weight: bold;">return</span> allPrinters<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">/*
   *snip*
*/</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Tell FF &amp;amp; TB which printers to offer a print dialogue for</span>
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;print.printer_list&quot;</span><span style="color: #339933;">,</span> extract_allPrinters<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>The first lines check that the <code>FileInterface</code> object prototype is defined.  This is necessary because my autoconfig script broken into component scripts in the filesystem.  Besides making it easier to maintain, I can share functionality between Firefox and Thunderbird while excluding application-specific parts from the wrong autoconfig.</p>
<p>This function uses a prototype called <code>FileInterface</code> (explained later) to grep <code>.printers</code> for lines beginning with <em>_all</em>.   If <code>grep</code> returns a match, the function takes the first one.  <code>print.printer_list</code> takes a space-separated list of printers while <code>_all</code> is comma-separated, so the final thing to do is <code>replace</code> the commas with spaces.</p>
<p>Later on in the script I call <code>defaultPref</code> to set the printer list.</p>
<h1>The FileInterface object prototype</h1>
<p><code>nsILocalFile</code> is the XPCOM interface used to access files on the client-side filesystem.  This object prototype provides only enough functionality to search files, but remains extensible should I need to create or modify.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// All you need is a (string) path</span>
<span style="color: #003366; font-weight: bold;">function</span> FileInterface<span style="color: #009900;">&#40;</span>path<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #000066; font-weight: bold;">typeof</span><span style="color: #009900;">&#40;</span>path<span style="color: #009900;">&#41;</span> <span style="color: #339933;">==</span> <span style="color: #3366CC;">&quot;undefined&quot;</span> <span style="color: #009900;">&#41;</span>
     <span style="color: #000066; font-weight: bold;">throw</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Need a path for FileInterface()&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">path</span> <span style="color: #339933;">=</span> path<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">/* Emulate the functionality of unix grep
   Takes a RegExp as it's only argument
   Returns an array of lines matching the RegExp
     E.G.: passwd = new FileInterface(&quot;/etc/passwd&quot;);
           lines = passwd.grep(/brundage/);
           // lines[0] = brundage:x:1002:1002::/home/brundage:/bin/zsh
*/</span>
FileInterface.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">grep</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>re<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  matches <span style="color: #339933;">=</span> undefined<span style="color: #339933;">;</span>
   <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> re <span style="color: #009900;">&#41;</span>
   <span style="color: #009900;">&#123;</span>  line <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
      matches <span style="color: #339933;">=</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
      <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">initIStream</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000066; font-weight: bold;">do</span>
      <span style="color: #009900;">&#123;</span>  hasMore <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">iStream</span>.<span style="color: #660066;">readLine</span><span style="color: #009900;">&#40;</span>line<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
         <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> re.<span style="color: #660066;">test</span><span style="color: #009900;">&#40;</span>line.<span style="color: #660066;">value</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span>
            matches.<span style="color: #660066;">push</span><span style="color: #009900;">&#40;</span>line.<span style="color: #660066;">value</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">while</span><span style="color: #009900;">&#40;</span>hasMore<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">iStream</span>.<span style="color: #000066;">close</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
   <span style="color: #000066; font-weight: bold;">return</span> matches<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">/* Initializes a nsILineInputStream for higher-level functions
   Takes three arguments, assigning read-only defaults to undefined arguments.
   For possible values see: https://developer.mozilla.org/en/NsIFileInputStream
*/</span>
FileInterface.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">initIStream</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>ioFlags<span style="color: #339933;">,</span>perm<span style="color: #339933;">,</span>behaviorFlags<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> ioFlags <span style="color: #009900;">&#41;</span>
     ioFlags <span style="color: #339933;">=</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>  <span style="color: #006600; font-style: italic;">// Default mode (PR_READONLY)</span>
   <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> perm <span style="color: #009900;">&#41;</span>
     perm <span style="color: #339933;">=</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">1</span><span style="color: #339933;">;</span>  <span style="color: #006600; font-style: italic;">// Default mode (0)</span>
   <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> behaviorFlags <span style="color: #009900;">&#41;</span>
     behaviorFlags <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #006600; font-style: italic;">// Initializing the stream requires an nsILocalFile.  Make one out of the path attribute.</span>
   <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">initLocalFile</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #006600; font-style: italic;">// Get the nsIFileInputStream instance from the global Components variable</span>
   <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">iStream</span> <span style="color: #339933;">=</span>  Components.<span style="color: #660066;">classes</span><span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;@mozilla.org/network/file-input-stream;1&quot;</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">createInstance</span><span style="color: #009900;">&#40;</span>Components.<span style="color: #660066;">interfaces</span>.<span style="color: #660066;">nsIFileInputStream</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">iStream</span> <span style="color: #009900;">&#41;</span>  <span style="color: #006600; font-style: italic;">// Bad Things</span>
      <span style="color: #000066; font-weight: bold;">throw</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;network/file-input-stream component does not exist&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #006600; font-style: italic;">// Point the stream at the iLocalFile</span>
   <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">iStream</span>.<span style="color: #660066;">init</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">iLocalFile</span><span style="color: #339933;">,</span> ioFlags<span style="color: #339933;">,</span> perm<span style="color: #339933;">,</span> behaviorFlags<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #006600; font-style: italic;">// Transform iStream into a nsILineInputStream</span>
   <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">iStream</span>.<span style="color: #660066;">QueryInterface</span><span style="color: #009900;">&#40;</span>Components.<span style="color: #660066;">interfaces</span>.<span style="color: #660066;">nsILineInputStream</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">/* Initialize an nsILocalFile instance with the path attribute of this object
   Required for streams
*/</span>
FileInterface.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">initLocalFile</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">iLocalFile</span> <span style="color: #339933;">=</span> Components.<span style="color: #660066;">classes</span><span style="color: #009900;">&#91;</span><span style="color: #3366CC;">&quot;@mozilla.org/file/local;1&quot;</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">createInstance</span><span style="color: #009900;">&#40;</span>Components.<span style="color: #660066;">interfaces</span>.<span style="color: #660066;">nsILocalFile</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">iLocalFile</span> <span style="color: #009900;">&#41;</span>  <span style="color: #006600; font-style: italic;">// Bad Things</span>
     <span style="color: #000066; font-weight: bold;">throw</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;file/local component does not exist&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">iLocalFile</span>.<span style="color: #660066;">initWithPath</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">path</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h1>There you have it</h1>
<p>I have only encountered this single situation that requires access to the local filesystem.  Can you think of others?</p>
<h3>You may also like these:</h3><ul>
<li><a href='http://blog.deanandadie.net/2010/05/manufacturing-user-preferences-for-mcd/' rel='bookmark' title='Manufacturing User Preferences For MCD'>Manufacturing User Preferences For MCD</a> <small>Nobody likes boring code Mozilla products like Thunderbird and Firefox...</small></li>
<li><a href='http://blog.deanandadie.net/2010/04/ldap-queries-in-mission-control-desktop/' rel='bookmark' title='LDAP Queries in Mission Control Desktop'>LDAP Queries in Mission Control Desktop</a> <small>Previously, we saw that Mozilla MCD can inspect a user&#8217;s...</small></li>
<li><a href='http://blog.deanandadie.net/2010/04/an-introduction-to-mission-control-desktop/' rel='bookmark' title='An Introduction To Mission Control Desktop'>An Introduction To Mission Control Desktop</a> <small>What is MCD? MCD (aka AutoConfig) is a script used...</small></li>
</ul>
<p>Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.deanandadie.net/2010/05/reading-local-files-with-javascript/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mapping Firefox &amp; Thunderbird Behaviors to Preference Settings</title>
		<link>http://blog.deanandadie.net/2010/04/mapping-firefox-thunderbird-behaviors-to-preference-settings/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mapping-firefox-thunderbird-behaviors-to-preference-settings</link>
		<comments>http://blog.deanandadie.net/2010/04/mapping-firefox-thunderbird-behaviors-to-preference-settings/#comments</comments>
		<pubDate>Wed, 21 Apr 2010 16:42:44 +0000</pubDate>
		<dc:creator>Dean</dc:creator>
				<category><![CDATA[Enterprise Software]]></category>
		<category><![CDATA[autoconfig]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[mission control desktop]]></category>
		<category><![CDATA[preferences]]></category>
		<category><![CDATA[thunderbird]]></category>

		<guid isPermaLink="false">http://blog.deanandadie.net/?p=809</guid>
		<description><![CDATA[Individual in the Enterprise Firefox, Thunderbird have full-fledged graphical settings editors.  It is easy for a user to change the behavior of his or her web browser with a few mouse clicks.  While this approach is sensible for the home user, GUIs hamper software configuration in the corporate enterprise.  Although Mozilla products textually represent preferences [...]<h3>You may also like these:</h3><ul>
<li><a href='http://blog.deanandadie.net/2010/05/manufacturing-user-preferences-for-mcd/' rel='bookmark' title='Manufacturing User Preferences For MCD'>Manufacturing User Preferences For MCD</a> <small>Nobody likes boring code Mozilla products like Thunderbird and Firefox...</small></li>
<li><a href='http://blog.deanandadie.net/2010/04/setting-user-preferences-with-mission-control-desktop/' rel='bookmark' title='Setting User Preferences with Mission Control Desktop'>Setting User Preferences with Mission Control Desktop</a> <small>A challenge with software Managing software for thousands of users...</small></li>
<li><a href='http://blog.deanandadie.net/2010/04/an-introduction-to-mission-control-desktop/' rel='bookmark' title='An Introduction To Mission Control Desktop'>An Introduction To Mission Control Desktop</a> <small>What is MCD? MCD (aka AutoConfig) is a script used...</small></li>
</ul>

Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p><img class="aligncenter size-full wp-image-816" title="thunderbird_settings" src="http://blog.deanandadie.net/wp-content/uploads/2010/04/thunderbird_settings.png" alt="Thunderbird settings" width="590" height="400" /></p>
<h1>Individual in the Enterprise</h1>
<p>Firefox, Thunderbird have full-fledged graphical settings editors.  It is easy for a user to change the behavior of his or her web browser with a few mouse clicks.  While this approach is sensible for the home user, <abbr title="graphical user iterfaces">GUIs</abbr> hamper software configuration in the corporate enterprise.  Although Mozilla products textually represent preferences in a flat file, discovering the right text and value is not always simple.  I will outline some techniques I use to determine preference strings for a given behavior.</p>
<h1>Preferences in Mission Control Desktop</h1>
<p>Mozilla <a href="http://blog.deanandadie.net/2010/04/an-introduction-to-mission-control-desktop/"><abbr title="Mission Control Desktop">MCD</abbr> autoconfig</a> is an invaluable tool to the software administrator.  It runs at browser startup setting preferences according to corporate policy.  After starting, Firefox <em>saves all settings</em> to the user&#8217;s local <code>prefs.js</code> file.  The autoconfig API and user  <code>prefs.js</code> work with text preferences.  When you decide to change the application&#8217;s behavior your <code>prefs.js</code> is a good place to look.</p>
<h3>Start clean</h3>
<p>Quit Firefox.  Backup then remove your Firefox profile directory. On linux it is in <code>$HOME/.mozilla/firefox</code>. Then launch the browser starting with a good autoconfigured profile.</p>
<h3>Compare</h3>
<p>Take a backup of your user prefs.js from Firefox&#8221;s profile directory. (<code>$HOME/.mozilla/firefox//prefs.js</code>)  Make the behavior change and apply.  Use <code>diff</code> to compare the preference files.</p>
<h3>An example</h3>
<p>Suppose your company decides that Firefox should only keep third-party cookies for the lifetime of the browser.  Once the user closes Firefox, it will delete all third-party cookies.  Make the change (for version 3.6.3) in <em>Settings</em> &#8211;&gt; <em>Privacy</em> &#8211;&gt; Check <em>Accept cookies from sites</em>, then check <em>Accept third-party cookies</em> and change the dropdown to Keep until: <em>I close Firefox</em>.</p>
<p>Your preferences should look something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="diff" style="font-family:monospace;"><span style="">0</span> apollo firefox/kzssiknu.default % diff -u prefs.js.pre prefs.js
<span style="color: #888822;">--- prefs.js.pre    2010-04-22 12:57:30.000000000 -0500</span>
<span style="color: #888822;">+++ prefs.js        2010-04-22 12:57:39.000000000 -0500</span>
<span style="color: #440088;">@@ -230,6 +230,7 @@</span>
 user_pref<span style="">&#40;</span>&quot;lightweightThemes.persisted.footerURL&quot;, true<span style="">&#41;</span>;
 user_pref<span style="">&#40;</span>&quot;lightweightThemes.persisted.headerURL&quot;, true<span style="">&#41;</span>;
 user_pref<span style="">&#40;</span>&quot;metrics.upload.enable&quot;, false<span style="">&#41;</span>;
<span style="color: #00b000;">+user_pref<span style="">&#40;</span>&quot;network.cookie.lifetimePolicy&quot;, <span style="">2</span><span style="">&#41;</span>;</span>
 user_pref<span style="">&#40;</span>&quot;network.cookie.prefsMigrated&quot;, true<span style="">&#41;</span>;
 user_pref<span style="">&#40;</span>&quot;nglayout.debug.disable_xul_cache&quot;, true<span style="">&#41;</span>;
 user_pref<span style="">&#40;</span>&quot;nglayout.debug.disable_xul_fastload&quot;, true<span style="">&#41;</span>;</pre></div></div>

<p>See that a new preference called <code>network.cookie.lifetimePolicy</code> was inserted with value <code>2</code>.  Use these in autoconfig, calling</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Remember third-party cookies until the browser closes</span>
lockPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;network.cookie.lifetimePolicy&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h1>Sometimes it&#8217;s not that easy</h1>
<p>The above method does not work all the time.  For example, Thunderbird&#8217;s <em>password</em> settings are not so obvious.  My company does not allow password storage so I needed to lock out that behavior.<br />
<img class="aligncenter size-full wp-image-841" title="Save Passwords" src="http://blog.deanandadie.net/wp-content/uploads/2010/04/Screen-shot-2010-04-22-at-2.29.34-PM.png" alt="Save Passwords" width="464" height="200" /></p>
<p>Inspecting the preferences GUI leads nowhere.  My first resource in these cases is the <a href="http://kb.mozillazine.org/About:config_entries">About:config_entries</a> page on MozillaZine.  It&#8217;s a wild wiki page containing <strong>mostly-complete</strong> setting documentation for all the Mozilla products.  There you will find a table with the right information.</p>
<table border="2" cellspacing="0" cellpadding="4">
<tbody>
<tr>
<th> Name</th>
<th> Type</th>
<th> Meaning of Values</th>
</tr>
<tr>
<td><strong>signon. rememberSignons</strong></td>
<td>Boolean</td>
<td><strong>True</strong>: (default): Enable the <a title="Password  Manager" href="http://kb.mozillazine.org/Password_Manager">Password Manager</a><br />
<strong>False</strong> Opposite of the above</td>
</tr>
</tbody>
</table>
<p>The About:config_entries page also has pointers to the wiki&#8217;s <a href="http://kb.mozillazine.org/Category:Preferences">Category:Preferences</a> and <a href="http://preferential.mozdev.org/preferences.html">The Preferential Project</a>.  Each page has something the others lack.  When these resources fail, I sign on to <a href="http://irc.mozilla.org/">irc.mozilla.org</a> (as <code>OccamRazor</code>, old-school <abbr title="Internet relay chat">IRC</abbr> etiquette rules apply.) or as a last resort, hit a search engine.</p>
<h1>Document it</h1>
<p>When you find the right text to twiddle document the behavior in your autoconfig as I did for the cookie lifetime above.</p>
<h3>You may also like these:</h3><ul>
<li><a href='http://blog.deanandadie.net/2010/05/manufacturing-user-preferences-for-mcd/' rel='bookmark' title='Manufacturing User Preferences For MCD'>Manufacturing User Preferences For MCD</a> <small>Nobody likes boring code Mozilla products like Thunderbird and Firefox...</small></li>
<li><a href='http://blog.deanandadie.net/2010/04/setting-user-preferences-with-mission-control-desktop/' rel='bookmark' title='Setting User Preferences with Mission Control Desktop'>Setting User Preferences with Mission Control Desktop</a> <small>A challenge with software Managing software for thousands of users...</small></li>
<li><a href='http://blog.deanandadie.net/2010/04/an-introduction-to-mission-control-desktop/' rel='bookmark' title='An Introduction To Mission Control Desktop'>An Introduction To Mission Control Desktop</a> <small>What is MCD? MCD (aka AutoConfig) is a script used...</small></li>
</ul>
<p>Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.deanandadie.net/2010/04/mapping-firefox-thunderbird-behaviors-to-preference-settings/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>LDAP Queries in Mission Control Desktop</title>
		<link>http://blog.deanandadie.net/2010/04/ldap-queries-in-mission-control-desktop/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=ldap-queries-in-mission-control-desktop</link>
		<comments>http://blog.deanandadie.net/2010/04/ldap-queries-in-mission-control-desktop/#comments</comments>
		<pubDate>Mon, 19 Apr 2010 04:12:23 +0000</pubDate>
		<dc:creator>Dean</dc:creator>
				<category><![CDATA[Enterprise Software]]></category>
		<category><![CDATA[autoconfig]]></category>
		<category><![CDATA[enterprise]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[mcd]]></category>
		<category><![CDATA[mission control desktop]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[thunderbird]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://blog.deanandadie.net/?p=753</guid>
		<description><![CDATA[Previously, we saw that Mozilla MCD can inspect a user&#8217;s environment using getEnv().  It can also retrieve information from an LDAP directory.  I use this feature to inform Firefox and Thunderbird of the user in detail.  The corporate directory knows the user&#8217;s full name, mail server and authentication credentials.  autoconfig takes this and, among other [...]<h3>You may also like these:</h3><ul>
<li><a href='http://blog.deanandadie.net/2010/04/an-introduction-to-mission-control-desktop/' rel='bookmark' title='An Introduction To Mission Control Desktop'>An Introduction To Mission Control Desktop</a> <small>What is MCD? MCD (aka AutoConfig) is a script used...</small></li>
<li><a href='http://blog.deanandadie.net/2010/04/setting-user-preferences-with-mission-control-desktop/' rel='bookmark' title='Setting User Preferences with Mission Control Desktop'>Setting User Preferences with Mission Control Desktop</a> <small>A challenge with software Managing software for thousands of users...</small></li>
<li><a href='http://blog.deanandadie.net/2010/05/reading-local-files-with-javascript/' rel='bookmark' title='Reading Local Files With Javascript'>Reading Local Files With Javascript</a> <small>Security Conscious Javascript Normally, javascript does not have access to...</small></li>
</ul>

Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p>Previously, <a href="http://blog.deanandadie.net/2010/04/setting-user-preferences-with-mission-control-desktop/">we saw</a> that <a href="http://blog.deanandadie.net/2010/04/an-introduction-to-mission-control-desktop/">Mozilla MCD</a> can inspect a user&#8217;s environment using <code>getEnv()</code>.  It can also retrieve information from an LDAP directory.  I use this feature to inform Firefox and Thunderbird of the user in detail.  The corporate directory knows the user&#8217;s full name, mail server and authentication credentials.  autoconfig takes this and, among other useful things, constructs an email account for Thunderbird without user intervention.</p>
<p>The javascript API to deal with LDAP is a bit hackish, however it is all we have.  The first task is to define a function called <code>processLDAPValues()</code> which accepts a <code>queryResults</code> string as its only argument.  Inside <code>processLDAPValues</code> you extract return data from <code>queryResults</code>.</p>
<p>Instead of invoking <code>processLDAPValues()</code> directly, you call <code>getLDAPAttributes()</code> which in turn gets you to your function.  To illustrate, here is the code I use to query the corporate directory server and save the values for later use.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">var</span> userInfo <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Object<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #006600; font-style: italic;">// This will hold LDAP results</span>
&nbsp;
userInfo.<span style="color: #660066;">envUser</span> <span style="color: #339933;">=</span> getenv<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;LOGNAME&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>   <span style="color: #006600; font-style: italic;">// Unix UID</span>
userInfo.<span style="color: #660066;">envHome</span> <span style="color: #339933;">=</span> getenv<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;HOME&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>      <span style="color: #006600; font-style: italic;">// User home directory</span>
&nbsp;
<span style="color: #003366; font-weight: bold;">var</span> ldapHost <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;ldap.example.com&quot;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">var</span> ldapBase <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;dc=example,dc=com&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> userInfo.<span style="color: #660066;">envUser</span> <span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #003366; font-weight: bold;">var</span> ldapFilter <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;uid=&quot;</span> <span style="color: #339933;">+</span> userInfo.<span style="color: #660066;">envUser</span><span style="color: #339933;">;</span>  <span style="color: #009900;">&#125;</span>
<span style="color: #000066; font-weight: bold;">else</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">throw</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Couldn't get UID from the environment&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// LDAP attributes to retrieve from the server</span>
<span style="color: #003366; font-weight: bold;">var</span> ldapAttrs <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Array<span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&quot;cn&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;email&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;employeenumber&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;givenname&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;mailhost&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;sn&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;uid&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Define how to process LDAP results before we make the call</span>
<span style="color: #003366; font-weight: bold;">function</span> processLDAPValues<span style="color: #009900;">&#40;</span>queryResults<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> queryResults <span style="color: #009900;">&#41;</span>
   <span style="color: #009900;">&#123;</span>  <span style="color: #006600; font-style: italic;">// Build the userInfo object for later use</span>
      <span style="color: #000066; font-weight: bold;">for</span><span style="color: #009900;">&#40;</span> <span style="color: #003366; font-weight: bold;">var</span> attr <span style="color: #000066; font-weight: bold;">in</span> ldapAttrs <span style="color: #009900;">&#41;</span>
      <span style="color: #009900;">&#123;</span>  userInfo<span style="color: #009900;">&#91;</span> ldapAttrs<span style="color: #009900;">&#91;</span>attr<span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> getLDAPValue<span style="color: #009900;">&#40;</span> queryResults<span style="color: #339933;">,</span> ldapAttrs<span style="color: #009900;">&#91;</span>attr<span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #009900;">&#125;</span>
   <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span>
   <span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">throw</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&quot;No LDAP results&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span>
&nbsp;
<span style="color: #006600; font-style: italic;">// Call upon LDAP for the values in ldapAttrs array</span>
<span style="color: #006600; font-style: italic;">// Uses the previous processLDAPValues()</span>
getLDAPAttributes<span style="color: #009900;">&#40;</span> ldapHost<span style="color: #339933;">,</span> ldapBase<span style="color: #339933;">,</span> ldapFilter<span style="color: #339933;">,</span> ldapAttrs.<span style="color: #660066;">join</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;,&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>The first thing I do is create a <code>userInfo</code> object that will hold LDAP results for use later in the autoconfig.  To that object I add attributes for the user&#8217;s login name and home directory.</p>
<p>The next bit sets variables to contain the directory server&#8217;s hostname, base DN and the LDAP filter to use in the search. It&#8217;s a good idea to throw an error if there is no <code>$LOGNAME</code>.  (In a later post I will show how to enhance autoconfig error reporting.)</p>
<p>The <code>ldapAttrs</code> array names the attributes I want to return from LDAP.  Change this array to suit your environment.  The last line of code joins the array together with commas and feeds it to <code>getLDAPAttributes</code> along with the hostname, base DN and filter<code>.  getLDAPAttributes</code> is defined in <code>MOZILLA_HOME/defaults/autoconfig/prefcalls.js</code> and does the work to perform the query, then call your predefined <code>processLDAPValues()</code> function.</p>
<p>The example autoconfig script at developer.mozilla.org set preferences inside <code>processLDAPValues</code>, however this is a bad convention.  There are many preferences that require user information and separating <code>pref()</code> calls away from the main block of preference setting can be confusing.  As you can see here I simply run through the array of attributes I&#8217;m interested in and get the result from the LDAP query for that attribute, assigning it to the <code>userInfo</code> object.</p>
<p>Later on in the script I ask the <code>userInfo</code> object for those stored LDAP attributes.  To set the hostname of the user&#8217;s mail server, for example, I call</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// IMAP server name from corporate LDAP directory</span>
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mail.server.server1.hostname&quot;</span><span style="color: #339933;">,</span> userInfo.<span style="color: #660066;">mailhost</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>LDAP directories are a great resource.  What attributes could you store in your corporate server?</p>
<h3>You may also like these:</h3><ul>
<li><a href='http://blog.deanandadie.net/2010/04/an-introduction-to-mission-control-desktop/' rel='bookmark' title='An Introduction To Mission Control Desktop'>An Introduction To Mission Control Desktop</a> <small>What is MCD? MCD (aka AutoConfig) is a script used...</small></li>
<li><a href='http://blog.deanandadie.net/2010/04/setting-user-preferences-with-mission-control-desktop/' rel='bookmark' title='Setting User Preferences with Mission Control Desktop'>Setting User Preferences with Mission Control Desktop</a> <small>A challenge with software Managing software for thousands of users...</small></li>
<li><a href='http://blog.deanandadie.net/2010/05/reading-local-files-with-javascript/' rel='bookmark' title='Reading Local Files With Javascript'>Reading Local Files With Javascript</a> <small>Security Conscious Javascript Normally, javascript does not have access to...</small></li>
</ul>
<p>Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.deanandadie.net/2010/04/ldap-queries-in-mission-control-desktop/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Setting User Preferences with Mission Control Desktop</title>
		<link>http://blog.deanandadie.net/2010/04/setting-user-preferences-with-mission-control-desktop/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=setting-user-preferences-with-mission-control-desktop</link>
		<comments>http://blog.deanandadie.net/2010/04/setting-user-preferences-with-mission-control-desktop/#comments</comments>
		<pubDate>Fri, 16 Apr 2010 21:08:46 +0000</pubDate>
		<dc:creator>Dean</dc:creator>
				<category><![CDATA[Enterprise Software]]></category>
		<category><![CDATA[autoconfig]]></category>
		<category><![CDATA[enterprise]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[mcd]]></category>
		<category><![CDATA[mission control desktop]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[thunderbird]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://blog.deanandadie.net/?p=609</guid>
		<description><![CDATA[A challenge with software Managing software for thousands of users presents a formidable challenge to the system administrator. Publishing corporate policy, using standard environments and providing clear end-user documentation helps. However, it doesn&#8217;t beat automatically doing it right.  This is the power of MCD autoconfig. In an earlier post, I introduced MCD as a way [...]<h3>You may also like these:</h3><ul>
<li><a href='http://blog.deanandadie.net/2010/04/an-introduction-to-mission-control-desktop/' rel='bookmark' title='An Introduction To Mission Control Desktop'>An Introduction To Mission Control Desktop</a> <small>What is MCD? MCD (aka AutoConfig) is a script used...</small></li>
<li><a href='http://blog.deanandadie.net/2010/04/ldap-queries-in-mission-control-desktop/' rel='bookmark' title='LDAP Queries in Mission Control Desktop'>LDAP Queries in Mission Control Desktop</a> <small>Previously, we saw that Mozilla MCD can inspect a user&#8217;s...</small></li>
<li><a href='http://blog.deanandadie.net/2010/05/manufacturing-user-preferences-for-mcd/' rel='bookmark' title='Manufacturing User Preferences For MCD'>Manufacturing User Preferences For MCD</a> <small>Nobody likes boring code Mozilla products like Thunderbird and Firefox...</small></li>
</ul>

Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<h1>A challenge with software</h1>
<p>Managing software for thousands of users presents a formidable challenge to the system administrator. Publishing corporate policy, using standard environments and providing clear end-user documentation helps. However, it doesn&#8217;t beat <strong>automatically</strong> doing it right.  This is the power of <abbr title="Mission Control Desktop">MCD</abbr> autoconfig.</p>
<p>In <a href="http://blog.deanandadie.net/2010/04/an-introduction-to-mission-control-desktop/">an earlier post</a>, I introduced MCD as a way to configure Mozilla products (Firefox, Thunderbird, Prism, etc) and provided background on building them with autoconfig support.  This post covers how to get started with the standard javascript API.  In forthcoming posts I&#8217;ll detail the useful enhancements I built using this API.</p>
<h2>The environment</h2>
<p>First, a quick rehash of my world.  I work in a Solaris shop with over 33,000 users.  <em>Supported users</em> log into a shared Sun Ray server or their personal workstation which mounts a shared NFS directory.  That directory houses the software I support along with about 700 other programs.</p>
<p>While this post is unix-centric, other operating environments that launch managed software can make use of MCD. <a href="http://blog.deanandadie.net/2010/04/an-introduction-to-mission-control-desktop/">See the introductory post</a> for  a little more detail.</p>
<h1>Mozilla Preference System</h1>
<p>Firefox and Thunderbird use a simple preference tree to store all configuration options. Leaves of the tree are strings that store the option&#8217;s value.  For example, the preference <code>browser.startup.homepage</code> is a string containing the URL(s) of Firefox&#8217;s homepage.  <code>mail.forward_message_mode</code> contains an integer indicating how Thunderbird should forward email messages (inline or as an attachment).  You can find every available setting and their values in the <a href="http://www.mozilla.org/support/thunderbird/edit">config editor</a> for Thunderbird and <a href="about:config">about:config</a> in Firefox.</p>
<p>When a user changes his or her preferences the changed values are stored in a file called <code>prefs.js</code> in their home directory. On my MacOS laptop, this is <code>$HOME/Library/Application Support/Firefox/Profiles/kzssiknu.default</code>.</p>
<h1>The Application Programming Interface</h1>
<p>The autoconfig acts on preferences through a javascript API defined in the file <code><a href="http://mxr.mozilla.org/mozilla-central/source/extensions/pref/autoconfig/src/prefcalls.js">MOZILLA_LIB_DIR/defaults/autoconfig/prefcalls.js</a></code>.  I will talk about the most useful in this post and <a href="http://blog.deanandadie.net/2010/04/ldap-queries-in-mission-control-desktop/">cover the LDAP parts</a> of the API later.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Used most often</span>
<span style="color: #003366; font-weight: bold;">function</span> defaultPref<span style="color: #009900;">&#40;</span>prefName<span style="color: #339933;">,</span> value<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">function</span> lockPref<span style="color: #009900;">&#40;</span>prefName<span style="color: #339933;">,</span> value<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">// Sometimes used</span>
<span style="color: #003366; font-weight: bold;">function</span> displayError<span style="color: #009900;">&#40;</span>funcname<span style="color: #339933;">,</span> message<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #003366; font-weight: bold;">function</span> getenv<span style="color: #009900;">&#40;</span><span style="color: #000066;">name</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h2>defaultPref() and lockPref()</h2>
<p>These two functions perform the bulk of work in an autoconfig script.  A default preference setting may be overridden by the user, but a locked preference may not.</p>
<h2>getenv() and displayError()</h2>
<p><code>getenv()</code> acts as you would expect from its name. This function returns the value of an environment variable.  I use it to get <code>$USER</code> and <code>$HOME</code>. <code>displayError()</code> pops up an error message.  It is useful for debugging, but a user should rarely see it.</p>
<h1>Putting it all together</h1>
<p>We now have some basic building blocks to configure thousands of users. Here is a look at a simple autoconfig.js file for Firefox.  These settings will apply to every user.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Catch errors</span>
<span style="color: #000066; font-weight: bold;">try</span>
<span style="color: #009900;">&#123;</span>
   <span style="color: #006600; font-style: italic;">// Set  downloads directory to a folder on the user's desktop</span>
   <span style="color: #003366; font-weight: bold;">var</span> download_dir <span style="color: #339933;">=</span> getenv<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;HOME&quot;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> <span style="color: #3366CC;">&quot;/Desktop/Downloads&quot;</span><span style="color: #339933;">;</span>
   defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;browser.download.defaultFolder&quot;</span><span style="color: #339933;">,</span> download_dir<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;browser.download.dir&quot;</span><span style="color: #339933;">,</span> download_dir<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;browser.download.downloadDir&quot;</span><span style="color: #339933;">,</span> download_dir<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;browser.download.folderList&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>kk
&nbsp;
   <span style="color: #006600; font-style: italic;">// Length of Time to Remember Visited Pages For (Days) - 30</span>
   defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;browser.history_expire_days&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">30</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #006600; font-style: italic;">// Automatically Add 'www.' and '.com' to the Location if a Web Page is Not Found - Enabled</span>
   defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;browser.fixup.alternate.enabled&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #006600; font-style: italic;">// Lock the cache size to 60MB for shared performance</span>
   lockPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;browser.cache.memory.capacity&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">60000</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   lockPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;browser.cache.disk.capacity&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">60000</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #006600; font-style: italic;">// fix memory usage with lots of tabs</span>
   lockPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;browser.sessionhistory.max_total_viewers&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
   <span style="color: #006600; font-style: italic;">// Set animated images to loop once</span>
   defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;image.animation_mode&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;once&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">catch</span><span style="color: #009900;">&#40;</span>e<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>
   displayError<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;autoconfig.js failed&quot;</span><span style="color: #339933;">,</span> e<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h1>Learning preference strings</h1>
<p>Finding the right preference setting or combination of preferences that change the program&#8217;s behavior sometimes presents a challenge.  I use the <a href="http://kb.mozillazine.org/About:config_entries">About:config entries</a> page on the Mozilla Zine knowledge base.  That page also has a pointer to three more resources.</p>
<p>Another technique is to watch your own <code>prefs.js</code> file for changes when you twiddle settings.  Save a copy of prefs.js before flipping a preference.  Immediately quit the application after the change and diff the two files.</p>
<p>[Edit: I wrote up <a href="http://blog.deanandadie.net/2010/04/mapping-firefox-thunderbird-behaviors-to-preference-settings/">an entire post</a> on this subject.]</p>
<h1>Using LDAP and more fun things to do</h1>
<p>In following posts I will cover <a href="http://blog.deanandadie.net/2010/04/ldap-queries-in-mission-control-desktop/">retrieving information from LDAP</a>, better error reporting, <a href="http://blog.deanandadie.net/2010/05/reading-local-files-with-javascript/">reading local files</a> like <code>$HOME/.printers</code>, and simplifying Thunderbird email account management.  Stay tuned.</p>
<h3>You may also like these:</h3><ul>
<li><a href='http://blog.deanandadie.net/2010/04/an-introduction-to-mission-control-desktop/' rel='bookmark' title='An Introduction To Mission Control Desktop'>An Introduction To Mission Control Desktop</a> <small>What is MCD? MCD (aka AutoConfig) is a script used...</small></li>
<li><a href='http://blog.deanandadie.net/2010/04/ldap-queries-in-mission-control-desktop/' rel='bookmark' title='LDAP Queries in Mission Control Desktop'>LDAP Queries in Mission Control Desktop</a> <small>Previously, we saw that Mozilla MCD can inspect a user&#8217;s...</small></li>
<li><a href='http://blog.deanandadie.net/2010/05/manufacturing-user-preferences-for-mcd/' rel='bookmark' title='Manufacturing User Preferences For MCD'>Manufacturing User Preferences For MCD</a> <small>Nobody likes boring code Mozilla products like Thunderbird and Firefox...</small></li>
</ul>
<p>Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.deanandadie.net/2010/04/setting-user-preferences-with-mission-control-desktop/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>An Introduction To Mission Control Desktop</title>
		<link>http://blog.deanandadie.net/2010/04/an-introduction-to-mission-control-desktop/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=an-introduction-to-mission-control-desktop</link>
		<comments>http://blog.deanandadie.net/2010/04/an-introduction-to-mission-control-desktop/#comments</comments>
		<pubDate>Thu, 15 Apr 2010 20:00:34 +0000</pubDate>
		<dc:creator>Dean</dc:creator>
				<category><![CDATA[Enterprise Software]]></category>
		<category><![CDATA[autoconfig]]></category>
		<category><![CDATA[enterprise]]></category>
		<category><![CDATA[firefox]]></category>
		<category><![CDATA[mcd]]></category>
		<category><![CDATA[mission control desktop]]></category>
		<category><![CDATA[mozilla]]></category>
		<category><![CDATA[thunderbird]]></category>
		<category><![CDATA[work]]></category>

		<guid isPermaLink="false">http://blog.deanandadie.net/?p=264</guid>
		<description><![CDATA[What is MCD? MCD (aka AutoConfig) is a script used to programmatically configure Mozilla products such as Firefox and Thunderbird in the enterprise for multiple users.  Part of my job is to ensure 33,385 people have the right settings to check their email and browse the web.  Centralizing their set up with autoconfig removes the [...]<h3>You may also like these:</h3><ul>
<li><a href='http://blog.deanandadie.net/2010/04/setting-user-preferences-with-mission-control-desktop/' rel='bookmark' title='Setting User Preferences with Mission Control Desktop'>Setting User Preferences with Mission Control Desktop</a> <small>A challenge with software Managing software for thousands of users...</small></li>
<li><a href='http://blog.deanandadie.net/2010/04/ldap-queries-in-mission-control-desktop/' rel='bookmark' title='LDAP Queries in Mission Control Desktop'>LDAP Queries in Mission Control Desktop</a> <small>Previously, we saw that Mozilla MCD can inspect a user&#8217;s...</small></li>
<li><a href='http://blog.deanandadie.net/2010/05/reading-local-files-with-javascript/' rel='bookmark' title='Reading Local Files With Javascript'>Reading Local Files With Javascript</a> <small>Security Conscious Javascript Normally, javascript does not have access to...</small></li>
</ul>

Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<h1>What is MCD?</h1>
<p><abbr title="Mission Control Desktop">MCD</abbr> (aka AutoConfig) is a script used to programmatically configure Mozilla products such as Firefox and Thunderbird in the enterprise for multiple users.  Part of my job is to ensure 33,385 people have the right settings to check their email and browse the web.  Centralizing their set up with autoconfig removes the burden from the user.</p>
<h1>Why write about it?</h1>
<p><a href="https://developer.mozilla.org/en/MCD">Documentation on MCD</a> is old, but not exactly out of date.  The basics of autoconfig have not  changed since the age of the Netscape browser.  From trolling  newsgroups, IRC and Google, I know many people use MCD, but share little about the subject. (<a href="http://kaply.com/weblog/2007/03/15/deploying-firefox-2-within-the-enterprise-part-1/">Some</a> <a href="http://ick2.wordpress.com/2008/01/25/control-thunderbird-in-the-enterprise/">do</a>.)  Over the course of my work I wrote object  prototypes, extended error reporting and generally tried to make using  this bit of javascript easier. I want to reach out to the community and  give a little back.</p>
<h1>A quick run-through</h1>
<p>Most people think of javascript as a browser technology. But, MCD has access to <a href="https://developer.mozilla.org/en/XPCOM">XPCOM</a>, a bridge between C++ libraries and javascript, which gives the developer power to poke at Mozilla internals.  When Thunderbird (Firefox, Seamonkey, etc) launches, it executes a  javascript script that makes use of a configuration API.</p>
<p>The autoconfig sets preferences exactly as a user would using <code><a href="about:config">about:config</a></code>. It can also render preferences immutable, locking them down according to corporate policy.  When I inherited the script it was  simply a long string of preference directives with a little LDAP voodoo.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;news.server_change_xaction&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mail.migration.copyMailFiles&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;network.cookie.disableCookieForMailNews&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   lockPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mail.remember_password&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;javascript.allow.mailnews&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mail.addr_book.lastnamefirst&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">1</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mail.toolbars.showbutton.file&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mail.toolbars.showbutton.junk&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mail.forward_message_mode&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mailnews.wraplength&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">72</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mail.wrap_long_lines&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mail.collect_email_address_outgoing&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
defaultPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;mail.collect_email_address_incoming&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p><em>Not the easiest thing to grok.</em></p>
<p>After Thunderbird executes the autoconfig it starts up normally, applying saved user preferences. <code>defaultPref</code> settings are overridden by user preferences, but <code>lockPref</code> are not.</p>
<p>If you want to turn on a proxy server and force SSL in Firefox for <strong>every user</strong> it becomes easy to do:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// Set http proxy to your.server.domain</span>
lockPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;network.proxy.http&quot;</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">&quot;your.server.domain&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #006600; font-style: italic;">// Require and lock SSL</span>
lockPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;network.proxy.ssl&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h1>Details, implementation details</h1>
<p>There are a number of things required to get MCD working.</p>
<h2>Build *zilla (Firefox, Thunderbird, etc) with support</h2>
<p>Your Mozilla product needs to be built with <em>pref extension</em> support. Add this to your <code>.mozconfig</code> file:</p>

<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family:monospace;">ac_add_options --enable-extensions=pref</pre></div></div>

<p>To utilize LDAP (you do want to use LDAP, don&#8217;t you?) check the configure script for:</p>

<div class="wp_syntax"><div class="code"><pre class="sh" style="font-family:monospace;">MOZ_LDAP_XPCOM=1</pre></div></div>

<p>You can check <code><a href="about:buildconfig">about:buildconfig</a></code> in Firefox to see if your build is good to go. While MCD documentation is sparse, the Mozilla Developer&#8217;s Center has plenty of <a href="https://developer.mozilla.org/en/Build_Documentation">build instructions</a>.</p>
<h2>Software distribution</h2>
<p>I work in a Solaris world. Servers and desktops mount a shared NFS directory from a network of servers housing some 735 programs, including Firefox &amp; Thunderbird.  The directory is mounted read-only so average users are not tempted to twiddle with the software.  Although I wrote this paper from a unix perspective the implementation will work in a Linux, Windows, or MacOS environment.  Mounting a shared software repository makes the system robust, however MCD works in a network of stand-alone desktops.</p>
<h2>Breaking .cfg &#8220;encryption&#8221;</h2>
<p>*zilla products first read a javascript configuration file in the lib directory called, for example, <code>firefox.cfg</code>.  In the beginning-time, Mozilla developers chose to ROT-7 encode the file, obscuring its contents from users.  When Netscape 7 came out, they did away with ROT-7 in favor of ROT-13. Many Firefox and Thunderbird .cfg files are still encoded this way using <code><a href="http://www.opennet.ru/docs/RUS/mozilla_authconf/moz-byteshift.pl">moz_byteshift.pl</a></code>.</p>
<p>The rotary encoding is controlled by a setting in <code>$MOZ_LIB_DIR/greprefs/all.js</code>. At packaging time I patch this file, setting encoding to 0.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// ROT-encoding is bad, mmmkay?</span>
pref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;general.config.obscure_value&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #006600; font-style: italic;">// for MCD .cfg files</span></pre></div></div>

<p>This tells *zilla not to ROT-decode the .cfg file.</p>
<p>This shadowy file mojo likely came from the day of stand-alone workstations where users had root access and the software maintainers wanted to have <em>just a little</em> control over Netscape preferences.  Hiding the configuration file&#8217;s location gives you the illusion of control.</p>
<p>Now, the .cfg file is on a read-only mounted partition and nobody on the system has super-user level access. There is little danger of a user skirting corporate policy by turning off autoconfig.</p>
<h2>Pointing *zilla at the autoconfig</h2>
<p>When Firefox starts up it checks for and executes javascript a .cfg file giving it the autoconfig script&#8217;s path.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// $MOZ_LIB_DIR/firefox.cfg</span>
<span style="color: #006600; font-style: italic;">// the output from the obscuration is still more readable than MORK!</span>
lockPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;autoadmin.global_config_url&quot;</span><span style="color: #339933;">,</span><span style="color: #3366CC;">&quot;file:///path/to/firefox,v3.0.17/share/autoconfig.js&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
lockPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;autoadmin.offline_failover&quot;</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
lockPref<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;autoadmin.refresh_interval&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">60</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>I left the <em>MORK</em> comment line in there to remind me how far we&#8217;ve come already.</p>
<p>These directives:</p>
<ul>
<li>Set the autoconfig url</li>
<li>Tell *zilla to automatically fail over to offline mode if online browsing fails</li>
<li>Re-fetch the autoconfig file every 60 minutes</li>
</ul>
<p>Any URL *zilla understands is a valid value for <code>autoadmin.global_config_url</code> meaning you could house the autoconfig script on a web server.</p>
<h2>Away you go</h2>
<p>Now your Mozilla product will read and execute the javascript autoconfig script you indicated.  There you can set or lock application preferences using a specialized XPCOM API.  I will cover the API in <a href="http://blog.deanandadie.net/2010/04/setting-user-preferences-with-mission-control-desktop/">a following post</a>.</p>
<h3>You may also like these:</h3><ul>
<li><a href='http://blog.deanandadie.net/2010/04/setting-user-preferences-with-mission-control-desktop/' rel='bookmark' title='Setting User Preferences with Mission Control Desktop'>Setting User Preferences with Mission Control Desktop</a> <small>A challenge with software Managing software for thousands of users...</small></li>
<li><a href='http://blog.deanandadie.net/2010/04/ldap-queries-in-mission-control-desktop/' rel='bookmark' title='LDAP Queries in Mission Control Desktop'>LDAP Queries in Mission Control Desktop</a> <small>Previously, we saw that Mozilla MCD can inspect a user&#8217;s...</small></li>
<li><a href='http://blog.deanandadie.net/2010/05/reading-local-files-with-javascript/' rel='bookmark' title='Reading Local Files With Javascript'>Reading Local Files With Javascript</a> <small>Security Conscious Javascript Normally, javascript does not have access to...</small></li>
</ul>
<p>Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.deanandadie.net/2010/04/an-introduction-to-mission-control-desktop/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Problematic Decimal Arithmetic in Javascript</title>
		<link>http://blog.deanandadie.net/2008/06/problematic-decimal-arithmetic-in-javascript/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=problematic-decimal-arithmetic-in-javascript</link>
		<comments>http://blog.deanandadie.net/2008/06/problematic-decimal-arithmetic-in-javascript/#comments</comments>
		<pubDate>Sun, 29 Jun 2008 03:09:10 +0000</pubDate>
		<dc:creator>Dean</dc:creator>
				<category><![CDATA[Brewsession]]></category>
		<category><![CDATA[Enterprise Software]]></category>
		<category><![CDATA[javascript]]></category>

		<guid isPermaLink="false">http://blog.brewsession.com/?p=40</guid>
		<description><![CDATA[It is a pretty well known fact that using javascript to add decimals 0.1 with 0.2 does not result in 0.3. [1] Try it yourself with the FireBug console. For the uninitiated, the problem stems from javascript&#8217;s internal representation of numbers. They are actually binary numbers that are usually exact, but sometimes for example, are [...]<h3>You may also like these:</h3><ul>
<li><a href='http://blog.deanandadie.net/2010/05/reading-local-files-with-javascript/' rel='bookmark' title='Reading Local Files With Javascript'>Reading Local Files With Javascript</a> <small>Security Conscious Javascript Normally, javascript does not have access to...</small></li>
<li><a href='http://blog.deanandadie.net/2010/05/manufacturing-user-preferences-for-mcd/' rel='bookmark' title='Manufacturing User Preferences For MCD'>Manufacturing User Preferences For MCD</a> <small>Nobody likes boring code Mozilla products like Thunderbird and Firefox...</small></li>
<li><a href='http://blog.deanandadie.net/2007/06/could-be-an-obstacle/' rel='bookmark' title='Could be an Obstacle'>Could be an Obstacle</a> <small>Hi Reader, I am going to tell you the truth....</small></li>
</ul>

Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p style="text-align: justify;">It is a pretty well known fact that using javascript to add decimals 0.1 with 0.2 does not result in 0.3. <sup>[<a href="#ref1">1</a>]</sup> Try it yourself with the FireBug console.  For the uninitiated, the problem stems from javascript&#8217;s internal representation of numbers.  They are actually binary numbers that are usually exact, but sometimes for example, are <em>0.00000000000000004</em> off.  This is particularly aggravating when writing calculators that rely on js to give accurate results.</p>
<p style="text-align: justify;">In my text inputs I was using toFixed() and some magic HTML attributes to keep decimals nice and clean.  However, this method breaks down when a user enters a number with more significant figures than initially set up or you try to operate on two numbers with different sig figs.  It was probably inevitable that I use a little arithmetic library extending <em>Number</em> to make decimals play nice.</p>
<p style="text-align: justify;">Since javascript is 13 years old I thought it would be a simple thing to find such a library.  I was wrong.  After four days learning, looking and lamenting I had no library.  After putting this one together in about a day and a half I am not surprised that nobody published theirs.  Most of the eleven functions are one-liners, yet it bothers me that there are probably thirty-odd implementations of the this out there and not one found through Google.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #006600; font-style: italic;">// decimal_arithmetic.js</span>
String.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">digitsAfterDecimal</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #003366; font-weight: bold;">var</span> parts <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">split</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;.&quot;</span><span style="color: #339933;">,</span> <span style="color: #CC0000;">2</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #006600; font-style: italic;">// FIXME: Not international!</span>
   <span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span> <span style="color: #339933;">!</span> parts<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #009900;">&#41;</span>
   <span style="color: #009900;">&#123;</span>  parts<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span> <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;&quot;</span><span style="color: #339933;">;</span>  <span style="color: #009900;">&#125;</span>
   <span style="color: #000066; font-weight: bold;">return</span> parts<span style="color: #009900;">&#91;</span><span style="color: #CC0000;">1</span><span style="color: #009900;">&#93;</span>.<span style="color: #660066;">length</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
Number.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">biggerScalar</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>n<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">return</span> n.<span style="color: #660066;">scale</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">&gt;</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">scale</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">?</span> n.<span style="color: #660066;">scale</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">scale</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
Number.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">digitsAfterDecimal</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">toString</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">digitsAfterDecimal</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
Number.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">divided</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>n<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">dividedBy</span><span style="color: #009900;">&#40;</span>n<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
Number.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">dividedBy</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>n<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">multiply</span><span style="color: #009900;">&#40;</span> n.<span style="color: #660066;">reciprocal</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
Number.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">minus</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>n<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">plus</span><span style="color: #009900;">&#40;</span> n.<span style="color: #660066;">negative</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
Number.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">multiply</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>n<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #003366; font-weight: bold;">var</span> s <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">biggerScalar</span><span style="color: #009900;">&#40;</span>n<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span>Math.<span style="color: #660066;">round</span><span style="color: #009900;">&#40;</span>s<span style="color: #339933;">*</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">*</span> Math.<span style="color: #660066;">round</span><span style="color: #009900;">&#40;</span>s<span style="color: #339933;">*</span>n<span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">/</span> <span style="color: #009900;">&#40;</span>s<span style="color: #339933;">*</span>s<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
Number.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">negative</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #339933;">-</span><span style="color: #CC0000;">1</span> <span style="color: #339933;">*</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">;</span>  <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
Number.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">plus</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>n<span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #003366; font-weight: bold;">var</span> s <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">biggerScalar</span><span style="color: #009900;">&#40;</span>n<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span>Math.<span style="color: #660066;">round</span><span style="color: #009900;">&#40;</span>s<span style="color: #339933;">*</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">+</span> Math.<span style="color: #660066;">round</span><span style="color: #009900;">&#40;</span>s<span style="color: #339933;">*</span>n<span style="color: #339933;">,</span><span style="color: #CC0000;">0</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">/</span> s<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
Number.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">reciprocal</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #CC0000;">1</span> <span style="color: #339933;">/</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">;</span>  <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
&nbsp;
Number.<span style="color: #660066;">prototype</span>.<span style="color: #660066;">scale</span> <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#123;</span>  <span style="color: #000066; font-weight: bold;">return</span> Math.<span style="color: #660066;">pow</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">10</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">digitsAfterDecimal</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>  <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Now you can do magical things like:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #CC0000;">0.1</span>.<span style="color: #660066;">plus</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">0.2</span><span style="color: #009900;">&#41;</span>
<span style="color: #006600; font-style: italic;">// 0.3</span></pre></div></div>

<p>yielding the correct results.</p>
<p style="text-align: justify;">I am looking forward to javascript 2.0 when I can override the + operator.  Maybe I won&#8217;t go that far since binary arithmetic is still faster.</p>
<p><a name="ref1"></a>[<a href="#ref1_back">1</a>] <a href="http://groups.google.com/group/comp.lang.javascript/browse_thread/thread/6ebdd806d1a478b7/6a400346d203dcb5">http://groups.google.com/group/comp.lang.javascript/&#8230;</a></p>
<h3>You may also like these:</h3><ul>
<li><a href='http://blog.deanandadie.net/2010/05/reading-local-files-with-javascript/' rel='bookmark' title='Reading Local Files With Javascript'>Reading Local Files With Javascript</a> <small>Security Conscious Javascript Normally, javascript does not have access to...</small></li>
<li><a href='http://blog.deanandadie.net/2010/05/manufacturing-user-preferences-for-mcd/' rel='bookmark' title='Manufacturing User Preferences For MCD'>Manufacturing User Preferences For MCD</a> <small>Nobody likes boring code Mozilla products like Thunderbird and Firefox...</small></li>
<li><a href='http://blog.deanandadie.net/2007/06/could-be-an-obstacle/' rel='bookmark' title='Could be an Obstacle'>Could be an Obstacle</a> <small>Hi Reader, I am going to tell you the truth....</small></li>
</ul>
<p>Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.deanandadie.net/2008/06/problematic-decimal-arithmetic-in-javascript/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Extending acts_as_commentable</title>
		<link>http://blog.deanandadie.net/2008/04/extending-acts_as_commentable/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=extending-acts_as_commentable</link>
		<comments>http://blog.deanandadie.net/2008/04/extending-acts_as_commentable/#comments</comments>
		<pubDate>Sun, 13 Apr 2008 01:48:59 +0000</pubDate>
		<dc:creator>Dean</dc:creator>
				<category><![CDATA[Brewsession]]></category>
		<category><![CDATA[Enterprise Software]]></category>
		<category><![CDATA[aac]]></category>
		<category><![CDATA[aasm]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://blog.brewsession.com/?p=33</guid>
		<description><![CDATA[acts_as_commentable is a nice little ruby on rails plugin. It extends your ActiveRecord classes giving them comments. We are going to use comments on all kinds of things, starting with recipes, of course. However, AAC lacks a critical feature: the ability for users to approve comments before they are displayed. In this post I am [...]<h3>You may also like these:</h3><ul>
<li><a href='http://blog.deanandadie.net/2008/04/all_belong_to-rspec-matcher/' rel='bookmark' title='belong_to RSpec matcher'>belong_to RSpec matcher</a> <small>I was extending acts_as_commentable and needed a good RSpec test...</small></li>
<li><a href='http://blog.deanandadie.net/2007/01/hey-my-first-rails-plugin/' rel='bookmark' title='Hey, my first rails plugin'>Hey, my first rails plugin</a> <small>Ruby on Rails allows for plugins to extend its functionality....</small></li>
<li><a href='http://blog.deanandadie.net/2007/01/of-all-the-things-i-miss/' rel='bookmark' title='Of all the things I miss&#8230;.'>Of all the things I miss&#8230;.</a> <small>Before the death of my drives I had a flexible...</small></li>
</ul>

Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.juixe.com/techknow/index.php/2006/06/18/acts-as-commentable-plugin/">acts_as_commentable</a> is a nice little ruby on rails plugin.  It extends your ActiveRecord classes giving them comments.  We are going to use comments on all kinds of things, starting with recipes, of course.  However, AAC lacks a critical feature: the ability for users to approve comments before they are displayed.  In this post I am going to run through extending AAC using <a href="http://rubyi.st/aasm.html">acts_as_state_machine</a>.</p>
<p>The first thing I did (and do to all the plugins we use) was <a href="http://piston.rubyforge.org/">pistonize</a> the plugin so I could hack on it without fear of getting my changes destroyed.</p>
<p>I start off simply here by adding two states to the Comment model: :pending and :approved.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Comment <span style="color:#006600; font-weight:bold;">&amp;</span>lt; <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  <span style="color:#008000; font-style:italic;"># The first element of this array is the initial state</span>
  VALID_STATES = <span style="color:#006600; font-weight:bold;">&#91;</span> <span style="color:#ff3333; font-weight:bold;">:pending</span>, <span style="color:#ff3333; font-weight:bold;">:approved</span> <span style="color:#006600; font-weight:bold;">&#93;</span>
  acts_as_state_machine <span style="color:#ff3333; font-weight:bold;">:initial</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> VALID_STATES<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span>
&nbsp;
  event <span style="color:#ff3333; font-weight:bold;">:approve</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    transitions <span style="color:#ff3333; font-weight:bold;">:from</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:pending</span>, <span style="color:#ff3333; font-weight:bold;">:to</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:approved</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  VALID_STATES.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>_state<span style="color:#006600; font-weight:bold;">|</span>
    <span style="color:#008000; font-style:italic;"># Define _state as a state</span>
    state _state
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># More code snipped</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Now we are going to write some real code, so here comes a little <a href="http://rspec.info/">RSpec</a>.   aac provides three class methods:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Comment <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  <span style="color:#9966CC; font-weight:bold;">class</span> <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#0000FF; font-weight:bold;">self</span>
  <span style="color:#008000; font-style:italic;"># Helper class method to lookup all comments assigned</span>
  <span style="color:#008000; font-style:italic;"># to all commentable types for a given user.</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> find_comments_by_user<span style="color:#006600; font-weight:bold;">&#40;</span>user<span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># Helper class method to look up all comments for</span>
  <span style="color:#008000; font-style:italic;"># commentable class name and commentable id.</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> find_comments_for_commentable<span style="color:#006600; font-weight:bold;">&#40;</span>commentable_str, commentable_id<span style="color:#006600; font-weight:bold;">&#41;</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># Helper class method to look up a commentable object</span>
  <span style="color:#008000; font-style:italic;"># given the commentable class name and id</span>
  <span style="color:#9966CC; font-weight:bold;">def</span> find_commentable<span style="color:#006600; font-weight:bold;">&#40;</span>commentable_str, commentable_id<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Since it didn&#8217;t come with Test::Unit or RSpec tests I wrote up some test for these methods.</p>
</pre>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">describe Comment, <span style="color:#996600;">&quot;class methods&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  fixtures <span style="color:#ff3333; font-weight:bold;">:comments</span>, <span style="color:#ff3333; font-weight:bold;">:recipes</span>, <span style="color:#ff3333; font-weight:bold;">:users</span>
  it <span style="color:#996600;">&quot;should find comments by user&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    Comment.<span style="color:#9900CC;">find_comments_by_user</span><span style="color:#006600; font-weight:bold;">&#40;</span> comments<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:comment_one</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">user</span> <span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">should</span> all_belong_to<span style="color:#006600; font-weight:bold;">&#40;</span> comments<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:comment_one</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">user</span> <span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># This could be more specific</span>
  it <span style="color:#996600;">&quot;should find comments for a particular class&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    Comment.<span style="color:#9900CC;">find_comments_for_commentable</span><span style="color:#006600; font-weight:bold;">&#40;</span> Comments<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:comment_one</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">commentable_type</span>, comments<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:comment_one</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">commentable_id</span> <span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">should</span> be_an_instance_of<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC0066; font-weight:bold;">Array</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  it <span style="color:#996600;">&quot;should find all comments for a particular class&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    <span style="color:#008000; font-style:italic;"># I happen to know that comment_one is a recipe comment</span>
    Comment.<span style="color:#9900CC;">find_commentable</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#996600;">&quot;Recipe&quot;</span>, comments<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:comment_one</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">commentable_id</span> <span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">should</span> be_an_instance_of<span style="color:#006600; font-weight:bold;">&#40;</span>Recipe<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>If you are confused by <em>should all_belong_to</em> then you should check out my <a href="http://blog.brewsession.com/2008/04/09/all_belong_to-rspec-matcher/">previous post</a>. With these specs out of the way we can go on to adding more new code.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  it <span style="color:#996600;">&quot;should find approved comments by user&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    Comment.<span style="color:#9900CC;">find_approved_comments_by_user</span><span style="color:#006600; font-weight:bold;">&#40;</span> comments<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:comment_one</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">user</span> <span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">should</span> all_be_in_state<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;approved&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  it <span style="color:#996600;">&quot;should find pending comments by user&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    Comment.<span style="color:#9900CC;">find_pending_comments_by_user</span><span style="color:#006600; font-weight:bold;">&#40;</span> comments<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:comment_one</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">user</span> <span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">should</span> all_be_in_state<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;pending&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>Now, normally you would write one spec at a time, but I think I would bore my readers, so I combined these two.  Also take note that I am using another custom RSpec matcher <em>all_be_in_state()</em>.  It looks a lot like <em>all_belong_to()</em>, so I leave its implementation as an exercise to the reader (unless I can get another blog post out of it). To get these tests to pass I add a few lines of code:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">  VALID_STATES.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>_state<span style="color:#006600; font-weight:bold;">|</span>
    <span style="color:#008000; font-style:italic;"># Define _state as a state</span>
    state _state
&nbsp;
    <span style="color:#008000; font-style:italic;"># Add Comment.find__comments methods</span>
    <span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#9966CC; font-weight:bold;">class</span> <span style="color:#006600; font-weight:bold;">&amp;</span>lt;<span style="color:#006600; font-weight:bold;">&amp;</span>lt; <span style="color:#0000FF; font-weight:bold;">self</span>; <span style="color:#0000FF; font-weight:bold;">self</span>; <span style="color:#9966CC; font-weight:bold;">end</span> <span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">instance_eval</span> <span style="color:#9966CC; font-weight:bold;">do</span>
      define_method <span style="color:#996600;">&quot;find_#{_state}_comments_by_user&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>_user<span style="color:#006600; font-weight:bold;">|</span>
        find_in_state<span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#ff3333; font-weight:bold;">:all</span>, _state, <span style="color:#ff3333; font-weight:bold;">:conditions</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;user_id = ?&quot;</span>, _user.<span style="color:#9900CC;">id</span><span style="color:#006600; font-weight:bold;">&#93;</span>, <span style="color:#ff3333; font-weight:bold;">:order</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;created_at DESC&quot;</span> <span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>I am not a <em>method_missing</em> kind of guy, and prefer the dynamic-method metaprogramming style.  This lot of code defines class methods at runtime that find Comments in specific states.  I am actually using <a href="http://whytheluckystiff.net/articles/seeingMetaclassesClearly.html">whytheluckystiff's metaid</a> to hide some of the meta-junk, but I thought I should spell it out here for clarity.</p>
<p>Well, now we have a Comment class with two states and code to limit finds to cmments in a specific state.  Right now, that is all I have.  Here is the full code for the Comment class and the RSpec.  You will see another custom RSpec matcher here, <a href="http://tuples.us/2007/10/23/if-you-arent-writing-matchers-you-arent-using-rspec/"><em>require_a()</em></a>.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> Comment <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># The first element of this array is the initial state</span>
  VALID_STATES = <span style="color:#006600; font-weight:bold;">&#91;</span> <span style="color:#ff3333; font-weight:bold;">:pending</span>, <span style="color:#ff3333; font-weight:bold;">:approved</span> <span style="color:#006600; font-weight:bold;">&#93;</span>
&nbsp;
  acts_as_state_machine <span style="color:#ff3333; font-weight:bold;">:initial</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> VALID_STATES<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">0</span><span style="color:#006600; font-weight:bold;">&#93;</span>
&nbsp;
  belongs_to <span style="color:#ff3333; font-weight:bold;">:commentable</span>, <span style="color:#ff3333; font-weight:bold;">:polymorphic</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span>
  belongs_to <span style="color:#ff3333; font-weight:bold;">:user</span>
&nbsp;
  event <span style="color:#ff3333; font-weight:bold;">:approve</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    transitions <span style="color:#ff3333; font-weight:bold;">:from</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:pending</span>, <span style="color:#ff3333; font-weight:bold;">:to</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#ff3333; font-weight:bold;">:approved</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  validates_associated <span style="color:#ff3333; font-weight:bold;">:user</span>
  validates_presence_of <span style="color:#ff3333; font-weight:bold;">:comment</span>, <span style="color:#ff3333; font-weight:bold;">:commentable_id</span>, <span style="color:#ff3333; font-weight:bold;">:commentable_type</span>, <span style="color:#ff3333; font-weight:bold;">:state</span>,                           <span style="color:#ff3333; font-weight:bold;">:user_id</span>
&nbsp;
  VALID_STATES.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>_state<span style="color:#006600; font-weight:bold;">|</span>
    <span style="color:#008000; font-style:italic;"># Define _state as a state</span>
    state _state
&nbsp;
    <span style="color:#008000; font-style:italic;"># Add Comment.find_&lt;state&gt;_comments methods</span>
    meta_def <span style="color:#996600;">&quot;find_#{_state}_comments_by_user&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>_user<span style="color:#006600; font-weight:bold;">|</span>
      find_in_state<span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#ff3333; font-weight:bold;">:all</span>, _state, <span style="color:#ff3333; font-weight:bold;">:conditions</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;user_id = ?&quot;</span>, _user.<span style="color:#9900CC;">id</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
                     <span style="color:#ff3333; font-weight:bold;">:order</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;created_at DESC&quot;</span> <span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">class</span> <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#0000FF; font-weight:bold;">self</span>
&nbsp;
    <span style="color:#008000; font-style:italic;"># Helper class method to look up a commentable object</span>
    <span style="color:#008000; font-style:italic;"># given the commentable class name and id</span>
    <span style="color:#9966CC; font-weight:bold;">def</span> find_commentable<span style="color:#006600; font-weight:bold;">&#40;</span>commentable_str, commentable_id<span style="color:#006600; font-weight:bold;">&#41;</span>
      commentable_str.<span style="color:#9900CC;">constantize</span>.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span>commentable_id<span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#008000; font-style:italic;"># This could be refactored into find_&lt;state&gt;_comments_by_user (somehow)</span>
    <span style="color:#9966CC; font-weight:bold;">def</span> find_comments_by_user<span style="color:#006600; font-weight:bold;">&#40;</span>_user<span style="color:#006600; font-weight:bold;">&#41;</span>
      find<span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#ff3333; font-weight:bold;">:all</span>, <span style="color:#ff3333; font-weight:bold;">:conditions</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">&quot;user_id = ?&quot;</span>, _user.<span style="color:#9900CC;">id</span><span style="color:#006600; font-weight:bold;">&#93;</span>,
            <span style="color:#ff3333; font-weight:bold;">:order</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;created_at DESC&quot;</span> <span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
    <span style="color:#008000; font-style:italic;"># Helper class method to look up all comments for</span>
    <span style="color:#008000; font-style:italic;"># commentable class name and commentable id.</span>
    <span style="color:#9966CC; font-weight:bold;">def</span> find_comments_for_commentable<span style="color:#006600; font-weight:bold;">&#40;</span>commentable_str, commentable_id<span style="color:#006600; font-weight:bold;">&#41;</span>
      find<span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#ff3333; font-weight:bold;">:all</span>,
            <span style="color:#ff3333; font-weight:bold;">:conditions</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006600; font-weight:bold;">&#91;</span> <span style="color:#996600;">&quot;commentable_type = ? and commentable_id = ?&quot;</span>,
                             commentable_str, commentable_id <span style="color:#006600; font-weight:bold;">&#93;</span>,
            <span style="color:#ff3333; font-weight:bold;">:order</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;created_at DESC&quot;</span> <span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
end<span style="color:#006600; font-weight:bold;">&lt;/</span>state<span style="color:#006600; font-weight:bold;">&gt;</span></pre></div></div>


<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">dirname</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF; font-weight:bold;">__FILE__</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#006600; font-weight:bold;">+</span> <span style="color:#996600;">'/../../../../spec/spec_helper'</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">module</span> CommentSpecHelper
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
describe Comment <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
  fixtures <span style="color:#ff3333; font-weight:bold;">:comments</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">include</span> CommentSpecHelper
&nbsp;
  before<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:each</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    <span style="color:#0066ff; font-weight:bold;">@comment</span> = Comment.<span style="color:#9900CC;">new</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  it <span style="color:#996600;">&quot;should start out in pending state&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    <span style="color:#0066ff; font-weight:bold;">@comment</span>.<span style="color:#9900CC;">state</span>.<span style="color:#9900CC;">should</span> == <span style="color:#996600;">&quot;pending&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  it <span style="color:#996600;">&quot;sould transition to approved&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    <span style="color:#0066ff; font-weight:bold;">@comment</span> = comments<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:pending_comment</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#0066ff; font-weight:bold;">@comment</span>.<span style="color:#9900CC;">approve</span>!
    <span style="color:#0066ff; font-weight:bold;">@comment</span>.<span style="color:#9900CC;">state</span>.<span style="color:#9900CC;">should</span> == <span style="color:#996600;">&quot;approved&quot;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  it <span style="color:#996600;">&quot;should require a comment&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    <span style="color:#0066ff; font-weight:bold;">@comment</span>.<span style="color:#9900CC;">should</span> require_a<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:comment</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  it <span style="color:#996600;">&quot;should require a commentable_id&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    <span style="color:#0066ff; font-weight:bold;">@comment</span>.<span style="color:#9900CC;">should</span> require_a<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:commentable_id</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  it <span style="color:#996600;">&quot;should require a commentable_type&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    <span style="color:#0066ff; font-weight:bold;">@comment</span>.<span style="color:#9900CC;">should</span> require_a<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:commentable_type</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  it <span style="color:#996600;">&quot;should require a state&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    <span style="color:#0066ff; font-weight:bold;">@comment</span>.<span style="color:#9900CC;">should</span> require_a<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:state</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  it <span style="color:#996600;">&quot;should require a user_id&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    <span style="color:#0066ff; font-weight:bold;">@comment</span>.<span style="color:#9900CC;">should</span> require_a<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:user_id</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
describe Comment, <span style="color:#996600;">&quot;class methods&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
&nbsp;
  fixtures <span style="color:#ff3333; font-weight:bold;">:comments</span>, <span style="color:#ff3333; font-weight:bold;">:recipes</span>, <span style="color:#ff3333; font-weight:bold;">:users</span>
&nbsp;
  it <span style="color:#996600;">&quot;should find all comments for a particular class&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    <span style="color:#008000; font-style:italic;"># I happen to know that comment_one is a recipe comment</span>
    Comment.<span style="color:#9900CC;">find_commentable</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#996600;">&quot;Recipe&quot;</span>, comments<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:comment_one</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">commentable_id</span> <span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">should</span> be_an_instance_of<span style="color:#006600; font-weight:bold;">&#40;</span>Recipe<span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  it <span style="color:#996600;">&quot;should find comments by user&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    Comment.<span style="color:#9900CC;">find_comments_by_user</span><span style="color:#006600; font-weight:bold;">&#40;</span> comments<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:comment_one</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">user</span> <span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">should</span> all_belong_to<span style="color:#006600; font-weight:bold;">&#40;</span> comments<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:comment_one</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">user</span> <span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  it <span style="color:#996600;">&quot;should find approved comments by user&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    Comment.<span style="color:#9900CC;">find_approved_comments_by_user</span><span style="color:#006600; font-weight:bold;">&#40;</span> comments<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:comment_one</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">user</span> <span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">should</span> all_be_in_state<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;approved&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  it <span style="color:#996600;">&quot;should find pending comments by user&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    Comment.<span style="color:#9900CC;">find_pending_comments_by_user</span><span style="color:#006600; font-weight:bold;">&#40;</span> comments<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:comment_one</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">user</span> <span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">should</span> all_be_in_state<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;pending&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
  <span style="color:#008000; font-style:italic;"># This could be more specific</span>
  it <span style="color:#996600;">&quot;should find comments for a particular class&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
    Comment.<span style="color:#9900CC;">find_comments_for_commentable</span><span style="color:#006600; font-weight:bold;">&#40;</span> comments<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:comment_one</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">commentable_type</span>, comments<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:comment_one</span><span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">commentable_id</span> <span style="color:#006600; font-weight:bold;">&#41;</span>.<span style="color:#9900CC;">should</span> be_an_instance_of<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC0066; font-weight:bold;">Array</span><span style="color:#006600; font-weight:bold;">&#41;</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>--Dean</p>
<h3>You may also like these:</h3><ul>
<li><a href='http://blog.deanandadie.net/2008/04/all_belong_to-rspec-matcher/' rel='bookmark' title='belong_to RSpec matcher'>belong_to RSpec matcher</a> <small>I was extending acts_as_commentable and needed a good RSpec test...</small></li>
<li><a href='http://blog.deanandadie.net/2007/01/hey-my-first-rails-plugin/' rel='bookmark' title='Hey, my first rails plugin'>Hey, my first rails plugin</a> <small>Ruby on Rails allows for plugins to extend its functionality....</small></li>
<li><a href='http://blog.deanandadie.net/2007/01/of-all-the-things-i-miss/' rel='bookmark' title='Of all the things I miss&#8230;.'>Of all the things I miss&#8230;.</a> <small>Before the death of my drives I had a flexible...</small></li>
</ul>
<p>Related posts brought to you by <a href='http://yarpp.org'>Yet Another Related Posts Plugin</a>.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.deanandadie.net/2008/04/extending-acts_as_commentable/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

