<?xml version='1.0' encoding='utf-8' ?>
<feed xmlns='http://www.w3.org/2005/Atom'>
  <title type='text'>Russell Brooks</title>
  <generator uri='http://nestacms.com'>Nesta</generator>
  <id>tag:russbrooks.com,2009:/</id>
  <link href='http://russbrooks.com/articles.xml' rel='self' />
  <link href='http://russbrooks.com/' rel='alternate' />
  <subtitle type='text'>Circuitous Sinuosity</subtitle>
  <updated>2012-11-10T20:09:00+00:00</updated>
  <author>
    <name>Russell Brooks</name>
    <uri>http://russbrooks.com</uri>
  </author>
  <entry>
    <title>How To Get Any Video Into iTunes and Apple TV Fast With No Quality Loss While Maintaining the 5.1 Soundtrack</title>
    <link href='http://russbrooks.com/2012/11/10/how-to-get-any-video-into-apple-tv-with-no-quality-loss-while-maintaining-the-5.1-soundtrack' rel='alternate' type='text/html' />
    <id>tag:russbrooks.com,2012-11-10:/2012/11/10/how-to-get-any-video-into-apple-tv-with-no-quality-loss-while-maintaining-the-5.1-soundtrack</id>
    <content type='html'>&lt;h2&gt;TL; DR&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Apple TV&lt;/strong&gt; - Set &quot;Dolby Digital&quot; to On rather than Auto.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://www.emmgunn.com/mp4tools/mp4toolshome.html&quot;&gt;MP4 Tools&lt;/a&gt;&lt;/strong&gt; to convert.

&lt;ul&gt;
&lt;li&gt;Set &quot;Device&quot; to &quot;Apple TV&quot;.&lt;/li&gt;
&lt;li&gt;Choose &quot;Pass Thru&quot; for Video.&lt;/li&gt;
&lt;li&gt;Choose &quot;Pass Thru&quot; for Audio.

&lt;ul&gt;
&lt;li&gt;If &quot;Pass Thru&quot; is grayed, the audio isn't compatible with ATV. Select &quot;AAC 5.1&quot;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Choose &quot;Mux (soft)&quot; for Subtitles.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://code.google.com/p/subler/&quot;&gt;Subler&lt;/a&gt;&lt;/strong&gt; to add complete metadata and cover art into the video file.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;That will &lt;em&gt;remux&lt;/em&gt; the video in mere minutes, which causes zero quality loss. It causes no lengthy, 2-hour-long, quality-reducing transcode (like HandBrake does).&lt;/p&gt;

&lt;p&gt;Now that you have weeks of work summarized into three steps, what follows is the research leading up to the above steps, as well as some tips on other tools.&lt;/p&gt;

&lt;h2&gt;Myths&lt;/h2&gt;

&lt;p&gt;Myths I am busting with this post:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&quot;I can't get some videos into iTunes &amp;amp; Apple TV.&quot;&lt;/li&gt;
&lt;li&gt;&quot;Conversion takes forever.&quot;&lt;/li&gt;
&lt;li&gt;&quot;Quality is lost with converting.&quot;&lt;/li&gt;
&lt;li&gt;&quot;Apple TV doesn't do 5.1 soundtracks.&quot;&lt;/li&gt;
&lt;li&gt;&quot;To play 5.1, Apple TV requires 2 audio streams per container: AC-3 5.1 and a 2-channel AAC.&quot;&lt;/li&gt;
&lt;/ol&gt;


&lt;h2&gt;Glossary&lt;/h2&gt;

&lt;p&gt;Some vocabulary first:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Container&lt;/strong&gt; - Sometimes &quot;Format&quot; or &quot;Container Format&quot;. The file itself. Examples of container formats: AVI, MPG, MP4, MKV, WebM&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Streams&lt;/strong&gt; - A container file can have essentially 3 types of streams inside it: Video, Audio, and Subtitles.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Channel&lt;/strong&gt; - Audio streams can be further broken up into channels. Stereo audio uses 2 channels. 5.1 audio uses 6 channels.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Codec&lt;/strong&gt; - Sometimes &quot;Compression Format&quot;. The method by which the video or audio streams are compressed.

&lt;ul&gt;
&lt;li&gt;Video Codecs: mp2v, h264, vp8&lt;/li&gt;
&lt;li&gt;Audio Codecs: DTS, AAC, AC3&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;It's very important to understand the difference between the two types of conversion methods, Transcoding and Remuxing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Transcoding&lt;/strong&gt; - Sometimes called &quot;re-encoding&quot;. Converting a stream to a different codec, bitrate (compression), or resolution. This means taking a fresh sample of every single frame. Transcoding is time-consuming and, with lossy codecs, causes generation-loss.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Demuxing&lt;/strong&gt; - Breaking a container into its component streams. Example: A video called &lt;code&gt;somevideo.mp4&lt;/code&gt; might contain an h264 video and an AAC audio stream. Demuxing it would create two files, one containing only video, one only audio. Both of these files would be exact copies of the stream in the container (no generation loss):

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;somevideo.h264&lt;/code&gt; - Only video&lt;/li&gt;
&lt;li&gt;&lt;code&gt;somevideo.aac&lt;/code&gt; - Only audio&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Muxing&lt;/strong&gt; - Combining individual stream files into a single container file. In the example above, &lt;code&gt;somevideo.h264&lt;/code&gt; and &lt;code&gt;somevideo.aac&lt;/code&gt; would be combined together into a file called &lt;code&gt;somevideo.mp4&lt;/code&gt;. That file would contain full video and audio tracks. Again, because there is no transcoding happening, there is no loss in quality when doing this.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Remuxing&lt;/strong&gt; - Sometimes referred to as &quot;converting container format&quot;. This means passing an exact copy of the streams through to a new container. Because nothing was transcoded, there is no loss in quality, and remuxing a 2-hour movie takes minutes not hours.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&lt;strong&gt;So remuxing is always preferred to transcoding.&lt;/strong&gt;  It's an order of magnitude faster, you leave the streams untouched, and avoid the generation-loss associated with transcoding.&lt;/p&gt;

&lt;h2&gt;What Apple TV Supports&lt;/h2&gt;

&lt;p&gt;There are some others, but the core ones we care about are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Containers&lt;/strong&gt; - MP4&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Video Codecs&lt;/strong&gt; - h264&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Audio Codecs&lt;/strong&gt; - AAC, AC-3 (via passthrough)&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Container&lt;/h2&gt;

&lt;p&gt;Most downloaded videos come in an MP4 container or perhaps AVI, MOV, or MKV (Metroska).  MP4's can sometimes have an M4V file extension.  If the file is MP4, M4V, or MOV, it can be dropped directly into iTunes, &lt;strong&gt;provided its audio stream is AAC or AC3&lt;/strong&gt;.  More on that very important point in a sec.&lt;/p&gt;

&lt;h2&gt;Video Stream&lt;/h2&gt;

&lt;p&gt;Nearly every video you download from the Internet, not matter what the container, has an h264 video stream in it.  h264 is fully compatible with Apple TV.  99% of the time, you can simply remux to MP4 very quickly without incurring a massively long transcode of the video stream.  If it came as an MP4, you can leave it MP4, again provided the audio stream is compatible.&lt;/p&gt;

&lt;h2&gt;Audio Stream&lt;/h2&gt;

&lt;p&gt;Audio is the area from which the majority of problems arise.  People often report problems importing h264 video into iTunes for Apple TV playback and, in most cases, it is because of an incompatible audio stream or an incorrect Dolby Digital setting in Apple TV.  You'll see reports such as, &quot;I imported an h264 MOV into iTunes and it's not working on Apple TV! I don't get any sound!  I thought Apple TV supported h264.  And MOV is Apple's own format!&quot;&lt;/p&gt;

&lt;p&gt;Correct, MOV &lt;em&gt;is&lt;/em&gt; Apple's own format, and h264 is very much supported on Apple TV.  It's not the MOV that is incompatible, nor is it the h264 video stream.  &lt;strong&gt;It is the audio stream inside the MOV that is incompatible.&lt;/strong&gt;  Only AC-3 and AAC audio codecs are supported by Apple TV, but there is a &quot;gotcha&quot; with AAC and 5.1 sound.&lt;/p&gt;

&lt;h3&gt;The DTS Problem&lt;/h3&gt;

&lt;p&gt;I see many videos, especially MKVs (Metroska video), coming with a DTS 5.1 soundtrack.  DTS is not compatible with Apple TV because the MP4 container does not support DTS.  Most conversion (remuxing) software will display an error when you try to remux a video with DTS to MP4.  To get video with DTS into iTunes and Apple TV, its audio stream must be transcoded to AC-3 or AAC.&lt;/p&gt;

&lt;h3&gt;The AAC Problem&lt;/h3&gt;

&lt;p&gt;If you are like me, you connected Apple TV to your reciever using solely an HDMI cable.  True, there is a TOSLINK (optical) output on the back of the Apple TV, but my logical thought was, &quot;OK, TOSLINK doesn't apply to my setup.  HDMI is capable of carrying all kinds of multichannel digital audio, right?  One world, one cable.&quot;  I went ahead using only the HDMI cable.&lt;/p&gt;

&lt;p&gt;My second logical thought was, &quot;I'll see if I can center my movie library around 5.1 AAC audio, it being the newer codec than AC-3.&quot;&lt;/p&gt;

&lt;p&gt;With 5.1 AAC videos over HDMI, I quicky discovered that only 2 audio channels were coming out of my 7.1 surround system.  [&lt;strong&gt;&lt;em&gt;gasp!&lt;/em&gt;&lt;/strong&gt;]&lt;/p&gt;

&lt;p&gt;Through trial and error, I found that I could get 5.1 sound to play if I did either of these:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Transcoded to AC-3 5.1 audio (Dolby Digital).&lt;/li&gt;
&lt;li&gt;Used a TOSLINK cable between my Apple TV and my receiver.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;TOSLINK wasn't an option for me because my receiver does not allow you to select a different, non-HDMI audio source while watching HDMI.&lt;/p&gt;

&lt;p&gt;To summarize, Apple TV comes configured like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;AAC 5.1&lt;/strong&gt; - Decoded in the Apple TV:

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;HDMI&lt;/strong&gt; - Only 2 channels sent to reciever (by default).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TOSLINK&lt;/strong&gt; - Full 5.1 sent to receiver.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;AC-3 5.1&lt;/strong&gt; - NOT decoded in the Apple TV:

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;HDMI&lt;/strong&gt; - Full 5.1 sent to receiver via &quot;Pass Thru&quot;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;TOSLINK&lt;/strong&gt; - Full 5.1 sent to receiver via &quot;Pass Thru&quot;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;&quot;Pass Thru&quot;, under the AC-3 bullet above, means that the audio stream is not decoded within Apple TV.  Your reciver must be able to decode AC-3.  AC-3 is a backcronym for &quot;Dolby Digital&quot;, which was invented in the 90's.  Any reciever manufactured in the last 10 or 15 years has support for Dolby Digital.&lt;/p&gt;

&lt;p&gt;The Apple TV, by default, will only send 2 of the 6 channels of a video's AAC audio over HDMI.  So I began standardizing on AC-3 5.1 soundtracks until I discovered the magic Apple TV setting:&lt;/p&gt;

&lt;h3&gt;The Solution: The Magic Setting&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Turn &quot;&lt;strong&gt;Dolby Digital&lt;/strong&gt;&quot; to On.  The setting mentioned in this &lt;a href=&quot;http://support.apple.com/kb/TS3518&quot;&gt;Apple TV support article&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Now the 5.1 soundtracks in my AAC videos are finally audible!&lt;/p&gt;

&lt;p&gt;Right now you're thinking, &quot;&lt;strong&gt;Why would a setting called 'Dolby Digital' have anything to do with the non-Dolby codec, AAC?&lt;/strong&gt;&quot;&lt;/p&gt;

&lt;p&gt;My guess:  The verbose way of saying what this setting's &lt;em&gt;actual&lt;/em&gt; function is, would be, &quot;It's OK to send decoded 5.1 over HDMI.&quot;  To us audio geeks, the option is probably better called, &quot;Bitstream 5.1 over HDMI&quot;, but that is far more cryptic to the average user.  The average user simply knows the &quot;Dolby Digital&quot; brand to mean &quot;good sound&quot; or &quot;surround sound&quot;.  Apple, following the rules of good User-Interface Design, usually avoid as best they can, acronyms and abbreviations.  They mean nothing to most users, so in using them, you communicate nothing to most of your audience.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why would '2 channels' be the default over HDMI?&lt;/strong&gt;  Two possible answers I can see:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Perhaps during Apple's testing, there could have been some fringe issues with 5.1 AAC over some older HDMI setups or versions, like static or no sound as the above support article indicates.  Apple probably opted for the safer 2-channel default because &quot;audio not coming out my rear speakers is better than static coming out of all of them&quot;.&lt;/li&gt;
&lt;li&gt;I saw &quot;HDMI negotiation&quot; as another possible cause. I haven't dug deeper into this, but I saw one person speculating that there is a HDMI-negotiation process that occurs between your receiver and your Apple TV to determine the # of simultaneous bitstream channels that your receiver can handle. If that type of negotiation is not a feature of your receiver, or this process fails in some way, perhaps it defaults back to 2 channels.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;The Apple TV Setup Guide says something like, &quot;If you have a Dolby Digital receiver, set this to On.&quot;&lt;/p&gt;

&lt;h2&gt;Tools&lt;/h2&gt;

&lt;h3&gt;Conversion&lt;/h3&gt;

&lt;h4&gt;MP4 Tools&lt;/h4&gt;

&lt;p&gt;I've had the best success with &lt;a href=&quot;http://www.emmgunn.com/mp4tools/mp4toolshome.html&quot;&gt;MP4 Tools&lt;/a&gt;. It focuses on Apple TV and remuxing, although it will transcode too. It's free if you are OK with nag screens, or $5 to make those go away (which I did). A very small price for a great, easy-to-use tool that works.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Open your video with &lt;strong&gt;MP4 Tools&lt;/strong&gt;. Go into the &lt;strong&gt;MP4&lt;/strong&gt; tab.&lt;/li&gt;
&lt;li&gt;Choose the &quot;&lt;strong&gt;Apple TV&lt;/strong&gt;&quot; device in the lower right.

&lt;ul&gt;
&lt;li&gt;It will gray out settings that aren't compatible with Apple TV.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Check off the streams you want to include: Audio, Video, Subtitles.&lt;/li&gt;
&lt;li&gt;Choose &quot;&lt;strong&gt;Pass Thru&lt;/strong&gt;&quot; for Video.

&lt;ul&gt;
&lt;li&gt;This copies the h264 stream to the new container. No quality loss.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Choose &quot;&lt;strong&gt;Pass Thru&lt;/strong&gt;&quot; for Audio if it's already 5.1 AC-3 or AAC.

&lt;ul&gt;
&lt;li&gt;If &quot;Pass Thru&quot; is grayed out, choose AAC 5.1.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Choose &quot;&lt;strong&gt;Mux (soft)&lt;/strong&gt;&quot; for subtitles.

&lt;ul&gt;
&lt;li&gt;&quot;Hard&quot; will burn them in to the frames and cause a 2-hour-long transcode.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Leave everything else as is. Click &quot;&lt;strong&gt;Convert&lt;/strong&gt;&quot;.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;Because we're remuxing, a 2-hour movie only take maybe 2 or 3 minutes. If the audio had to transcode, then only a few minutes more.&lt;/p&gt;

&lt;p&gt;MP4 Tools leaves the individual video and audio stream files on your drive after it's done, and log files, in addition to the remuxed video.  I turn this feature off in Preferences so the software cleans up after itself, leaving only the remuxed video.&lt;/p&gt;

&lt;p&gt;Soft subtitles sometimes don't work in ATV. Sometimes you have to burn them in. When you burn them in, &quot;Pass Thru&quot; video grays out. Of course, you have to transcode video to burn in subtitles (a several-hour process).  Tip: To see the Subtitles menu in Apple TV, hold down the Select button on the remote (the big round one in the middle). A subtitle-selection menu appears.&lt;/p&gt;

&lt;p&gt;If &quot;Header Compression&quot; was used in an MKV, MP4 Tools will prompt you remux it away. Just say &quot;Yes&quot;. It will create a new MKV file with Header Compression disabled. Simply run that one through MP4 Tools in the same way, again remuxing it so there is no quality loss. This is another area where this tool succeeds where others do not (FFmpeg).&lt;/p&gt;

&lt;p&gt;You can basically stop here, and be on your way with high-quality 5.1 videos in iTunes and Apple TV.  But from here, you'll likely want to write full metadata into the file, including hi-res cover art, that will make your personally converted videos look just as fancy as the ones you downloaded from Apple. They'll appear in iTunes and ATV with all the nice metadata: Title, Synopsis, MPAA Rating, Cover Art, Director, Actors, Genre, etc.  What follows is a tool that does just that, as well as some other tools you should keep on hand.&lt;/p&gt;

&lt;h3&gt;Metadata&lt;/h3&gt;

&lt;p&gt;How to make all your videos have that &quot;nice-looking&quot; metadata that shows up in iTunes and Apple TV:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://code.google.com/p/subler/&quot;&gt;Subler&lt;/a&gt;&lt;/strong&gt; - Subler has remuxing features, but it's primarily a metadata editor. It downloads the video's complete metadata from the TMDb and TVDB databases online, then writes that into your video file.

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Tip&lt;/strong&gt;: If Subler crashes upon Save, just relaunch it and Save the metadata again. It does very occasinally crash, but I haven't noticed that adversely affect the video files at all.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;&quot;Seeing&quot; the Streams&lt;/h3&gt;

&lt;p&gt;It's a good idea to keep some free software on-hand that allows you to view the stream data inside video containers.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://mediainfo.sourceforge.net/&quot;&gt;MediaInfo&lt;/a&gt;&lt;/strong&gt; - Peer into &lt;strong&gt;all&lt;/strong&gt; of the metadata inside a video file. A keep the free command-line version of this app installed. Install &lt;a href=&quot;http://mxcl.github.com/homebrew/&quot;&gt;Homebrew&lt;/a&gt;, then &lt;code&gt;brew install mediainfo&lt;/code&gt;. There is also a GUI one in the App Store for a couple bucks.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://ffmpeg.org/&quot;&gt;FFprobe&lt;/a&gt;&lt;/strong&gt; - Also a simply install via Homebrew: &lt;code&gt;brew install ffmpeg&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://www.videolan.org/vlc/&quot;&gt;VLC&lt;/a&gt;&lt;/strong&gt; - Press Command-I for &quot;Video Information&quot;. Go into the &quot;Codec Details&quot; tab and you'll see the Video, Audio, and Subtitle streams.  Expand the arrow next to each of the streams to see more info, including the codec of each one.&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Other Conversion Tools&lt;/h3&gt;

&lt;p&gt;These tools can do both remuxing and transcoding, but I didn't get into them in this article for reasons listed:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://ffmpeg.org/&quot;&gt;FFmpeg&lt;/a&gt;&lt;/strong&gt; - FFmpeg is an enormously powerful command-line tool, and is one of my favorites.  It is absolutely capable of remuxing to Apple TV-compatible formats, but my goal with this article was to show some simple, GUI-based conversion tools, geared toward remuxing and Apple TV, that I could recommend to non-nerds. And FFmpeg sometimes has trouble remuxing MKV's when &quot;Header Compression&quot; was used in the MKV.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://www.iffmpeg.com/&quot;&gt;iFFmpeg&lt;/a&gt;&lt;/strong&gt; - A nice GUI wrapper for FFmpeg with some good, Apple-centric presets. Of course, FFmpeg's overwhelming array of settings and options bubbles up to this app. Great for learning FFmpeg, though, and discovering its secrets.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://www.videolan.org/vlc/&quot;&gt;VLC&lt;/a&gt;&lt;/strong&gt; - VLC does have some admirable transcoding and remuxing features, but being a media player, that's not its focus. It doesn't always succeed, or its resultant files don't import into iTunes. Although, I keep VLC installed at all times. It's an excellent media player that plays every format in the world.&lt;/li&gt;
&lt;/ul&gt;


&lt;h3&gt;Transcoding Only: Last Resort&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://handbrake.fr/&quot;&gt;HandBrake&lt;/a&gt;&lt;/strong&gt; - Handbrake is a great tool, but is strictly a transcoding app, i.e., lossy conversion. Unfortunately, it doesn't do straight remuxing. Exhaust your efforts first with the above tools before resorting to HandBrake. I often see folks recommending HandBrake to get things into iTunes. That is unfortunate because they are imposing unnecessary, 2-hour-long, quality-reducing transcodes on all of their videos.&lt;/li&gt;
&lt;/ul&gt;</content>
    <published>2012-11-10T20:09:00+00:00</published>
    <updated>2012-11-10T20:09:00+00:00</updated>
    <category term='mac'></category>
  </entry>
  <entry>
    <title>Install PostgreSQL 9 on Ubuntu Linux</title>
    <link href='http://russbrooks.com/2010/12/4/install-postgresql-9-on-ubuntu-linux' rel='alternate' type='text/html' />
    <id>tag:russbrooks.com,2010-12-04:/2010/12/4/install-postgresql-9-on-ubuntu-linux</id>
    <content type='html'>&lt;p&gt;Tested on: Ubuntu 10.04&lt;/p&gt;

&lt;h2&gt;Add Repo&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;sudo nano /etc/apt/sources.list&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Append lines:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;## Postgres 9 hasn't been backported yet.  Manually added repos.&amp;#x000A;deb http://ppa.launchpad.net/pitti/postgresql/ubuntu lucid main &amp;#x000A;deb-src http://ppa.launchpad.net/pitti/postgresql/ubuntu lucid main&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Go to &lt;a href=&quot;https://launchpad.net/~pitti/+archive/postgresql&quot;&gt;this site&lt;/a&gt; and expand the &quot;Technical details about this PPA&quot; panel.  Under Signing Key, copy everything to the right of the slash [/], and paste into the command below.  In this example, it is &quot;8683D8A2&quot;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 8683D8A2&amp;#x000A;apt-get update&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Remove Old Versions&lt;/h2&gt;

&lt;p&gt;Careful!  These commands completely remove your old PostgreSQL version.  Back up data first.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;sudo service postgresql-8.4 stop&amp;#x000A;sudo apt-get purge postgresql*&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Install&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;sudo apt-get install postgresql-9.0&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Verify you can log in:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;sudo -u postgres psql&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You probably want to create a user for your web app while you're in there:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::sql&amp;#x000A;CREATE USER www_db WITH PASSWORD 'jw8s0F49eQ';&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Open External Access&lt;/h2&gt;

&lt;p&gt;If you plan to access Postgres externally, modify conf file to make Postgres listen on * instead of localhost.  Modify Host-Based Authentication file to make Postgres respond to more IP ranges than solely 127.0.0.1.  See my &lt;a href=&quot;http://russbrooks.com/2009/5/25/install-ubuntu-9-04-server-edition-rails-php-passenger-postgresql-and-mysql&quot;&gt;other article&lt;/a&gt; on this.&lt;/p&gt;

&lt;h2&gt;Instrumentation&lt;/h2&gt;

&lt;p&gt;So pgAdmin doesn't complain:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;apt-get install postgresql-contrib-9.0&amp;#x000A;sudo -u postgres psql -U postgres -d postgres &amp;lt; /usr/share/postgresql/9.0/contrib/adminpack.sql&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;</content>
    <published>2010-12-04T20:10:00+00:00</published>
    <updated>2010-12-04T20:10:00+00:00</updated>
    <category term='linux'></category>
  </entry>
  <entry>
    <title>Server-Side Email on OS X</title>
    <link href='http://russbrooks.com/2010/11/27/email-from-os-x-terminal' rel='alternate' type='text/html' />
    <id>tag:russbrooks.com,2010-11-27:/2010/11/27/email-from-os-x-terminal</id>
    <content type='html'>&lt;p&gt;This will make it so that you can send email from Terminal sessions, server-side scripts, and web pages.  We are also going to tell it to route email through your ISP's email servers: Gmail, in this case.&lt;/p&gt;

&lt;p&gt;Works on: &lt;strong&gt;OS 10.5 and 10.6&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;Postfix&lt;/h2&gt;

&lt;p&gt;Conveniently, the powerful and popular SMTP server, Postfix, is already installed on OS X.  In this example, we're going to tell it to route outgoing email through your Gmail account.&lt;/p&gt;

&lt;p&gt;Edit Postfix's config file:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;sudo nano /etc/postfix/main.cf&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Press &lt;code&gt;Esc-/&lt;/code&gt; to go to the bottom of the file. Add the block of text below to the bottom, changing &lt;code&gt;relayhost&lt;/code&gt; to your outgoing SMTP-server address.  In this example, we are using port 587, which TLS-encrypted mail travels through.  Verify your ISP supports TLS and port 587.  Nearly all do.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;relayhost = smtp.gmail.com:587&amp;#x000A;smtp_sasl_auth_enable = yes&amp;#x000A;smtp_use_tls = yes&amp;#x000A;smtp_enforce_tls = yes&amp;#x000A;smtp_sasl_security_options =&amp;#x000A;smtp_sasl_tls_security_options =&amp;#x000A;smtp_sasl_tls_verified_security_options =&amp;#x000A;smtp_tls_loglevel = 2&amp;#x000A;# Log is here /var/log/mail.log  &amp;#x000A;smtp_sasl_password_maps = hash:/etc/postfix/smtp_sasl_passwords&amp;#x000A;smtp_tls_per_site = hash:/etc/postfix/smtp_tls_sites&amp;#x000A;tls_random_source = dev:/dev/urandom&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Create the file to hold login credentials:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;sudo nano /etc/postfix/smtp_sasl_passwords&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Add this line to it, changing it to match your SMTP server address and credentials:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;smtp.gmail.com username:password&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Edit this file:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;sudo nano /etc/postfix/smtp_tls_sites&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Add this line to it, changing mail server accordingly:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;smtp.gmail.com MUST_NOPEERMATCH&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Run these commands:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;cd /etc/postfix&amp;#x000A;sudo chmod go-rx smtp_sasl_passwords&amp;#x000A;sudo postmap smtp_sasl_passwords&amp;#x000A;sudo postmap smtp_tls_sites&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Test&lt;/h2&gt;

&lt;p&gt;Change email addresses to yours:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;echo &quot;Hello&quot; | mail -s &quot;Test&quot; me@domain.com&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The above may not work if your ISP requires a valid From address, so also try:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;printf &quot;Subject: TestnHello&quot; | sendmail -f me@domain.com me@domain.com&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Both of these worked with Gmail, in my case.&lt;/p&gt;

&lt;p&gt;If things fail, tail out the log:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;tail -f /var/log/mail.log&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Send more email in a new Terminal tab while watching the logs.&lt;/p&gt;</content>
    <published>2010-11-27T22:32:00+00:00</published>
    <updated>2010-11-27T22:32:00+00:00</updated>
    <category term='mac'></category>
  </entry>
  <entry>
    <title>Install Rails 3 on OS X with Devise, RSpec, HAML, and jQuery Support</title>
    <link href='http://russbrooks.com/2010/11/26/install-rails-3-on-os-x-with-devise-rspec-haml-jquery' rel='alternate' type='text/html' />
    <id>tag:russbrooks.com,2010-11-26:/2010/11/26/install-rails-3-on-os-x-with-devise-rspec-haml-jquery</id>
    <content type='html'>&lt;h2&gt;Goals&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://postgresql.org/&quot;&gt;PostgreSQL&lt;/a&gt;&lt;/strong&gt; - Instead of MySQL&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://github.com/plataformatec/devise/&quot;&gt;Devise&lt;/a&gt;&lt;/strong&gt; - Instead of AuthLogic or Restful Authentication&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://haml-lang.com/&quot;&gt;HAML&lt;/a&gt;&lt;/strong&gt; - Instead of ERB&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://jquery.com/&quot;&gt;jQuery&lt;/a&gt;&lt;/strong&gt; - Instead of Prototype&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&quot;http://github.com/rspec/rspec/&quot;&gt;RSpec&lt;/a&gt;&lt;/strong&gt; - Instead of Test-Unit&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Prerequisites&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Ruby 1.9.2&lt;/strong&gt; - Installed via Homebrew. These instructions not tested with RVM.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rails 3.0.3&lt;/strong&gt; - &lt;code&gt;gem install rails&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PostgreSQL&lt;/strong&gt; - See my notes on &lt;a href=&quot;http://russbrooks.com/2010/11/25/install-postgresql-9-on-os-x&quot;&gt;installing PostgreSQL 9 on OS X&lt;/a&gt; via Homebrew.&lt;/li&gt;
&lt;/ul&gt;


&lt;h2&gt;Create App&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;rails new myapp&amp;#x000A;cd myapp&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Create Database&lt;/h2&gt;

&lt;p&gt;Change &lt;code&gt;config/database.yml&lt;/code&gt; accordingly to point to your dev DB, then:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;rake db:create&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Gems&lt;/h2&gt;

&lt;p&gt;Add to Gemfile in the root of your app:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::ruby&amp;#x000A;gem 'autotest'&amp;#x000A;gem 'devise'&amp;#x000A;gem 'haml-rails' # Not haml&amp;#x000A;gem 'hpricot'&amp;#x000A;gem 'pg'&amp;#x000A;group :development, :test do&amp;#x000A;  gem 'rspec-rails', '~&amp;gt; 2.1'&amp;#x000A;end&amp;#x000A;gem 'ruby_parser'&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Run &lt;code&gt;sudo bundle install&lt;/code&gt; to install all gems.  Note &lt;code&gt;haml-rails&lt;/code&gt; instead of &lt;code&gt;haml&lt;/code&gt;.  &lt;code&gt;haml-rails&lt;/code&gt; is newer and includes Rails 3 generators.  Also, &lt;code&gt;hpricot&lt;/code&gt; and &lt;code&gt;ruby_parser&lt;/code&gt; are necessary or Devise's generators fail.&lt;/p&gt;

&lt;h2&gt;Devise&lt;/h2&gt;

&lt;p&gt;Follow the Devise instructions at the end.  There are a couple of manual steps.  If you missed it, those steps are:&lt;/p&gt;

&lt;p&gt;Add to &lt;code&gt;config/environments/development.rb&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::ruby&amp;#x000A;config.action_mailer.default_url_options = { :host =&amp;gt; 'localhost:3000' }&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Add to &lt;code&gt;config/environments/production.rb&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::ruby&amp;#x000A;config.action_mailer.default_url_options = { :host =&amp;gt; 'russbrooks.com:3000' }&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Add to &lt;code&gt;config/routes.rb&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::ruby&amp;#x000A;root :to =&amp;gt; &quot;home#index&quot;&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Since we are going to use HAML templates, rename &lt;code&gt;app/views/layouts/application.html.erb&lt;/code&gt; to &lt;code&gt;application.html.haml&lt;/code&gt;, then paste:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::ruby&amp;#x000A;!!!&amp;#x000A;%html{ :lang =&amp;gt; 'en', 'xml:lang' =&amp;gt; 'en', :xmlns =&amp;gt; 'http://www.w3.org/1999/xhtml' }&amp;#x000A;  %head&amp;#x000A;    %title&amp;#x000A;      My New Site&amp;#x000A;    = stylesheet_link_tag :all&amp;#x000A;    = javascript_include_tag :defaults&amp;#x000A;    = csrf_meta_tag&amp;#x000A;  %body{ :class =&amp;gt; @body_class }&amp;#x000A;    #wrap&amp;#x000A;      #header&amp;#x000A;      #body&amp;#x000A;        %p{ :class =&amp;gt; :notice }&amp;#x000A;          = notice&amp;#x000A;        %p{ :class =&amp;gt; :alert }&amp;#x000A;          = alert&amp;#x000A;        = yield&amp;#x000A;      #footer&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Remove Rails' welcome page or it will render instead of home#index:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;rm public/index.html&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Use HAML Instead of ERB&lt;/h2&gt;

&lt;p&gt;Add this to &lt;code&gt;config/application.rb&lt;/code&gt; anywhere inside the Application class:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::ruby&amp;#x000A;# Default template engine for Rails Generators. Use HAML instead of ERB.&amp;#x000A;config.generators do |g|&amp;#x000A;  g.template_engine :haml&amp;#x000A;end&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The generators are now built in to the HAML-Rails gem. There is no need to add the &lt;code&gt;rails3-generators&lt;/code&gt; gem.&lt;/p&gt;

&lt;h2&gt;Use RSpec Instead of Test-Unit&lt;/h2&gt;

&lt;p&gt;We already added the necessary gems to Gemfile and did a &lt;code&gt;bundle install&lt;/code&gt; above, so just run the RSpec installation generator:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;rails g rspec:install&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This makes Rails generators produce RSpec tests instead of Test-Unit tests.&lt;/p&gt;

&lt;h2&gt;Use jQuery Instead of Prototype&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;rake rails:template LOCATION=http://github.com/lleger/Rails-3-jQuery/raw/master/jquery.rb&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Generate User Model and DB Table&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;rails g devise User&amp;#x000A;rake db:migrate&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Use &lt;code&gt;rake routes&lt;/code&gt; to see the routes Devise created for sign_up, sign_in, sign_out, etc.  You should be able to access those in a browser to test them at this point.  See the Devise docs for more info.&lt;/p&gt;

&lt;p&gt;From there, you might want to start with some scaffolding to ensure everything worked right, for example, that it generates HAML, RSpec tests, and is using jQuery.  For example, maybe create a &quot;Post&quot; resource if you are creating a blog:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;rails generate scaffold Post title:string teaser:string body:text&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;</content>
    <published>2010-11-26T18:20:00+00:00</published>
    <updated>2010-11-26T18:20:00+00:00</updated>
    <category term='mac'></category>
  </entry>
  <entry>
    <title>Install PostgreSQL 9 on OS X</title>
    <link href='http://russbrooks.com/2010/11/25/install-postgresql-9-on-os-x' rel='alternate' type='text/html' />
    <id>tag:russbrooks.com,2010-11-25:/2010/11/25/install-postgresql-9-on-os-x</id>
    <content type='html'>&lt;h2&gt;Homebrew&lt;/h2&gt;

&lt;p&gt;You're not still using MacPorts, are you?  Please go get &lt;a href=&quot;http://mxcl.github.com/homebrew/&quot; title=&quot;Homebrew&quot;&gt;Homebrew&lt;/a&gt; immediately, the new-hotness package manager for OS X written in Ruby.  It amazing how simple Homebrew makes this process in comparison to my &lt;a href=&quot;http://russbrooks.com/2009/3/20/install-upgrade-php-apache-postgresql-on-mac-os-x-10-5-leopard&quot; title=&quot;Install / Upgrade PHP, Apache, PostgreSQL on Mac OS X 10.5 Leopard&quot;&gt;old instructions on this topic&lt;/a&gt;.  It's also nice to be able to &lt;a href=&quot;https://github.com/mxcl/homebrew/blob/master/Library/Formula/postgresql.rb&quot;&gt;peer into friendly-Ruby Homebrew Formulae&lt;/a&gt; to see the exact build commands.&lt;/p&gt;

&lt;h2&gt;Uninstall Old Versions&lt;/h2&gt;

&lt;p&gt;Initially, I tried a &lt;code&gt;brew install postgresql&lt;/code&gt; over the top of the existing version that was installed via non-Homebrew means.  When it was complete, &lt;code&gt;psql --version&lt;/code&gt; was still showing &lt;code&gt;8.4.x&lt;/code&gt;.  I found it is best to uninstall any old PostgreSQL versions first.  Of course, &lt;a href=&quot;http://www.postgresql.org/docs/8.4/interactive/backup.html&quot; title=&quot;PostgreSQL 8.4.5 Documentation - Backup and Restore&quot;&gt;back up your data&lt;/a&gt; with &lt;a href=&quot;http://pgadmin.org/&quot; title=&quot;pgAdmin III&quot;&gt;pgAdmin&lt;/a&gt; or &lt;code&gt;pg_dump&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;First, uninstall any Homebrew versions.  The &lt;code&gt;--force&lt;/code&gt; option makes it uninstall all versions.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;brew rm postgresql --force&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Via Uninstaller&lt;/h3&gt;

&lt;p&gt;Second, uninstall any versions installed by other means.&lt;/p&gt;

&lt;p&gt;If you installed using &lt;a href=&quot;http://www.enterprisedb.com/&quot; title=&quot;EnterpriseDB&quot;&gt;EnterpriseDB&lt;/a&gt;, you likely have an &lt;code&gt;uninstall-postgresql.app&lt;/code&gt; file in your install directory.  Double-click that to uninstall their Postgres install.&lt;/p&gt;

&lt;h3&gt;Manual&lt;/h3&gt;

&lt;p&gt;I went the manual route.  Change paths accordingly for your version.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;sudo /sbin/SystemStarter stop postgresql-8.4&amp;#x000A;sudo rm -rf /Applications/PostgreSQL\ 8.4&amp;#x000A;sudo rm -rf /etc/postgres-reg.ini&amp;#x000A;sudo rm -rf /Library/StartupItems/postgresql-8.4&amp;#x000A;sudo rm -rf /Library/PostgreSQL/8.4&amp;#x000A;sudo dscl . delete /users/postgres&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Edit &lt;code&gt;/etc/profile&lt;/code&gt; and delete any lines that reference &quot;postgres&quot;.  For me, there was just one line that had to do with loading Postgres' Environment file.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;nano /etc/profile&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I rebooted here, to make sure the Postgres startup items were truly gone.  Open &quot;Activity Monitor&quot; and ensure there are no &quot;postgres&quot; processes.&lt;/p&gt;

&lt;h2&gt;Install PostgreSQL&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;brew update&amp;#x000A;brew install postgresql&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Follow the instructions at the end of the install to initialize the DB, add startup items, and start Postgres.  For me, it was:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;initdb /usr/local/var/postgres&amp;#x000A;cp /usr/local/Cellar/postgresql/9.1.4/homebrew.mxcl.postgresql.plist ~/Library/LaunchAgents/&amp;#x000A;launchctl load -w ~/Library/LaunchAgents/homebrew.mxcl.postgresql.plist&amp;#x000A;pg_ctl -D /usr/local/var/postgres -l /usr/local/var/postgres/server.log start&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Important Note About Authentication&lt;/h2&gt;

&lt;p&gt;The Homebrew formula does not create a &quot;postgres&quot; user, as was common up to this point.  Out of the box, you authenticate against the DB using the same user account under which you ran &lt;code&gt;brew install&lt;/code&gt;.  It's perfectly acceptable to leave it that way on your Dev machine.  Don't forget to change that if this is a Production environment.&lt;/p&gt;

&lt;h2&gt;Instrumentation&lt;/h2&gt;

&lt;p&gt;Install Instrumentation so pgAdmin doesn't yell at you.  Run this as the same user under which you installed Postgres.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;psql postgres -c 'CREATE EXTENSION &quot;adminpack&quot;;'&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Test&lt;/h2&gt;

&lt;p&gt;Launch &lt;a href=&quot;http://pgadmin.org/&quot;&gt;pgAdmin&lt;/a&gt;, add a DB for &quot;localhost&quot;, and use your username and password.&lt;/p&gt;

&lt;h2&gt;Install the PG Gem&lt;/h2&gt;

&lt;p&gt;This installs the &quot;pg&quot; gem that &lt;a href=&quot;http://en.wikipedia.org/wiki/Yukihiro_Matsumoto&quot; title=&quot;Yukihiro Matsumoto&quot;&gt;Matz&lt;/a&gt; himself wrote.  It is recommended over the old &quot;postgres&quot; gem.  I do not believe you need to give it Architecture Flags anymore (&lt;code&gt;env ARCHFLAGS=&quot;-arch x86_64&quot; gem install pg&lt;/code&gt;), so just do:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;gem install pg&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;</content>
    <published>2010-11-25T18:27:00+00:00</published>
    <updated>2010-11-25T18:27:00+00:00</updated>
    <category term='mac'></category>
  </entry>
  <entry>
    <title>LFTP Cheatsheet</title>
    <link href='http://russbrooks.com/2010/11/19/lftp-cheetsheet' rel='alternate' type='text/html' />
    <id>tag:russbrooks.com,2010-11-19:/2010/11/19/lftp-cheetsheet</id>
    <content type='html'>&lt;p&gt;I don't use FTP personally.  But, on a professional level, &lt;a href=&quot;http://lftp.yar.ru/&quot; title=&quot;LFTP&quot;&gt;LFTP&lt;/a&gt; is becoming a super-reliable option for me when automating FTP transfers with script.  LFTP is a more robust FTP client than just plain FTP or cURL.  Unlike those clients, it retries a few times when transmission fails, has mirroring features, and supports simultaneous multi-file transfers, recursion, and Regular-Expression matches. Speed, from what I've experienced, is identical.&lt;/p&gt;

&lt;h2&gt;Upload a File&lt;/h2&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;lftp -e 'put /local/path/yourfile.mp4; bye' -u user,password ftp.foo.com&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Like all FTP clients, LFTP correctly uses Passive mode by default.  Passive is newer than Active.  It was designed to solve the problems with Active, and will go through the greatest array of firewalls without incident.  [Never use Active.]&lt;/p&gt;

&lt;h2&gt;Connection Timeout&lt;/h2&gt;

&lt;p&gt;LFTP will keep trying forever I believe, so it's wise to specify a timeout, especially if you are scripting this.  In this example, timeout is 10 seconds:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;lftp -e 'set net:timeout 10; put /local/path/yourfile.mp4; bye' -u user,password ftp.foo.com&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Active Mode&lt;/h2&gt;

&lt;p&gt;For what it's worth, Active mode -- older, stinkier, and won't go through your firewall:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;lftp -e 'set ftp:passive-mode false; set net:timeout 10; put /local/path/yourfile.mp4; bye' -u user,password ftp.foo.com&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Download&lt;/h2&gt;

&lt;p&gt;Uses Binary mode by default:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;lftp -e 'set net:timeout 10; get yourfile.mp4; bye' -u user,password ftp.foo.com&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If you need to put it in a specific local directory:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;lftp -e 'set net:timeout 10; get yourfile.mp4 -o /local/path/yourfile.mp4; bye' -u user,password ftp.foo.com&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Mirroring&lt;/h2&gt;

&lt;h3&gt;Recursive Upload&lt;/h3&gt;

&lt;p&gt;When using the &lt;code&gt;mirror&lt;/code&gt; command, LFTP is recursive by default.&lt;/p&gt;

&lt;p&gt;Mirror everything from the &lt;code&gt;/local/path&lt;/code&gt; to the root of the remote FTP site, including all subdirectories and their files.  The -R switch means &quot;reverse mirror&quot; which means &quot;put&quot; [upload].  Remote path is simply &lt;code&gt;/&lt;/code&gt;, the root.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;lftp -e 'mirror -R /local/path/ /' -u user,password ftp.foo.com&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Recursive Download&lt;/h3&gt;

&lt;p&gt;To mirror remote to local, just omit the &lt;code&gt;-R&lt;/code&gt; param and swap remote path with local.  Be careful with this.  Don't overwrite your local changes.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;lftp -e 'mirror / /local/path/' -u user,password ftp.foo.com&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Regular-Expression&amp;#8211;Match Upload&lt;/h3&gt;

&lt;p&gt;Only include certain file types.  Mirror everything in the &lt;code&gt;/local/path&lt;/code&gt; recursively, but only transfer files that end with &lt;code&gt;.htm&lt;/code&gt;, &lt;code&gt;.html&lt;/code&gt;, &lt;code&gt;.css&lt;/code&gt;, and &lt;code&gt;.js&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;lftp -e 'mirror -R -i &quot;\.(html?|css|js)$&quot; /local/path/ /' -u user,password ftp.foo.com&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;h3&gt;Non-Recursive&lt;/h3&gt;

&lt;p&gt;Deploy only root-level files, not the entire directory tree.  The &lt;code&gt;-r&lt;/code&gt; switch disables recursion.  In this example, we are also only deploying HTML, CSS, and JavaScript:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;lftp -e 'mirror -R -r -i &quot;\.(html?|css|js)$&quot; /local/path/ /' -u user,password ftp.foo.com&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;h2&gt;Special Characters in Username or Password&lt;/h2&gt;

&lt;p&gt;Special characters in your username or password must be escaped with backslashes:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;lftp -e 'put /local/path/yourfile.mp4; bye' -u user,password\!\! ftp.foo.com&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;IMO, FTP is not the right protocol for Internet file transfer of any kind.  But, unfortunately, it is in place everywhere so you do find yourself stuck with it as the only option from time to time.  [SFTP is the right protocol.]&lt;/p&gt;</content>
    <published>2010-11-19T20:06:00+00:00</published>
    <updated>2010-11-19T20:06:00+00:00</updated>
    <category term='linux'></category>
  </entry>
  <entry>
    <title>Rails Cache and MemCache on Passenger with Smart Spawning</title>
    <link href='http://russbrooks.com/2010/10/20/rails-cache-memcache-on-passenger-with-smart-spawning' rel='alternate' type='text/html' />
    <id>tag:russbrooks.com,2010-10-20:/2010/10/20/rails-cache-memcache-on-passenger-with-smart-spawning</id>
    <content type='html'>&lt;p&gt;This article applies to Passenger 2.2.x.  Passenger 3 was released today, so I'm not certain if this issue applies to that yet.&lt;/p&gt;

&lt;h2&gt;Smart Spawning&lt;/h2&gt;

&lt;p&gt;Passenger's &quot;Smart Spawning&quot; is enabled by default, but does not play nice with MemCacheD.&lt;/p&gt;

&lt;p&gt;If you recall from the Mongrel days, Mongrel_Cluster loads an entire copy of of your app and the Rails framework into each Mongrel.  Mongrel is analogous to an &quot;app process&quot; in Passenger.  For efficiency reasons, when Smart Spawning is active, Passenger shares your app code and Rails framework between app processes.  Unfortunately, this can seriously confuse MemCacheD.  Different app processes can contend for the same item in MemCache, unbeknownst to MemCache, causing one of those two MemCache connections to drop mid-stride.  If you have Rails.cache configured to use MemCache as its store, this can cause periodic incomplete cache reads.  Since everything in Rails.cache is marshaled on its way in, if a MemCache connection is interrupted, a cache read can be truncated, which causes demarshaling to fail, yielding a cryptic &quot;Marshal data too small&quot; error.  You may encounter other errors such as MemCache IO errors and timeouts.&lt;/p&gt;

&lt;h2&gt;Lazy Solution&lt;/h2&gt;

&lt;p&gt;To solve this, some developers back Passenger off to &quot;Conservative Spawning&quot;.  But that, like Mongrel_Cluster, stores a copy of your app and the Rails framework in each app process.  This wastes memory and app-process [re]spawn time.  I didn't want to concede to that.&lt;/p&gt;

&lt;h2&gt;Correct Solution&lt;/h2&gt;

&lt;p&gt;I found a clue in the Phusion Passenger User's Guide under &lt;a href=&quot;http://www.modrails.com/documentation/Users%20guide.html#spawning_methods_explained&quot;&gt;Spawning Methods Explained&lt;/a&gt;.  If you scroll a little further, there's a section called &quot;11.3.1. Example 1: Memcached connection sharing (harmful)&quot;.  It provides a small code snippet for your &lt;code&gt;environment.rb&lt;/code&gt; file.  This code resets the connection to MemCache when an app process is [re]started.  But, unfortunately their code snippet contains a some psuedo-code, &lt;code&gt;reestablish_connection_to_memcached&lt;/code&gt;, instead of actual code for the solution.  I see some solutions online that use a CACHE constant which would mean a global replace of &quot;&lt;code&gt;Rails.cache&lt;/code&gt;&quot; throughout your app.  We were already using the standard &lt;code&gt;Rails.cache&lt;/code&gt; application-wide, so I wanted to stick with that.  So, I call the &lt;code&gt;reset()&lt;/code&gt; method on &lt;code&gt;Rails.cache&lt;/code&gt; instead [but only if &lt;code&gt;Rails.cache&lt;/code&gt;'s store is set to MemCache].&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::ruby&amp;#x000A;if defined?(PhusionPassenger)&amp;#x000A;  PhusionPassenger.on_event(:starting_worker_process) do |forked|&amp;#x000A;    if forked&amp;#x000A;      Rails.cache.instance_variable_get(:@data).reset if Rails.cache.class == ActiveSupport::Cache::MemCacheStore&amp;#x000A;    end&amp;#x000A;  end&amp;#x000A;end&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Also update MemCacheD and your memcache-client gem to latest.  They're faster and better.  And add a &lt;code&gt;require 'memcache'&lt;/code&gt; to environment.rb, so Rails use the new gem and not its bundled old one.&lt;/p&gt;

&lt;p&gt;Restart MemCacheD:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;service memcached restart&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;...and Passenger [from the root of your app]:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;touch tmp/restart.txt  &amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;Rails.cache.write&lt;/code&gt; and &lt;code&gt;Rails.cache.fetch&lt;/code&gt; should now be shuttling data in and out of MemCacheD unscathed.&lt;/p&gt;</content>
    <published>2010-10-20T22:15:00+00:00</published>
    <updated>2010-10-20T22:15:00+00:00</updated>
    <category term='rails'></category>
  </entry>
  <entry>
    <title>BMW S-1000RR Test Ride</title>
    <link href='http://russbrooks.com/2010/3/20/bmw-s-1000rr-test-ride' rel='alternate' type='text/html' />
    <id>tag:russbrooks.com,2010-03-20:/2010/3/20/bmw-s-1000rr-test-ride</id>
    <content type='html'>&lt;p&gt;Everything you&amp;#8217;ve read and heard is true.  Germany really has crafted a groundbreaking masterwork in superbike engineering.  Sport-riding enthusiasts in the audience will know I am talking about the brand-new BMW S-1000RR, BMW&amp;#8217;s first-ever foray into the superbike arena.  May I say that Bavarian Motorwerks has not merely dropped a disposable, cookie-cutter, half-hearted hero into that arena, but a full-on fire-breathing dragon of epic, Tolkienian proportions.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.bmwplanetpower.com/&quot;&gt;
  &lt;img src=&quot;/attachments/2010/3/20/BMW_S1000RR_Press_7.jpeg&quot; width=&quot;415&quot; height=&quot;311&quot; class=&quot;photo&quot; alt=&quot;BMW S-1000RR&quot; title=&quot;BMW S-1000RR&quot; /&gt;
&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The salesman gave me the test-ride rules as we stood next to the running motorcycle, in Beemer green, onlookers gazing in admiration, while we conversed in that slightly-raised, talking-over-a-running-bike tone, &amp;#8220;You track-ride a 1098 and a CBR-1000, so you know what you&amp;#8217;re doing, but I have to go over the rules.  The bike is electronically limited to 8,000 RPMs during the break-in period, so just be aware of that.  BMW requires that we only demo in &amp;#8216;Rain Mode&amp;#8217;.&amp;#8221;&lt;/p&gt;

&lt;p&gt;&amp;#8220;150 horsepower,&amp;#8221; I interrupted.&lt;/p&gt;

&lt;p&gt;&amp;#8220;Exactly.  You can switch to other modes, but it doesn&amp;#8217;t matter.  The demo bike is configured to remain in Rain Mode.&amp;#8221;&lt;/p&gt;

&lt;p&gt;&amp;#8220;No problem,&amp;#8221; I affirmed.&lt;/p&gt;

&lt;p&gt;&amp;#8220;About the Quick-Shifter, if you&amp;#8217;re gonna try it, don&amp;#8217;t let off the throttle between gears.  Just stay one the throttle while up-shifting clutchless,&amp;#8221; as he made the universally understood wrist motion with his right hand.&lt;/p&gt;

&lt;p&gt;&amp;#8220;Check.&amp;#8221;&lt;/p&gt;

&lt;p&gt;He noodled various switches and poked his head closer to the display, &amp;#8220;Traction Control on.  ABS active.  Trip timer reset.  That&amp;#8217;s about it.  Enjoy!  Don&amp;#8217;t crash it!&amp;#8221;  [chuckles]&lt;/p&gt;

&lt;p&gt;&amp;#8220;How many have you guys sold already?&amp;#8221;, I inquired pulling my helmet onto my head.&lt;/p&gt;

&lt;p&gt;&amp;#8220;5 pre-orders right now.  Every single person we have let ride it, has bought it.&amp;#8221;&lt;/p&gt;

&lt;p&gt;&amp;#8220;Well, let&amp;#8217;s see if I can maintain that trend for ya,&amp;#8221; as I slung my leg over.&lt;/p&gt;

&lt;p&gt;Accelerating out of the parking lot, I was surprised how much power the bike actually had in Rain Mode.  Regardless of what the dealer had told me, I still had to at least try putting it in Race mode.  I frantically thumbed the tiny gray &amp;#8220;Mode&amp;#8221; button with my right thumb and squinted at the dash.  I watched as the little arrow cycled up to SPORT mode, then RACE.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;RAIN&lt;/li&gt;
&lt;li&gt;SPORT&lt;/li&gt;
&lt;li&gt;RACE &amp;lt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;I attempted a hard acceleration, but the bike was clearly still in RAIN mode.  Keep in mind that even in RAIN mode, the horsepower is equivalent to the most powerful 1,000&amp;#8217;s of 6 years ago.  There is a forth, even more powerful, mode beyond RACE, called &amp;#8220;SLICK&amp;#8221;, but you have to flip a switch under the seat to activate it.&lt;/p&gt;

&lt;p&gt;I noticed one particular difference immediately, and this was a small difference but it was an indicator of the thoughtful engineering to come, found throughout this machinery.  The turn-signal button moved all of a micron in each direction.  No huge 1/4-inch push with your thumb was necessary.  All it took was a tiny, effortless nudge with your left thumb and *snikt* the blinker was active.  The same applied for turning it off.&lt;/p&gt;

&lt;p&gt;I stopped at a red light with some fast, smooth road ahead and thought it the perfect time to try some full-throttle, clutchless upshifts.  The light greened and I was off.  I snapped through several gears, in the tuck, hitting 8,000 each time.  I even felt the temporary &amp;#8220;break-in&amp;#8221; limiter kick in on a gear or two.  I could not believe the smoothness and speed at which this motorcycle changed gears.  I realized I was actually being too hard on the shifter with my left foot, being used to my Ducati&amp;#8217;s fine but noticeably less effortless gearbox.  I made a mental note to shift more easily.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/attachments/2010/3/20/BMW_S1000RR_Press_9.jpeg&quot; width=&quot;415&quot; height=&quot;310&quot; class=&quot;photo&quot; alt=&quot;BMW S-1000RR&quot; title=&quot;BMW S-1000RR&quot; /&gt;&lt;/p&gt;

&lt;p&gt;I arrived at another light, made a right onto a buttery county road, and really gave it the goose.  This time, clucthless upshifts were executed by merely thinking.  I identified the bike&amp;#8217;s gorgeous and distinct engine sound as Mozart&amp;#8217;s Symphony No. 25 in G Minor.  Strudel to my ears, as I tucked it cleanly around a beautiful left-hand sweeper at 80 MPH, leaning off, knee out.  I rolled on smoothly but assertively and absolutely launched myself out of the corner.  90, 100, 110, 120&amp;#8230; as fast as you can say it.  Various expletives of wonderment came to mind as my spine shivered and goosebumps appeared on my skin.  Rapidly approaching a line of cars doing 50, I had a chance to feel the race-class brakes.  I one-fingered the lever and zzzzzzzzzzZZZZZZ the sintered brake pads made their sound, the nose gently dove, and the bike decelerated with all the stability and rapidity of a world-class superbike.  As I railed it down through the gears, habitually blipping the throttle each time, I noticed a certain smoothing of my downshifting.  Ah, I remembered&amp;#8230; the slipper clutch (or &amp;#8220;back-torque-limiting&amp;#8221; to be precise).  It was time to put that to the test.  I found a clean spot to pass and snapped it effortlessly down two gears and whacked it to the wood.  The front-wheel skimmed the Tarmac as the bike had me past a line of 5 cars in seconds.  Rounding a right-hand sweeper, a red light rapidly approached.  Slowing from 125 again, I intentionally downshifted sloppily, not blipping the throttle at all.  The Beemer absorbed my ham-fisted shifts with all the efficiency of Deutschland.&lt;/p&gt;

&lt;p&gt;I stood at the red light and thought, &amp;#8220;5 miles on the trip odometer.  I have to turn around at some point.  This is it.  Let&amp;#8217;s make it count.&amp;#8221;  I had read about the Wheelie-Control System so, being a recreational wheelier myself, I really wanted to feel that.  The light went green and I gave it everything an 8,000 RPM limit would afford me.  I pinned it.  The front wheel eagerly attempted to lift into the stratosphere, with the Rain-mode-limited 150 horsepower behind it, but Germany&amp;#8217;s finest electronics prevented that from happening.  I felt the wheelie control engage as the bike&amp;#8217;s front wheel just skimmed along at perhaps an inch off the ground.  But, even in Rain mode, MAN did the motorcycle accelerate!  I could feel the precession in the engineering beneath me, everything working in perfect harmony.  The engine note is nothing short of beautiful.  I cannot wait to feel it in SLICK mode on the track.  I also cannot wait to feel this motorcycle when the shackles of an 8000-RPM limit are removed and the full power of its 14,200 redline can be felt.  I can&amp;#8217;t even imagine.  Let&amp;#8217;s remember that it was only six years ago that 600cc motorcycles had 14,000-RPM redlines.  BMW has now exceeded this with a 1,000.  The rest of the liter bikes in this class all have sub-14,000 redlines.  According to BMW, the engine can spin significantly faster, but they limited it to 14.2 for production durability reasons.&lt;/p&gt;

&lt;p&gt;I&amp;#8217;m seeing mixed reports online about the Wheelie-Control System.  I saw &lt;a href=&quot;http://www.motorcycle-usa.com/65/5106/Motorcycle-Article/2010-BMW-S1000RR-First-Ride.aspx&quot;&gt;one report&lt;/a&gt; that indicated it is completely disabled in RACE and SLICK modes.  I saw a report that only in SLICK mode is it disabled.  I saw other reports that indicated that it is active in all modes, only allowing you to get the front wheel off the ground 12&amp;#8221; to 16&amp;#8221;, and only for 5 seconds (which, as a recreational wheelier, would be disappointing).&lt;/p&gt;

&lt;p&gt;The bike is absolutely effortless to ride.  It is the lightest, most nimble 1,000 I have ever ridden.  Every lever, switch, and control on that motorcycle are manipulated by making the most infinitesimal movement with your hands, fingers, and feet.  It has highly user-friendly ergos with everything in the right places.  It felt very slim for an inline-4, definitely slimmer than my CBR-1000.  The power curve felt pin-straight.  It is also remarkable that BMW has managed to pack every possible gadget onto this bike at this insanely reasonable price point: DTC (with lean-angle sensor), ABS, wheelie-control, track-ready suspension, track-ready brakes, slipper clutch, quick shifter, and a free-breathing exhaust.  I did the math, and to do the same to a new CBR, R1, or GSX-R with aftermarket kits, would bring you up to around $21,000, and you still wouldn&amp;#8217;t have power modes or true DTC with wheel sensors.  BMW has just, plain &lt;strong&gt;&lt;em&gt;nailed it&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;On the way back, I was waiting at another light, and I glanced at the SUV driver to my right.  He was looking down at the bike, hitting his passenger in the shoulder to get him to also look, and he had that &amp;#8220;HOLY SHNIKIES!  WTF IS THAT?&amp;#8221; look on his face with a smile.  He saw me looking over, so I slowly reached to the throttle and give it a few twists for him, rotating the handgrip with only my thumb and index finger to demonstrate to him the precision of this wondrous machine.  &amp;#8220;GROOOOOWL!!  GROOOOOOWL!!  GROOOOOOOOOOOOOOOOOWWLLL!!&amp;#8221;, the S-1000 sang its beautiful song.  His eyes widened to disproportionate levels, a huge grin came across his face, as he gave the thumbs-up of approval.  I had my mirrored shield on, but I&amp;#8217;m sure he saw my upper torso and head vibrating up and down as I giggled in absolute astonishment, looking down at the marvel I was straddling, shaking my head, arms out, palms up as if to say, &amp;#8220;Isn&amp;#8217;t it just&amp;#8230;?&amp;#8221;&lt;/p&gt;</content>
    <published>2010-03-20T17:45:00+00:00</published>
    <updated>2010-03-20T17:45:00+00:00</updated>
    <category term='motorbikes'></category>
  </entry>
  <entry>
    <title>Disable .DS_Store Files on Mac OS X</title>
    <link href='http://russbrooks.com/2009/12/30/disable-ds_store-files-on-mac-os-x' rel='alternate' type='text/html' />
    <id>tag:russbrooks.com,2009-12-30:/2009/12/30/disable-ds_store-files-on-mac-os-x</id>
    <content type='html'>&lt;p&gt;Have you ever noticed that your Mac leaves small .DS_Store files on network shares and wished you could shut that off?&lt;/p&gt;

&lt;p&gt;To disabled them, enter or paste these commands into a Terminal window:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::bash&amp;#x000A;defaults write com.apple.desktopservices DSDontWriteNetworkStores true&amp;#x000A;su -&amp;#x000A;defaults write com.apple.desktopservices DSDontWriteNetworkStores true&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Log out of your Mac from the Apple Menu, then log back in again.&lt;/p&gt;

&lt;p&gt;The second command [&lt;code&gt;su -&lt;/code&gt;] logs us in as Root, then we perform the command again as Root.  It is unlikely you will be browsing network shares as Root, but we do it just in case.&lt;/p&gt;

&lt;p&gt;The above command does not prevent these .DS_Store files from being created locally, which is a good thing.  The OS needs them locally.&lt;/p&gt;

&lt;p&gt;The only thing stored in these files is some unnecessary things like scrollbar positions, icon size, and window dimensions.  Trust me, you can safely live without them.  I prefer that my Mac be a good citizen and not leave a trail of liter strewn throughout the network.  [I should mention that Windows does the same thing with its thumbnail cache files.]&lt;/p&gt;</content>
    <published>2009-12-30T21:22:00+00:00</published>
    <updated>2009-12-30T21:22:00+00:00</updated>
    <category term='mac'></category>
  </entry>
  <entry>
    <title>Embed a Static HTML Page in a Rails View</title>
    <link href='http://russbrooks.com/2009/11/18/embed-a-static-hmtl-page-in-a-rails-view' rel='alternate' type='text/html' />
    <id>tag:russbrooks.com,2009-11-18:/2009/11/18/embed-a-static-hmtl-page-in-a-rails-view</id>
    <content type='html'>&lt;p&gt;During a recent Rails project, I had the need to embed some static HTML pages within a View that were wrapped in the application&amp;#8217;s default Layout. I found it interesting that there was no apparent simple way to do this, for example SSI.&lt;/p&gt;

&lt;p&gt;Things that didn&amp;#8217;t work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;render :file&lt;/code&gt; in the Controller. It worked, but you cannot wrap it in a Layout.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;render :file&lt;/code&gt; in the View&lt;/li&gt;
&lt;li&gt;&lt;code&gt;render :partial&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;render :inline&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;render :text&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;render :action&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;I discovered a loosely documented method called &lt;a href=&quot;http://apidock.com/rails/ActionController/Base/render_to_string&quot;&gt;render_to_string()&lt;/a&gt;, but it did not work directly in the View because &lt;code&gt;render_to_string()&lt;/code&gt; has a visibility of &amp;#8220;Protected&amp;#8221; in &lt;code&gt;ActionController::Base&lt;/code&gt;.  In other words, it is only accessible in &lt;code&gt;ActionController::Base&lt;/code&gt; and subclasses thereof.  The Controller is a subclass of ActionController but the View is not.&lt;/p&gt;

&lt;h2&gt;Questionable&lt;/h2&gt;

&lt;p&gt;One egregious way around this, that I&amp;#8217;ve seen online, is to simply make &lt;code&gt;render_to_string()&lt;/code&gt; public in your Controller:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::ruby&amp;#x000A;class MyController &amp;lt; ApplicationController&amp;#x000A;  public :render_to_string&amp;#x000A;end&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then access it in the View using the &lt;code&gt;controller.&lt;/code&gt; reference:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::ruby&amp;#x000A;controller.render_to_string :file =&amp;gt; '/aboslute/path/to/file.html'&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note that what is being shown above, in the MyController class, you cannot do in other OOP languages like C#, Java, and PHP.  We are effortlessly overriding a method&amp;#8217;s Protected visibility and making it Public.&lt;/p&gt;

&lt;p&gt;This raises the question, &amp;#8220;Why even have visibility modifiers in Ruby?&amp;#8221;&lt;/p&gt;

&lt;p&gt;Ruby is very open and trusting of the client-code programmer.  In Ruby, marking a member as Private or Protected essentially means, &amp;#8220;If you try to access this member in a way that violates its visibility, we will certainly let you know [by throwing an error], but if you &lt;strong&gt;&lt;em&gt;really&lt;/em&gt;&lt;/strong&gt; want to, you can still access it [by adding a line of code].&amp;#8221;&lt;/p&gt;

&lt;p&gt;The object masters will cry, &amp;#8220;But this breaks Encapsulation, an OOP fundamental!  What happens if the implementation changes?&amp;#8221;&lt;/p&gt;

&lt;p&gt;True, but by the same token, it allows you to do some powerful and flexible things in Ruby that you can&amp;#8217;t do in other languages.  [Plenty of examples online.]&lt;/p&gt;

&lt;h2&gt;Correct Solution&lt;/h2&gt;

&lt;p&gt;I opted to store the contents of &lt;code&gt;render_to_string&lt;/code&gt; in an attribute in the Controller:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;:::ruby&amp;#x000A;@file = render_to_string :file =&amp;gt; '/aboslute/path/to/file.html'&amp;#x000A;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then output the &lt;code&gt;@file&lt;/code&gt; attribute in the View.&lt;/p&gt;</content>
    <published>2009-11-18T22:00:00+00:00</published>
    <updated>2009-11-18T22:00:00+00:00</updated>
    <category term='rails'></category>
  </entry>
</feed>
