<?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>my dog boris &#187; Tech Tidbits</title>
	<atom:link href="http://www.mydogboris.com/category/tech-tidbits/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.mydogboris.com</link>
	<description>perspectives from a hands on technology executive</description>
	<lastBuildDate>Fri, 09 Sep 2011 19:40:40 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3</generator>
		<item>
		<title>Contact Synchronization Solution?</title>
		<link>http://www.mydogboris.com/2010/01/contact-sync/</link>
		<comments>http://www.mydogboris.com/2010/01/contact-sync/#comments</comments>
		<pubDate>Mon, 11 Jan 2010 23:46:55 +0000</pubDate>
		<dc:creator>Dan Hayes</dc:creator>
				<category><![CDATA[Tech Tidbits]]></category>

		<guid isPermaLink="false">http://www.mydogboris.com/?p=81</guid>
		<description><![CDATA[So I stumbled into Soocial while I was doing a search related to synchronizing contacts across multiple applications.  Soocial appears to be a simple alternative to something like Plaxo, which is trying to expand into the whole social networking craze. I don&#8217;t need or want another social networking application.  I use LinkedIn for my professional [...]]]></description>
			<content:encoded><![CDATA[<p>So I stumbled into <a href="http://www.soocial.com">Soocial</a> while I was doing a search related to synchronizing contacts across multiple applications.  Soocial appears to be a simple alternative to something like <a href="http://www.plaxo.com">Plaxo</a>, which is trying to expand into the whole social networking craze. I don&#8217;t need or want another social networking application.  I use <a href="http://www.linkedin.com">LinkedIn</a> for my professional networking and will most likely add a <a href="http://www.facebook.com">Facebook</a> account sometime this year for more social networking (is there a difference anymore?).  I just want to synchronize my contacts and calendars across multiple applications/services as simply and unobtrusively as possible.</p>
<p>Here is what I am trying to do.  I am sure I am not the only one out there trying to do the same thing.  In our organization we use Exchange.  This is the keeper of my office calendar which syncs perfectly with my iPhone via ActiveSync.  My wife and I also use our My Dog Boris Google Apps account for our family calendaring and personal email.  She also uses Outlook/Exchange at her office.  We both use the <a href="http://www.google.com/apps/intl/en/business/outlook_sync.html">Google Calendar Sync plug in for Outlook</a> to synchronize our office calendars with dedicated calendars set up in Google Apps.  On Google Apps, we can view each others office calendar (read only) as well as make entries to a 3rd calendar that we&#8217;ve set up for our Family events.  All that is working perfectly with few glitches.  Google Calendar Sync works in the background and rarely causes any problems (thanks Google).</p>
<p>Of course, most of you know that I am a Mac-guy and I do as much as I can (including all my development work) on the Macbook that usually sits next to my office PC.  When Snow Leopard came out last year, Active Sync was included in the operating system.  It allowed me to synchronize my mail, contacts, and calendars with Exchange.  Of course, Mac OS X has had support for syncing contacts and calendars with Google for some time.  I thought my prayers had been answered.  Well, hold your horses.  You see, while there is support for multiple calendars in iCal and multiple account in Address Book, they remain completely isolated from each other.   You cannot sync your Exchange Contact file with your &#8220;On My Mac&#8221; address book account that syncs with Gmail.  Hmmm.</p>
<p>The reason this isn&#8217;t an issue for calendaring is because of the Google Calendar Sync plug in for Outlook.  When this runs in the background in Windows, it is actually mapping from one domain (Exchange) to another (Gmail).  The Google Sync tool doesn&#8217;t (yet) support contact syncing.  There are other plug ins available that have support for syncing contacts between Outlook and Gmail but I have found them to be more trouble than they are worth.  I have tried both <a href="http://oggsync.com/">OggSync</a> and <a href="http://www.daveswebsite.com/software/gsync/index.shtml">gSyncit</a> but I ended up scrapping them as they just seemed buggy to me.  Plus, they weren&#8217;t free (not a good combination, IMHO).</p>
<p>Enter Soocial.  So while it is a little more intrusive than I would like (a third party having access to my contacts plus another point of failure), it seemed really simple and wasn&#8217;t trying to get me to join another social networking cult.  After setting up the free account (is there any other type on Soocial?), I added connectors to my Gmail account and downloaded the plug-in for Outlook.  Note there are a bunch of warnings about this being in beta but I went for it anyway.  I will confirm that there are some issues that I hope will be worked out (read on).  I also didn&#8217;t need to add a connector to my Macbook Address Book since I was already successfully syncing with Gmail as above.  Gmail would already act as that conduit for me.  After a little bit of trouble with the Outlook plug-in I was able to get everything working&#8230; well almost.</p>
<p>After an initial sync with Outlook I was getting duplicates in my Outlook contacts and on my iPhone.  However, my contacts on the Soocial website appeared to be very clean (no dupes).  So what I decided to do was make a backup .vcf file from the tools available on the Soocial site (just to be safe).  Then I deleted all my Outlook contacts (whereby removing them from Exchange and my iPhone).  I also deleted all my Gmail contacts (after making another backup from the Gmail site).  Next I initiated a manual sync with Gmail and after that appeared to successfully re-populate my Google contacts from my Soocial &#8220;master file&#8221;, I initiated a sync from the Soocial plug-in inside Outlook.  After a lengthy process (mine took almost 30 minutes), my contacts re-appeared in Outlook with no duplicates!  Now when I make a change to my contacts in either (1) the Soocial website, (2) Gmail, (3) Outlook, (4) iPhone, or (5) the Address Book on my Mac THEY WILL ALL BE SYNCHRONIZED.  Of course, there is some latency depending on the client you are using to update.  Exchange only gets notification of contact updates from Gmail or Soocial if Outlook is running and the plug in is syncing every so often (and visa versa).  I think I can live with that.</p>
<p>All is good now in contact synchronization land (at least until Soocial crashes or runs out of money).  Now if I can only get visibility to my Family and wife&#8217;s calendar (through Google Apps) in Outlook and on my iPhone.  I recall having that visibility when I was using gSyncit (it supports multiple calendar syncing between Google and Outlook).  However, I just couldn&#8217;t live with the hassle and bugs in the application.  Plus, I like the comfort of knowing that Google wrote the application that is trying to sync my calendars in Google.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mydogboris.com/2010/01/contact-sync/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Using JQuery &#8216;data&#8217; feature to detect form changes</title>
		<link>http://www.mydogboris.com/2009/10/using-jquery-data-feature-to-detect-form-changes/</link>
		<comments>http://www.mydogboris.com/2009/10/using-jquery-data-feature-to-detect-form-changes/#comments</comments>
		<pubDate>Thu, 15 Oct 2009 16:25:15 +0000</pubDate>
		<dc:creator>Dan Hayes</dc:creator>
				<category><![CDATA[Tech Tidbits]]></category>

		<guid isPermaLink="false">http://www.mydogboris.com/?p=60</guid>
		<description><![CDATA[You may be familiar with using javascript events such as &#8216;onblur&#8217; or &#8216;keyup&#8217; to fire handler methods or even ajax methods to update UI elements. One of the challenges I faced recently was detecting changes in a web form so that I could prevent the user from navigating away from the page without first checking [...]]]></description>
			<content:encoded><![CDATA[<p>You may be familiar with using javascript events such as &#8216;onblur&#8217; or &#8216;keyup&#8217; to fire handler methods or even ajax methods to update UI elements.  One of the challenges I faced recently was detecting changes in a web form so that I could prevent the user from navigating away from the page without first checking if they want to save their changes.  This is no big deal in a desktop app but a bit more challenging in a browser.  Thankfully, <a href="http://jquery.com">JQuery</a> comes to the rescue again.  This time with the help of the &#8216;data&#8217; property.  Here is how it works.</p>
<p>Let&#8217;s say I have a form with an id of &#8216;my_form&#8217; and I have a number of input fields, including select lists, text, and textarea tags.  By simply assigning a class of &#8216;editable&#8217; (you can use whatever you want), I can detect when a form has changed and enable the save (submit) button accordingly.  The magic happens in standard JQuery document ready function. Here is the entire javascript listing:</p>
<pre><code>var formChanged = false;

$(document).ready(function() {
     $('#my_form input[type=text].editable, #my_form textarea.editable').each(function (i) {
          $(this).data('initial_value', $(this).val());
     });

     $('#my_form input[type=text].editable, #my_form textarea.editable').keyup(function() {
          if ($(this).val() != $(this).data('initial_value')) {
               handleFormChanged();
          }
     });

     $('#my_form .editable').bind('change paste', function() {
          handleFormChanged();
     });

     $('.navigation_link').bind("click", function () {
          return confirmNavigation();
     });
});

function handleFormChanged() {
     $('#save_or_update').attr("disabled", false);
     formChanged = true;
}

function confirmNavigation() {
     if (formChanged) {
          return confirm('Are you sure? Your changes will be lost!');
     } else {
          return true;
     }
}
</code></pre>
<p>What is going on here? First, a standard variable &#8216;formChanged&#8217; is set to false when the page is loaded. In the JQuery document load function each text and textarea form element with a class of &#8216;editable&#8217; is collected and the JQuery &#8216;data&#8217; property (keyed with &#8216;initial_value&#8217;) is set to the values that were populated upon form load (likely using your favorite server side framework).  This is a HUGE feature that JQuery added.  It allows a ton of flexibility as we will see.</p>
<p>Next, I bind the keyup function to examine the contents of the text or textarea input and compare it against its respective &#8216;initial_value&#8217;.  If it is different, I call a simple &#8216;handleFormChanged()&#8217; function to enable the submit button (id = &#8216;save_or_update&#8217;).  Binding the keyup event in this way allows me to not wait until the onblur event to check for changes.  The onblur event is what triggers the normal &#8216;change&#8217; event in JQuery.  However, I also want to bind the &#8216;change&#8217; and &#8216;paste&#8217; events to any editable events as the user may use the cut and paste features to change the text or textarea values (here I simply assume a paste is always changing the value and don&#8217;t feel a need to check).  The change also picks up any change to a select list or a checkbox.  Of course, you should confirm that all your UI widgets are adequately covered by the various event handlers in JQuery.</p>
<p>The next JQuery bind is to any clickable component that is classed with &#8216;navigation_link&#8217; (again, my arbitrary terminology).  I added this class to the submit button, as well as all my links in the navigation.  You could also simply use a &#8216;a&#8217; selector to catch everything but I wanted precise control over which links triggered the action.  The &#8216;confirmNavigation()&#8217; method simply examines the value of the formChanged variable to know whether to confirm that the user wishes to navigate away from the form page.</p>
<p>The users really love the way this helps prevent losing changes by accident.  What is even nicer is that this code could exist in a javascript include and provide this functionality through your application.  Perhaps you could just simply assign a class attribute to the form such as &#8216;checked_form&#8217; and adjust your JQuery selectors accordingly, even keeping you from having to assign an &#8216;editable&#8217; class to each of the input elements.   Then, just make sure you mark your navigation links and/or buttons with a class attribute such as &#8216;navigation_link&#8217;, or if you want everything checked, just adjust your selectors to pick up every anchor tag and every button.</p>
<p>JQuery is really a huge time saver.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mydogboris.com/2009/10/using-jquery-data-feature-to-detect-form-changes/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Capistrano Bliss</title>
		<link>http://www.mydogboris.com/2009/06/capistrano-bliss/</link>
		<comments>http://www.mydogboris.com/2009/06/capistrano-bliss/#comments</comments>
		<pubDate>Fri, 12 Jun 2009 19:31:45 +0000</pubDate>
		<dc:creator>Dan Hayes</dc:creator>
				<category><![CDATA[Tech Tidbits]]></category>

		<guid isPermaLink="false">http://www.mydogboris.com/?p=54</guid>
		<description><![CDATA[I&#8217;ve recently had the opportunity to build an application for a startup using Rails.  While this certainly wasn&#8217;t my first experience with Rails, it would my first exposure to administering a Rails application in a soon to be production environment.  Since I am inherently lazy (like most techies), I wanted to make sure I had [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve recently had the opportunity to build an application for a startup using Rails.  While this certainly wasn&#8217;t my first experience with Rails, it would my first exposure to administering a Rails application in a soon to be production environment.  Since I am inherently lazy (like most techies), I wanted to make sure I had an automated process for pushing out changes and re-deploying the application.  After all, startups are notorious for rapid fire modifications based upon early feedback loops.  This seemed like a great opportunity to try out <a href="http://www.capify.org/">Capistrano</a>.  </p>
<p>Capistrano is a build automation tool, similar to Ant.  However, while Ant doesn&#8217;t make many assumptions about what (or how) your building and deploying, Capistrano makes a lot of assumptions (sound familiar?).  As a result, Capistrano can quickly become the centerpiece of your deployment process.  Capistrano leverages SSH to execute remote shell commands on one or more of your deployment servers, checking out code from your SCM (usually SVN or git), managing a directory structure of releases and creating symbolic links to your current release.  It will even help you remotely start and stop your app and erect a maintenance page! All of this is accomplished via Capistrano Tasks and Recipes that are scoped by a namespace to avoid conflicts.  Of course, you can easily create your own Recipes, but I didn&#8217;t have the need in my particular situation. The out of the box deploy script generated by Capistrano for me was more than adequate, although I did make some tweaks (see below) based on the fact that I was using Passenger (i.e. mod_rails) in my Apache configuration on the deployment server.    Here is what I had to do to get my new application up and running with Capistrano:</p>
<h4>Installation</h4>
<p>Installation was a snap.  Capistrano is ONLY installed on your development machine.  It is a simple gem install:</p>
<p><code><br />
$ sudo gem install capistrano<br />
...(output omitted)...<br />
Successfully installed capistrano-2.5.5<br />
</code></p>
<h4>Setting up my project</h4>
<p>Next I navigated to my rails project root and executed the following command:<br />
<code><br />
$ capify .<br />
[add] writing './Capfile'<br />
[add] writing './config/deploy.rb'<br />
[done] capified!<br />
</code><br />
I&#8217;ve been capified!  Well that wasn&#8217;t too painful.</p>
<h4>Tweaking for environment</h4>
<p>After capification (?) I updated the ./config/deploy.rb file generated by Capistrano.  Mine looked similar to this (some values changed to protect the innocent).  Note that I also put some nice comment dividers to help organize the information. They are not required:</p>
<pre>
#############################################################
#	Application
#############################################################

set :application, "myrailsapp"
set :deploy_to, "/var/www/#{application}"
set :rails_env, "production"

#############################################################
#	Settings
#############################################################

default_run_options[:pty] = true
set :use_sudo, true

#############################################################
#	Servers
#############################################################

set :user, "some_user_name"
set :domain, "yourdomain.com"
server domain, :app, :web
role :db, domain, :primary => true

#############################################################
#	Subversion
#############################################################

set :repository,  "svn+ssh://www.yourdomain.com/repos/myrailsapp/trunk"
set :svn_username, "svn_user_name"
set :svn_password, "svn_password"
set :checkout, "export"

#############################################################
# Passenger
#############################################################

namespace :deploy do
  task :start, :roles => :app do
    run "touch #{current_release}/tmp/restart.txt"
  end

  task :stop, :roles => :app do
    # Do nothing.
  end

  desc "Restart Application"
  task :restart, :roles => :app do
    run "touch #{current_release}/tmp/restart.txt"
  end
end
</pre>
<p>Everything is pretty self explanatory.  However, at the risk of pointing out the obvious&#8230; In the Application related properties, set the name of the rails app.  This name can be anything but it will be used in the path to the deployment location in the next line so you may want to put some thought into this. I set the rails environment to &#8216;production&#8217;.  I didn&#8217;t mess with the Settings related properties as I knew I would need to execute commands on the remote server as sudo.  The server related properties include the user name that will attempt the SSH session.  Domain could be something that resolves via DNS or an IP address, of course. I also needed to update the SVN properties with the path to my repository and my username/password.</p>
<p>For the most part, everything up to this point was out-of-the-box.  All I needed to do was adjust some user names, passwords, and server paths.  The last section (Recipe?) I added to accommodate the fact that I was using Passenger (i.e. mod_rails) on my Apache-based server as the glue between Apache and Ruby/Rails.  This is really simple.  The namespace used by Capistrano is &#8216;deploy&#8217;.  All I am doing is overriding the default implementation of the :start, :stop, and :restart tasks.  In the case of Passenger, all that is necessary is to &#8220;touch&#8221; a special file in the {RAILS_ROOT}/tmp directory called restart.txt.  Passenger monitors this file and will reload when it sees that it has been modified.</p>
<p>That&#8217;s just about it.  Well, almost.  You&#8217;ll want to perform the task &#8216;cap deploy:setup&#8217; from your RAILS_ROOT directory (again, on your development machine) first.  This will set up a small directory structure under your target deployment location (adding directories &#8216;releases&#8217;, and &#8216;shared&#8217;).  I had a small problem with permissions on the server so I had to manually SSH to update the file permissions in my target directory (i.e. &#8216;/var/www/myrailsapp&#8217; directory to allow for writing.  That was the only glitch for me and it only had to be done once.</p>
<h4>Deployment</h4>
<p>Next, I executed the following commands:<br />
<code><br />
$ cap deploy:cold<br />
...(output ommitted) [be prepared to respond to the SSH password and sudo password prompt]...<br />
</code><br />
This launched a remote SSH session, checked out the latest version from SVN, built a new timestamp directory under the &#8216;releases&#8217; subdirectory and created a symbolic link called &#8216;current&#8217; to the current release.  This way, my Document Root setting in my Apache configuration could simply refer to the &#8216;/var/www/myrailsapp/current/public&#8217; directory (don&#8217;t forget that you need to include the public directory in the Apache config).  Future releases could be done with:<br />
<code><br />
$ cap deploy<br />
</code><br />
&#8230;from the RAILS_ROOT directory of the development machine and voila.  It&#8217;s automation bliss.  There are loads of out of the box tasks (execute &#8216;cap &#8211;tasks&#8217; to see the full list) to help you in the deployment and management process.  A couple that I have been using a lot are &#8216;cap deploy:web:disable&#8217; and &#8216;cap deploy:web:enable&#8217;.  This will have Capistrano put up a maintenance page when you &#8216;disable&#8217; your website for maintenance and remove it when it is back online &#8216;enabled&#8217;.  However, be sure to update your Apache mod_rewrite rules to enable this.  Here is what I added to my Apache virtual host configuration:<br />
<code><br />
RewriteCond %{REQUEST_URI} !\.(css|jpg|png)$<br />
RewriteCond %{DOCUMENT_ROOT}/system/maintenance.html -f<br />
RewriteCond %{SCRIPT_FILENAME} !maintenance.html<br />
RewriteRule ^.*$ /system/maintenance.html [L]<br />
</code></p>
<p>My experience was very positive with Capistrano thanks to the power of opinionated software.  Your mileage may vary.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.mydogboris.com/2009/06/capistrano-bliss/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

