<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Ryan Detzel]]></title>
  <link href="http://ryandetzel.com/atom.xml" rel="self"/>
  <link href="http://ryandetzel.com/"/>
  <updated>2013-02-01T19:51:52+00:00</updated>
  <id>http://ryandetzel.com/</id>
  <author>
    <name><![CDATA[Ryan Detzel]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Vanish.io - Secure self-destructing messages.]]></title>
    <link href="http://ryandetzel.com/vanish-dot-io-secure-self-destructing-messages/"/>
    <updated>2013-01-10T01:30:00+00:00</updated>
    <id>http://ryandetzel.com/vanish-dot-io-secure-self-destructing-messages</id>
    <content type="html"><![CDATA[<p><a href="https://vanish.io">Vanish.io</a> is pretty simple. You enter your message and hit <strong>Create Message</strong> and a new secure self-destructing message is created for you to send to whom ever you want. Once the message has been destroyed there is <strong>absolutely no way of getting it back</strong>. There are no backups, no logs, and no digital trail what so ever. The prototype was built so I could send co-workers their passwords and other important information without having to send it through email or chat which is logged and archived. I quickly found it useful to also send my wife and friends sensitive information via email like credit card information, prescription details and personal messages I&#8217;d rather not have permanently archived in the cloud. :-)</p>

<p><img src="http://ryandetzel.com/images/posts/vanish/vanish-enter-message.png"></p>

<p>After testing this out on dozens of people and thousands of messages I&#8217;m ready to see if anyone else wants to use it. I&#8217;m also looking for tips on how to make it even more secure and better (attachments, emoticons) so if you have any ideas please leave a comment. Hopefully you find <a href="https://vanish.io">vanish.io</a> as useful as I do.</p>

<p><img src="http://ryandetzel.com/images/posts/vanish/vanish-message-ready.png">
<img src="http://ryandetzel.com/images/posts/vanish/vanish-message-view.png"></p>

<h3>Tip</h3>

<p>Even though the message is not tied to you in anyway if you&#8217;re going to send certain information that doesn&#8217;t need an identity to be useful (credit card number, social security, etc) it&#8217;s best to do it in a series of messages. For example take the first eight digits of your credit card and send it in one message and take the other eight and send those in another. This just makes it a little more safe.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Template Monster]]></title>
    <link href="http://ryandetzel.com/template-monster/"/>
    <updated>2012-12-06T19:48:00+00:00</updated>
    <id>http://ryandetzel.com/template-monster</id>
    <content type="html"><![CDATA[<p>I&#8217;ve been playing a lot with backbone.js and one of the very intriguing things (which exists outside of backbone.js) is the idea of javascript templates and defining the html template on the page and then rendering it with javascript. Since I&#8217;ve been using backbone.js it&#8217;s been natural to use the underscore template system but one of the things I found when actually making an application with it is that your source quickly gets cluttered with templates that look like this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='html'><span class='line'><span class="nt">&lt;script </span><span class="na">type=</span><span class="s">&quot;text/template&quot;</span> <span class="na">id=</span><span class="s">&quot;template_on_page&quot;</span><span class="nt">&gt;</span>
</span><span class='line'>    <span class="o">&lt;</span><span class="nx">p</span><span class="o">&gt;</span><span class="nx">This</span> <span class="nx">is</span> <span class="nx">a</span> <span class="nx">template</span> <span class="nx">from</span> <span class="o">&lt;%=</span><span class="nx">template_engine</span><span class="o">%&gt;&lt;</span><span class="err">/p&gt;</span>
</span><span class='line'><span class="nt">&lt;/script&gt;</span>
</span></code></pre></td></tr></table></div></figure>


<p>This works for small pages but on the current app I&#8217;m working on I have over 30 templates defined. Not only does this make for a huge (okay, not really that huge) download but it&#8217;s hard to find and make changes to the templates.</p>

<p>One of the suggestions people have is to put them in external files which solves the second issue but seems very clunky and if I include 30+ external files they&#8217;ll all download on page load no matter what.</p>

<p>The solution, Template Monster. Template monster is a very small and basic script that allows you to queue up or asynchronously download your template files and use them when they&#8217;re needed (or just before). This solves both issues; the templates are no longer all stuffed on the page and we can now only download templates when we need them.</p>

<p>I posted it up on Github and tested it with the underscore.js template system but it should work with any template library. Feel free to send pull requests.</p>

<p><a href="https://github.com/ryanrdetzel/Template-Monster">https://github.com/ryanrdetzel/Template-Monster</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Django 1.4 project and app templates]]></title>
    <link href="http://ryandetzel.com/django-project-app-templates/"/>
    <updated>2012-11-07T10:22:00+00:00</updated>
    <id>http://ryandetzel.com/django-project-app-templates</id>
    <content type="html"><![CDATA[<p>I love Django and I use it for every project but the one thing I hated was having to setup the settings and file/directory structures every time I wanted to start a new project/app. Apparently I wasn&#8217;t the only one that disliked this because starting in Django 1.4 we now have project and app templates to work with.</p>

<blockquote><p>The startapp and startproject management commands now have a &#8211;template option for specifying a path or URL to a custom app or project template.</p></blockquote>

<p>Awesome! What this means is you can setup a project/app just the way you want it and then use that as a template for all future projects or apps you create. So if you like your settings files named foo.py you can do that or if you want your templates directory at the root instead of in each app go ahead and do that too.</p>

<p>I found it fasinating how people setup their projects and I have yet to find another Django developer that does it the exact same way as I do but that might changed now that we have templates. As more people start to create and open source their templates we&#8217;ll start to see a trend and some popular ones will surface just like jQuery did for javascript frameworks and <a href="http://twitter.github.com/bootstrap/">bootstrap</a> did for front-end frameworks. Here are my templates in case you&#8217;re curious:</p>

<p><a href="https://github.com/ryanrdetzel/django-base-template">Project Template</a></p>

<p><a href="https://github.com/ryanrdetzel/django-app-template">App Template</a></p>

<h2>Some tips on using django templates</h2>

<h4>Passing a url</h4>

<p>When you&#8217;re passing the &#8211;template option to startproject or startapp you can use a url instead of a local directory. This means that if you publish your template to a website or <a href="https://github.com/ryanrdetzel/django-base-template">Github</a> you can easily start a new project/app with one command:</p>

<pre><code>django-admin.py startproject --template https://github.com/ryanrdetzel/django-base-template/zipball/master --extension py new_project_name
</code></pre>

<p>Note: If you&#8217;re using github take note of the changes to the path(zipball/master). This tells Github to compress your source into a zipball so it can be downloaded. You&#8217;ll have to do this if you want the template option to pick it up.</p>

<h4>Template tags in your files</h4>

<p>When django is using your template to create a new project/app it does so by rendering certain files through the template engine. This allows you to use tags as you would in a normal django template within your project/app and have them replaced during the process. The startproject provides the following tags.</p>

<ul>
<li>project_name &#8211; the project name as passed to the command</li>
<li>project_directory &#8211; the full path of the newly created project</li>
<li>secret_key &#8211; a random key for the SECRET_KEY setting</li>
</ul>


<p>So if in your settings.py if you want the name of your project(maybe for installed apps) you can simpley use &#8221; and when django is creating your project it will replace this tag with the name you passed into the startproject command.</p>

<p>This works for apps too, the startapp commands surfaces the following tags:</p>

<ul>
<li>app_name &#8211; the app name as passed to the command</li>
<li>app_directory &#8211; the full path of the newly created app</li>
</ul>


<p>Please note this warning which I did come across when playing with this feature.</p>

<blockquote><p>When the app template files are rendered with the Django template engine (by default all *.py files), Django will also replace all stray template variables contained. For example, if one of the Python files contains a docstring explaining a particular feature related to template rendering, it might result in an incorrect example.</p></blockquote>

<p>To work around this problem, you can use the templatetag to &#8220;escape&#8221; the various parts of the template syntax or don&#8217;t use any variables that you don&#8217;t want replaced in your templates. ;-) I hit this when I tried to include my app template in my project template. What happend is when I created a new project the  tags were replaced with nothing since the startproject command tried to render them first. Instead of escaping I felt it was best to break the app template out anyway so I would use it individually.</p>

<p>Hopefully this gives you enough information on templates to start researching and creating your own. Hit me up in the comments if you&#8217;ve published your template, as I said it&#8217;s always interesting to see how others setup their projects and I might borrow some ideas from your template to include in my own.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Swap redis servers without downtime]]></title>
    <link href="http://ryandetzel.com/swap-redis-servers-without-downtime/"/>
    <updated>2012-09-20T00:39:00+00:00</updated>
    <id>http://ryandetzel.com/swap-redis-servers-without-downtime</id>
    <content type="html"><![CDATA[<p>I use Redis for a lot of things ever since I first discovered it a few years ago. It&#8217;s fast, it&#8217;s easy to setup and it has some really great features. One of the projects I use it for is recording/tracking metrics on our site. Basically, as requests come into our Django app we do some analysis on it and push a snippet into a redis queue for later retrieval. I do this because it&#8217;s really really fast and I don&#8217;t have to worry about slowing down the request. Recently we needed to upgrade some servers which required me to move the redis server to another location and much to my surprise redis has a built in feature that allows for quick and easy master swap with zero downtime.</p>

<p>I could give step by step instructions but it&#8217;s dead simple and they do a pretty good job of <a href="http://redis.io/topics/admin">explaining it on their blog</a>. The swap took literaly five minutes and we didn&#8217;t miss one single impression during the swap over.</p>

<p>I love you Redis.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[1,532 days without a code change. How a pet project that hasn't been touched in over four years still gets daily signups.]]></title>
    <link href="http://ryandetzel.com/1532-days-without-a-code-change/"/>
    <updated>2012-07-13T07:24:00+00:00</updated>
    <id>http://ryandetzel.com/1532-days-without-a-code-change</id>
    <content type="html"><![CDATA[<p>The other day I got a phone call coming home from vacation. The call was from a New York number that wasn&#8217;t in my contacts which usually I&#8217;d ignore but since my brother was in NY I figured maybe it was a friend of his and something had gone wrong so I answered it. On the other end was a very faint voice, she asked cautiously, &#8220;Hi…is this the owner of Invoice Journal?&#8221;. I hesitated, in the 4+ years of running Invoice Journal I&#8217;ve never received a phone call so a million thoughts rushed through my mind before stumbling to answer &#8220;Yes&#8221;. &#8220;Okay, Umm, do you know when the site will be back up? I&#8217;ve been using this for all of my invoices and I haven&#8217;t been able to get on in days.&#8221; She uttered. &#8220;I really need to get my invoices out so if the site isn&#8217;t coming back up could you please send me the invoices I have in the system?&#8221;.</p>

<blockquote><p>Okay, Umm, do you know when the site will be back up? I&#8217;ve been using this for all of my invoices and I haven&#8217;t been able to get on in days.</p></blockquote>

<p>Hmm, at first I was a little taken back since I hadn&#8217;t thought about nor touched Invoice Journal in over four years. I had forgotten about it, I had neglected it, I had basically written it off but this soft voice reminded me that all though I had written it off she had not and that she actually relied on it to run her business. I was amazed. Being caught off guard and not really sure why it was in fact down I told her I was currently in the car but as soon as I got home I would check on the site and bring it back up for her. The call ended and for the next two hours Invoice Journal kept popping in my head.</p>

<p>Invoice Journal started as a pet project to occupy my time as I commuted on the train into work. I had roughly two hours of free time on the train everyday to do something so I figured why not build something I can use and learn something new in the process. At that point in time I was doing a decent amount of freelance work and being the cheap bastard that I am didn&#8217;t want to pay a service like Freshbooks to actually handle my invoices for me so I decided to write my own. From start to finish it only took a couple of months working on the train only and during the process I decided to build it in a fashion that anyone could use it once it was done. I never thought that it could actually catch on or that people might actually use it for real invoices. Boy was I wrong.</p>

<p>Later that evening when I arrived home I checked the server and for some reason apache was not running. I was probably messing with it last week and forget to fix an error in the config but a few keystrokes and she was up and running again. To close the loop I shot the women a quick email and she replied thanking me. Tired from a long vacation I crashed.</p>

<p>The next day while in the shower I thought about Invoice Journal again. I wondered, how many people are actually using the system still? Do people still sign up for accounts? I set a reminder(thanks Siri) to check these stats later that night. A few sql queries later and to my absolute amazement this is was I saw.</p>

<p><img src="http://ryandetzel.com/images/posts/invoice.journal.stats.png" alt="Invoice journal stats" /></p>

<p>Not only were people still using it consistently to invoice clients but 130+ people on average were still signing up each month with zero advertising, zero promotional emails, zero effort at all. WTF? I hadn&#8217;t touched this code in over 4 years(4 years, 2 months, and 12 days to be exact), how is it possible that people still signup and use this after all this time. It must have major bugs in it, it must be missing major features that other services offer…this was crazy! Now I&#8217;m wondering if I had continued to work on it, if I hadn&#8217;t neglected it could it actually be a useful successful, dare I say profitable project?</p>

<p>Now, as for why this is happening I can only guess that I&#8217;m offering something a lot of budget conscious people(freelancers) are looking for. I&#8217;m really curious to pull some additional metrics like who has the most invoices, what&#8217;s the longest running user, and what&#8217;s the total dollar amount processed but I&#8217;ll save that for another night.</p>

<p>Unfortunately, I don&#8217;t have time to fix it up. It&#8217;s been way too long and I&#8217;ve moved on from Perl(I&#8217;m a Python boy now). I&#8217;d almost be afraid to look at the code and fix things for fear of breaking it for the people that are actively using it. As far as I can tell I have two options; I can let it run as is or I can find someone eager to take it over….any takers? :-)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Pandora, your iPhone app sucks in the car, here is the code to fix it]]></title>
    <link href="http://ryandetzel.com/pandora-iphone-app-in-the-car/"/>
    <updated>2012-06-21T18:05:00+00:00</updated>
    <id>http://ryandetzel.com/pandora-iphone-app-in-the-car</id>
    <content type="html"><![CDATA[<p>I can&#8217;t be the first person to notice this and I&#8217;m really surprised that a public company(or am I?) has taken this long to update their app so that it&#8217;s even close to their competition. Anyway, let me explain my three pet peeves with the Pandora app while in the car.</p>

<p>First, the damn interface buttons are too small and too close together for quick glances. A day doesn&#8217;t go by where I don&#8217;t pause instead of skip or skip(Arg!) instead of pause.  Since there is no tactical feedback on the iPhone I have to physically look down at the device to change songs; Bad idea when I&#8217;m cruising 80 mph down the Mass Pike. Instead why don&#8217;t you offer swipe to skip and double tap to pause/play. This would allow me to skips songs and/or play/pause with not so much as a glance at the phone. Here&#8217;s the code to implement it.</p>

<blockquote><p>This code is not complete. My Objective-C is a little rusty but it should get the point across on how easy it is to implement these features. This code was not tested so it might not even work. :-P</p></blockquote>




<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
</pre></td><td class='code'><pre><code class='objective-c'><span class='line'><span class="o">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="n">viewDidLoad</span><span class="p">{</span>
</span><span class='line'>    <span class="c1">//...Your other magical code</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">UISwipeGestureRecognizer</span> <span class="o">*</span><span class="n">rightRecognizer</span> <span class="o">=</span> <span class="p">[[</span><span class="n">UISwipeGestureRecognizer</span> <span class="n">alloc</span><span class="p">]</span> <span class="nl">initWithTarget:</span><span class="n">self</span> <span class="nl">action:</span><span class="k">@selector</span><span class="p">(</span><span class="nl">handleSwipe:</span><span class="p">)];</span>
</span><span class='line'>    <span class="n">rightRecognizer</span><span class="p">.</span><span class="n">direction</span> <span class="o">=</span> <span class="n">UISwipeGestureRecognizerDirectionLeft</span><span class="p">;</span>
</span><span class='line'>    <span class="p">[</span><span class="n">self</span><span class="p">.</span><span class="n">view</span> <span class="nl">addGestureRecognizer:</span><span class="n">rightRecognizer</span><span class="p">];</span>
</span><span class='line'>    <span class="p">[</span><span class="n">rightRecognizer</span> <span class="n">release</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">UITapGestureRecognizer</span> <span class="o">*</span><span class="n">doubleTap</span> <span class="o">=</span> <span class="p">[[</span><span class="n">UITapGestureRecognizer</span> <span class="n">alloc</span><span class="p">]</span> <span class="nl">initWithTarget:</span><span class="n">self</span> <span class="nl">action:</span><span class="k">@selector</span><span class="p">(</span><span class="nl">handleDoubleTap:</span><span class="p">)];</span>
</span><span class='line'>    <span class="p">[</span><span class="n">doubleTap</span> <span class="nl">setNumberOfTapsRequired:</span><span class="mi">2</span><span class="p">];</span>
</span><span class='line'>    <span class="p">[</span><span class="n">self</span><span class="p">.</span><span class="n">view</span> <span class="nl">addGestureRecognizer:</span><span class="n">doubleTap</span><span class="p">];</span>
</span><span class='line'>    <span class="p">[</span><span class="n">doubleTap</span> <span class="n">release</span><span class="p">];</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="o">-</span> <span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nl">handleSwipe:</span><span class="p">(</span><span class="n">UISwipeGestureRecognizer</span><span class="o">*</span><span class="p">)</span><span class="n">gestureRecognizer</span> <span class="p">{</span>
</span><span class='line'>    <span class="c1">// Skip!</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="o">-</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="nl">handleDoubleTap:</span><span class="p">(</span><span class="n">UISwipeGestureRecognizer</span><span class="o">*</span><span class="p">)</span><span class="n">gestureRecognizer</span><span class="p">{</span>
</span><span class='line'>    <span class="c1">//If currently playing</span>
</span><span class='line'>        <span class="c1">// Pause</span>
</span><span class='line'>    <span class="c1">//Else</span>
</span><span class='line'>        <span class="c1">// Play</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>The other thing that really grinds my gears is when you pop up that damn &#8220;Sorry, our music licenses&#8230;&#8221; alert. Sure I get why you have to alert me that I&#8217;ve skipped too many times but the alert interface(again while driving) is horrible. I skip(while trying to avoid the play button) and nothing happens. Damn, I have to look down again and I see the message and now I have to look even longer and aim for the OK button to dismiss it. Pain in the ass! A simple audible alert and a modal that fades away would be perfect. Here&#8217;s the code, help yourself.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
</pre></td><td class='code'><pre><code class='objective-c'><span class='line'><span class="o">-</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="n">handleLicenseWarning</span><span class="p">{</span>
</span><span class='line'>    <span class="cm">/* You already have this function, change that damn alert to this */</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">NSURL</span> <span class="o">*</span><span class="n">soundFileURL</span> <span class="o">=</span> <span class="p">[</span><span class="n">NSURL</span> <span class="nl">fileURLWithPath:</span><span class="p">[[</span><span class="n">NSBundle</span> <span class="n">mainBundle</span><span class="p">]</span> <span class="nl">pathForResource:</span><span class="s">@&quot;bong.mp3&quot;</span> <span class="nl">ofType:</span><span class="s">@&quot;mp3&quot;</span><span class="p">]];</span>
</span><span class='line'>    <span class="n">AVAudioPlayer</span> <span class="o">*</span><span class="n">player</span> <span class="o">=</span> <span class="p">[[</span><span class="n">AVAudioPlayer</span> <span class="n">alloc</span><span class="p">]</span> <span class="nl">initWithContentsOfURL:</span><span class="n">soundFileURL</span> <span class="nl">error:</span><span class="nb">nil</span><span class="p">];</span>
</span><span class='line'>    <span class="p">[</span><span class="n">player</span> <span class="n">play</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">UIView</span> <span class="o">*</span><span class="n">licenseWarning</span> <span class="o">=</span> <span class="p">[[</span><span class="n">UIView</span> <span class="n">alloc</span><span class="p">]</span> <span class="nl">initWithFrame:</span><span class="n">CGRectMake</span><span class="p">(</span><span class="n">self</span><span class="p">.</span><span class="n">view</span><span class="p">.</span><span class="n">frame</span><span class="p">.</span><span class="n">size</span><span class="p">.</span><span class="n">width</span><span class="o">/</span><span class="mi">2</span><span class="o">-</span><span class="mi">100</span><span class="p">,</span>
</span><span class='line'>                                                                                                                                            <span class="n">self</span><span class="p">.</span><span class="n">view</span><span class="p">.</span><span class="n">frame</span><span class="p">.</span><span class="n">size</span><span class="p">.</span><span class="n">width</span><span class="o">/</span><span class="mi">2</span><span class="o">-</span><span class="mi">50</span><span class="p">,</span>
</span><span class='line'>                                                                                                                                            <span class="mi">200</span><span class="p">,</span> <span class="mi">100</span><span class="p">)];</span>
</span><span class='line'>    <span class="p">[</span><span class="n">licenseWarning</span> <span class="nl">setBackgroundColor:</span><span class="p">[</span><span class="n">UIColor</span> <span class="n">darkGrayColor</span><span class="p">]];</span>
</span><span class='line'>    <span class="p">[</span><span class="n">licenseWarning</span> <span class="nl">setAlpha:</span><span class="mf">0.8</span><span class="p">];</span>
</span><span class='line'>    <span class="p">[</span><span class="n">licenseWarning</span><span class="p">.</span><span class="n">layer</span> <span class="nl">setCornerRadius:</span><span class="mi">8</span><span class="p">];</span>
</span><span class='line'>    <span class="p">[</span><span class="n">licenseWarning</span><span class="p">.</span><span class="n">layer</span> <span class="nl">setMasksToBounds:</span><span class="n">YES</span><span class="p">];</span>
</span><span class='line'>    <span class="p">[</span><span class="n">licenseWarning</span> <span class="nl">setTag:</span><span class="mi">123</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'>    <span class="n">UILabel</span> <span class="o">*</span><span class="n">warning</span> <span class="o">=</span> <span class="p">[[</span><span class="n">UILabel</span> <span class="n">alloc</span><span class="p">]</span> <span class="nl">initWithFrame:</span><span class="n">CGRectMake</span><span class="p">(</span><span class="mi">10</span><span class="p">,</span><span class="mi">10</span><span class="p">,</span><span class="mi">180</span><span class="p">,</span><span class="mi">80</span><span class="p">)];</span>
</span><span class='line'>    <span class="p">[</span><span class="n">warning</span> <span class="nl">setBackgroundColor:</span><span class="p">[</span><span class="n">UIColor</span> <span class="n">clearColor</span><span class="p">]];</span>
</span><span class='line'>    <span class="p">[</span><span class="n">warning</span> <span class="nl">setText:</span><span class="s">@&quot;Blah blah, our license...&quot;</span><span class="p">];</span>
</span><span class='line'>    <span class="p">[</span><span class="n">warning</span> <span class="nl">setTextColor:</span><span class="p">[</span><span class="n">UIColor</span> <span class="n">whiteColor</span><span class="p">]];</span>
</span><span class='line'>    <span class="p">[</span><span class="n">licenseWarning</span> <span class="nl">addSubview:</span><span class="n">warning</span><span class="p">];</span>
</span><span class='line'>    <span class="p">[</span><span class="n">warning</span> <span class="n">release</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'>    <span class="p">[</span><span class="n">self</span><span class="p">.</span><span class="n">view</span> <span class="nl">addSubview:</span><span class="n">licenseWarning</span><span class="p">];</span>
</span><span class='line'>    <span class="p">[</span><span class="n">licenseWarning</span> <span class="n">release</span><span class="p">];</span>
</span><span class='line'>
</span><span class='line'>    <span class="p">[</span><span class="n">NSTimer</span> <span class="nl">scheduledTimerWithTimeInterval:</span><span class="mi">4</span>
</span><span class='line'>                                          <span class="nl">target:</span><span class="n">self</span>
</span><span class='line'>                                        <span class="nl">selector:</span><span class="k">@selector</span><span class="p">(</span><span class="n">hideWarning</span><span class="p">)</span>
</span><span class='line'>                                        <span class="nl">userInfo:</span><span class="nb">nil</span>
</span><span class='line'>                                         <span class="nl">repeats:</span><span class="n">NO</span><span class="p">];</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="o">-</span><span class="p">(</span><span class="kt">void</span><span class="p">)</span><span class="n">hideWarning</span><span class="p">{</span>
</span><span class='line'>    <span class="p">[</span><span class="n">UIView</span> <span class="nl">animateWithDuration:</span><span class="mf">0.5</span> <span class="nl">animations:</span><span class="o">^</span><span class="p">{</span>
</span><span class='line'>        <span class="p">[[</span><span class="n">self</span><span class="p">.</span><span class="n">view</span> <span class="nl">viewWithTag:</span><span class="mi">123</span><span class="p">]</span> <span class="nl">setAlpha:</span><span class="mf">0.0</span><span class="p">];</span>
</span><span class='line'>    <span class="p">}</span> <span class="nl">completion:</span><span class="o">^</span><span class="p">(</span><span class="kt">BOOL</span> <span class="n">b</span><span class="p">){</span>
</span><span class='line'>        <span class="p">[[</span><span class="n">self</span><span class="p">.</span><span class="n">view</span> <span class="nl">viewWithTag:</span><span class="mi">123</span><span class="p">]</span> <span class="n">removeFromSuperview</span><span class="p">];</span>
</span><span class='line'>    <span class="p">}];</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>I&#8217;ll expect these features in your next release which is coming any day now, right?</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Getting gzip to work with Amazon's CloudFront and nginx]]></title>
    <link href="http://ryandetzel.com/using-amazons-cloudfront-with-nginx/"/>
    <updated>2012-05-25T12:35:00+00:00</updated>
    <id>http://ryandetzel.com/using-amazons-cloudfront-with-nginx</id>
    <content type="html"><![CDATA[<p>I spent way too much time trying to figure out why CloudFront wouldn&#8217;t accept and serve my gzip&#8217;d content so I&#8217;m posting this hoping that I can save someone else some time.</p>

<p>Instead of diving into the issues with cloudfront and nginx I&#8217;ll just provide you with the settings that ended up working for me. The two settings to make note of are the gzip_http_version which is set to 1.0 and the gzip_proxied setting which is set to any. Buffers, comp_level and types can all be changed to fit what you&#8217;re trying to serve.</p>

<figure class='code'><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class=''><span class='line'>gzip on;
</span><span class='line'>gzip_http_version 1.0;
</span><span class='line'>gzip_buffers    4 8k;
</span><span class='line'>gzip_vary on;
</span><span class='line'>gzip_proxied any;
</span><span class='line'>gzip_comp_level 9;
</span><span class='line'>gzip_types text/plain text/html text/css application/x-javascript text/xml application/xml application/xml+rss text/javascript image/png image/gif image/jpeg;</span></code></pre></td></tr></table></div></figure>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[AWS Security Group Cleanse]]></title>
    <link href="http://ryandetzel.com/aws-security-group-cleanse/"/>
    <updated>2012-05-21T14:15:00+00:00</updated>
    <id>http://ryandetzel.com/aws-security-group-cleanse</id>
    <content type="html"><![CDATA[<p>One afternoon while I was adding an ip to our AWS security group I noticed that we had almost 70 rules listed under one group most of which I had no clue what they were for. Over the past two years rules have been added as new servers were spun up, office ips changed and various employee added their home ip addresses. As part of our security month I set out to clean this up and maker sure it stays clean by automating the process.</p>

<p>Amazon&#8217;s interface for managing this is severely lacking mainly because they&#8217;ve built a system on APIs and thus the power comes from taping into those. My plan for this is to write a python script that when run will revoke old rules and add new ones based off the rules defined in the file. There will be three sections; one for ssh access which will be where developers deposit their ips, one for local servers which should only be used for other AWS instances and one for publicly accessible ports(web,ssl, etc)</p>

<p>Here&#8217;s how the rules will be laid out in the file:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
</pre></td><td class='code'><pre><code class='python'><span class='line'><span class="c">## Add your home ip addresses here</span>
</span><span class='line'><span class="n">ALLOWED_SSH</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;23.xx.xx.xx&#39;</span><span class="p">,</span> <span class="c">## Office</span>
</span><span class='line'>                              <span class="p">]</span>
</span><span class='line'>
</span><span class='line'><span class="c">## Server IPs that are given full access</span>
</span><span class='line'><span class="n">INTERNAL</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;10.xxx.xx.xxx&#39;</span><span class="p">,</span> <span class="c"># misc</span>
</span><span class='line'>            <span class="s">&#39;10.xxx.xx.xxx&#39;</span><span class="p">,</span> <span class="c"># static</span>
</span><span class='line'>            <span class="s">&#39;10.xxx.xx.xxx&#39;</span><span class="p">,</span> <span class="c"># solr</span>
</span><span class='line'>            <span class="s">&#39;10.xxx.xx.xxx&#39;</span>  <span class="c"># www</span>
</span><span class='line'>           <span class="p">]</span>
</span><span class='line'>
</span><span class='line'><span class="n">PRODUCTION_RULES</span> <span class="o">=</span> <span class="p">[</span>
</span><span class='line'>    <span class="n">Rule</span><span class="p">(</span><span class="s">&quot;tcp&quot;</span><span class="p">,</span> <span class="s">&quot;80&quot;</span><span class="p">,</span>  <span class="s">&quot;80&quot;</span><span class="p">,</span> <span class="s">&quot;0.0.0.0/0&quot;</span><span class="p">,</span> <span class="bp">None</span><span class="p">),</span>    <span class="c"># web</span>
</span><span class='line'>    <span class="n">Rule</span><span class="p">(</span><span class="s">&quot;tcp&quot;</span><span class="p">,</span> <span class="s">&quot;443&quot;</span><span class="p">,</span> <span class="s">&quot;443&quot;</span><span class="p">,</span> <span class="s">&quot;0.0.0.0/0&quot;</span><span class="p">,</span> <span class="bp">None</span><span class="p">),</span>   <span class="c"># ssl </span>
</span><span class='line'>    <span class="n">Rule</span><span class="p">(</span><span class="s">&quot;tcp&quot;</span><span class="p">,</span> <span class="s">&quot;8080&quot;</span><span class="p">,</span> <span class="s">&quot;8080&quot;</span><span class="p">,</span> <span class="s">&quot;0.0.0.0/0&quot;</span><span class="p">,</span> <span class="bp">None</span><span class="p">),</span> <span class="c"># solr</span>
</span><span class='line'><span class="p">]</span>
</span></code></pre></td></tr></table></div></figure>


<p>The plan is to join these rules and revoke rules no longer in the list and authorize new ones that were added. By breaking it up like this and allowing comments it should be easy to keep our security group clutter free.</p>

<p>Here is the full script that runs nightly.</p>

<figure class='code'><figcaption><span> (aws-security.py)</span> <a href='http://ryandetzel.com/downloads/code/aws-security.py'>download</a></figcaption>
 <div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
<span class='line-number'>66</span>
<span class='line-number'>67</span>
<span class='line-number'>68</span>
<span class='line-number'>69</span>
<span class='line-number'>70</span>
<span class='line-number'>71</span>
<span class='line-number'>72</span>
</pre></td><td class='code'><pre><code class='py'><span class='line'><span class="kn">import</span> <span class="nn">collections</span>
</span><span class='line'><span class="kn">import</span> <span class="nn">boto</span>
</span><span class='line'>
</span><span class='line'><span class="n">group</span> <span class="o">=</span> <span class="s">&#39;ProductionSecurity&#39;</span>
</span><span class='line'><span class="n">dry_run</span> <span class="o">=</span> <span class="bp">True</span>
</span><span class='line'>
</span><span class='line'><span class="k">if</span> <span class="n">dry_run</span><span class="p">:</span>
</span><span class='line'>    <span class="k">print</span> <span class="s">&quot;** DRY RUN **</span><span class="se">\n</span><span class="s">No changes will be made&quot;</span>
</span><span class='line'>
</span><span class='line'><span class="n">Rule</span> <span class="o">=</span> <span class="n">collections</span><span class="o">.</span><span class="n">namedtuple</span><span class="p">(</span><span class="s">&quot;rules&quot;</span><span class="p">,</span> <span class="p">[</span><span class="s">&quot;protocol&quot;</span><span class="p">,</span>
</span><span class='line'>                                        <span class="s">&quot;from_port&quot;</span><span class="p">,</span>
</span><span class='line'>                                        <span class="s">&quot;to_port&quot;</span><span class="p">,</span>
</span><span class='line'>                                        <span class="s">&quot;ip&quot;</span><span class="p">,</span>
</span><span class='line'>                                        <span class="s">&quot;group_name&quot;</span><span class="p">])</span>
</span><span class='line'>
</span><span class='line'><span class="c">## these ips are allowed to ssh into all machines</span>
</span><span class='line'><span class="n">ALLOWED_SSH</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;23.xx.xx.xx&#39;</span><span class="p">,</span> <span class="c">## Office</span>
</span><span class='line'>               <span class="p">]</span>
</span><span class='line'>
</span><span class='line'><span class="c">## Server IPs that are given full access</span>
</span><span class='line'><span class="n">INTERNAL</span> <span class="o">=</span> <span class="p">[</span><span class="s">&#39;10.xxx.xx.xxx&#39;</span><span class="p">,</span> <span class="c"># misc</span>
</span><span class='line'>            <span class="s">&#39;10.xxx.xx.xxx&#39;</span><span class="p">,</span> <span class="c"># static</span>
</span><span class='line'>            <span class="s">&#39;10.xxx.xx.xxx&#39;</span><span class="p">,</span> <span class="c"># solr</span>
</span><span class='line'>            <span class="s">&#39;10.xxx.xx.xxx&#39;</span>  <span class="c"># www</span>
</span><span class='line'>            <span class="p">]</span>
</span><span class='line'>
</span><span class='line'><span class="n">PRODUCTION_RULES</span> <span class="o">=</span> <span class="p">[</span>
</span><span class='line'>    <span class="n">Rule</span><span class="p">(</span><span class="s">&quot;tcp&quot;</span><span class="p">,</span> <span class="s">&quot;80&quot;</span><span class="p">,</span>  <span class="s">&quot;80&quot;</span><span class="p">,</span> <span class="s">&quot;0.0.0.0/0&quot;</span><span class="p">,</span> <span class="bp">None</span><span class="p">),</span>    <span class="c"># web</span>
</span><span class='line'>    <span class="n">Rule</span><span class="p">(</span><span class="s">&quot;tcp&quot;</span><span class="p">,</span> <span class="s">&quot;443&quot;</span><span class="p">,</span> <span class="s">&quot;443&quot;</span><span class="p">,</span> <span class="s">&quot;0.0.0.0/0&quot;</span><span class="p">,</span> <span class="bp">None</span><span class="p">),</span>   <span class="c"># ssl </span>
</span><span class='line'>    <span class="n">Rule</span><span class="p">(</span><span class="s">&quot;tcp&quot;</span><span class="p">,</span> <span class="s">&quot;8080&quot;</span><span class="p">,</span> <span class="s">&quot;8080&quot;</span><span class="p">,</span> <span class="s">&quot;0.0.0.0/0&quot;</span><span class="p">,</span> <span class="bp">None</span><span class="p">),</span> <span class="c"># solr</span>
</span><span class='line'><span class="p">]</span>
</span><span class='line'>
</span><span class='line'><span class="k">for</span> <span class="n">ip</span> <span class="ow">in</span> <span class="n">ALLOWED_SSH</span><span class="p">:</span>
</span><span class='line'>    <span class="n">PRODUCTION_RULES</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">Rule</span><span class="p">(</span><span class="s">&quot;tcp&quot;</span><span class="p">,</span><span class="s">&quot;22&quot;</span><span class="p">,</span><span class="s">&quot;22&quot;</span><span class="p">,</span><span class="s">&quot;</span><span class="si">%s</span><span class="s">/32&quot;</span> <span class="o">%</span> <span class="n">ip</span><span class="p">,</span><span class="bp">None</span><span class="p">))</span>
</span><span class='line'>
</span><span class='line'><span class="k">for</span> <span class="n">ip</span> <span class="ow">in</span> <span class="n">INTERNAL</span><span class="p">:</span>
</span><span class='line'>    <span class="n">PRODUCTION_RULES</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">Rule</span><span class="p">(</span><span class="s">&quot;tcp&quot;</span><span class="p">,</span><span class="s">&quot;0&quot;</span><span class="p">,</span><span class="s">&quot;65535&quot;</span><span class="p">,</span><span class="s">&quot;</span><span class="si">%s</span><span class="s">/32&quot;</span> <span class="o">%</span> <span class="n">ip</span><span class="p">,</span><span class="bp">None</span><span class="p">))</span>
</span><span class='line'>
</span><span class='line'><span class="n">conn</span> <span class="o">=</span> <span class="n">boto</span><span class="o">.</span><span class="n">connect_ec2</span><span class="p">()</span>
</span><span class='line'><span class="n">groups</span> <span class="o">=</span> <span class="p">[</span><span class="n">g</span> <span class="k">for</span> <span class="n">g</span> <span class="ow">in</span> <span class="n">conn</span><span class="o">.</span><span class="n">get_all_security_groups</span><span class="p">()</span> <span class="k">if</span> <span class="n">g</span><span class="o">.</span><span class="n">name</span> <span class="o">==</span> <span class="n">group</span><span class="p">]</span>
</span><span class='line'><span class="n">group</span> <span class="o">=</span> <span class="n">groups</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span>
</span><span class='line'>
</span><span class='line'><span class="n">existing</span> <span class="o">=</span> <span class="p">[]</span>
</span><span class='line'><span class="k">for</span> <span class="n">rule</span> <span class="ow">in</span> <span class="n">group</span><span class="o">.</span><span class="n">rules</span><span class="p">:</span>
</span><span class='line'>    <span class="k">for</span> <span class="n">ip</span> <span class="ow">in</span> <span class="n">rule</span><span class="o">.</span><span class="n">grants</span><span class="p">:</span>
</span><span class='line'>        <span class="n">rule_check</span> <span class="o">=</span> <span class="n">Rule</span><span class="p">(</span><span class="n">rule</span><span class="o">.</span><span class="n">ip_protocol</span><span class="p">,</span>
</span><span class='line'>                                    <span class="n">rule</span><span class="o">.</span><span class="n">from_port</span><span class="p">,</span>
</span><span class='line'>                                    <span class="n">rule</span><span class="o">.</span><span class="n">to_port</span><span class="p">,</span>
</span><span class='line'>                                    <span class="s">&quot;</span><span class="si">%s</span><span class="s">&quot;</span> <span class="o">%</span> <span class="n">ip</span><span class="p">,</span>
</span><span class='line'>                                    <span class="bp">None</span><span class="p">)</span>
</span><span class='line'>        <span class="k">if</span> <span class="n">rule_check</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">PRODUCTION_RULES</span><span class="p">:</span>
</span><span class='line'>            <span class="k">if</span> <span class="n">rule</span><span class="o">.</span><span class="n">ip_protocol</span> <span class="o">==</span> <span class="s">&quot;tcp&quot;</span><span class="p">:</span>
</span><span class='line'>                <span class="k">print</span> <span class="s">&quot;Revoking </span><span class="si">%s</span><span class="s"> (</span><span class="si">%s</span><span class="s">-</span><span class="si">%s</span><span class="s">)&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">ip</span><span class="p">,</span><span class="n">rule</span><span class="o">.</span><span class="n">from_port</span><span class="p">,</span><span class="n">rule</span><span class="o">.</span><span class="n">to_port</span><span class="p">)</span>
</span><span class='line'>                <span class="k">if</span> <span class="ow">not</span> <span class="n">dry_run</span><span class="p">:</span>
</span><span class='line'>                    <span class="n">group</span><span class="o">.</span><span class="n">revoke</span><span class="p">(</span><span class="n">ip_protocol</span><span class="o">=</span><span class="n">rule</span><span class="o">.</span><span class="n">ip_protocol</span><span class="p">,</span>
</span><span class='line'>                                <span class="n">from_port</span><span class="o">=</span><span class="n">rule</span><span class="o">.</span><span class="n">from_port</span><span class="p">,</span>
</span><span class='line'>                                <span class="n">to_port</span><span class="o">=</span><span class="n">rule</span><span class="o">.</span><span class="n">to_port</span><span class="p">,</span>
</span><span class='line'>                                <span class="n">cidr_ip</span><span class="o">=</span><span class="n">ip</span><span class="p">,</span>
</span><span class='line'>                                <span class="n">src_group</span><span class="o">=</span><span class="bp">None</span><span class="p">)</span>
</span><span class='line'>        <span class="k">else</span><span class="p">:</span>
</span><span class='line'>            <span class="n">existing</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">rule_check</span><span class="p">)</span>
</span><span class='line'>
</span><span class='line'><span class="c">## Fill in missing rules </span>
</span><span class='line'><span class="k">for</span> <span class="n">rule</span> <span class="ow">in</span> <span class="n">PRODUCTION_RULES</span><span class="p">:</span>
</span><span class='line'>    <span class="k">if</span> <span class="n">rule</span> <span class="ow">not</span> <span class="ow">in</span> <span class="n">existing</span><span class="p">:</span>
</span><span class='line'>        <span class="k">print</span> <span class="s">&quot;Authorizing </span><span class="si">%s</span><span class="s"> (</span><span class="si">%s</span><span class="s">-</span><span class="si">%s</span><span class="s">)&quot;</span> <span class="o">%</span> <span class="p">(</span><span class="n">rule</span><span class="o">.</span><span class="n">ip</span><span class="p">,</span><span class="n">rule</span><span class="o">.</span><span class="n">from_port</span><span class="p">,</span><span class="n">rule</span><span class="o">.</span><span class="n">to_port</span><span class="p">)</span>
</span><span class='line'>        <span class="k">if</span> <span class="ow">not</span> <span class="n">dry_run</span><span class="p">:</span>
</span><span class='line'>            <span class="n">group</span><span class="o">.</span><span class="n">authorize</span><span class="p">(</span><span class="n">ip_protocol</span><span class="o">=</span><span class="n">rule</span><span class="o">.</span><span class="n">protocol</span><span class="p">,</span>
</span><span class='line'>                            <span class="n">from_port</span><span class="o">=</span><span class="n">rule</span><span class="o">.</span><span class="n">from_port</span><span class="p">,</span>
</span><span class='line'>                            <span class="n">to_port</span><span class="o">=</span><span class="n">rule</span><span class="o">.</span><span class="n">to_port</span><span class="p">,</span>
</span><span class='line'>                            <span class="n">cidr_ip</span><span class="o">=</span><span class="n">rule</span><span class="o">.</span><span class="n">ip</span><span class="p">,</span>
</span><span class='line'>                            <span class="n">src_group</span><span class="o">=</span><span class="bp">None</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>


<h3>TODO</h3>

<p>One flaw with this system is you have to have access to the code to add an ip. An issue I&#8217;d like to solve soon is when you need to add an ip temporarily(coffee shop, airport, hotel, etc). Ideally I&#8217;d like to add a system where you email and ip to a certain address and it adds it for you either temporarily or permanently depending on what address you sent it to.</p>

<p>There is also no reason besides laziness that all servers should have all ports open internally. You&#8217;ll noticed that all the ips in the INTERNAL list get full access to the other servers which is not a good idea. I should change this to list out what ports should be open and for which servers. For example we probably only need to open ssh, mysql, memcached and redis between the servers.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How all disputes should be settled.]]></title>
    <link href="http://ryandetzel.com/how-all-disputes-should-be-settled/"/>
    <updated>2012-04-11T08:41:00+00:00</updated>
    <id>http://ryandetzel.com/how-all-disputes-should-be-settled</id>
    <content type="html"><![CDATA[<p><img src="http://ryandetzel.com/images/posts/notch-quick3.png" alt="Quick 3 challenge" /></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Code sharing dilemma.]]></title>
    <link href="http://ryandetzel.com/code-sharing-delemma/"/>
    <updated>2012-02-17T13:30:00+00:00</updated>
    <id>http://ryandetzel.com/code-sharing-delemma</id>
    <content type="html"><![CDATA[<p>Should I share code when I know it&#8217;s not going to add any value to the Internet and only clutter it with more useless spam content?</p>

<p>An old colleague contacted me recently congratulating me on my cool script I wrote. We wont get into the details of the script but it was a bot that performed a certain task and since this person is following me he was able to spot it.  Since I&#8217;ve worked with him in the past and he mentioned he&#8217;s been trying to do something similar I offered up the code. I thought he was going to use it for his job, maybe they were trying to do something similar to what we&#8217;re doing so there is no harm in that. After I sent off the code he messaged me back thanking me and telling me his true intentions.  He planned on using the script to basically spam the Internet with useless pages filled with ads.  Ugh. Maybe I should&#8217;ve asked him what he was going to use it for first; maybe I shouldn&#8217;t care but either way I couldn&#8217;t help but feel responsible for cluttering up the Internet with more useless content.  I wish him luck on his ventures but going forward I&#8217;m probably going to be more reluctant to share clever code so I can avoid such moral dilemmas in the future.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Changing over to Amazon RDS]]></title>
    <link href="http://ryandetzel.com/changing-over-to-amazon-rds/"/>
    <updated>2011-11-02T08:30:00+00:00</updated>
    <id>http://ryandetzel.com/changing-over-to-amazon-rds</id>
    <content type="html"><![CDATA[<p>We moved our dedicated mysql server over to RDS a couple of months ago and I would suggest to anyone that can justify a dedicated sql box to do so too.</p>

<p><strong>Pros</strong></p>

<ul>
<li>Reboots quickly and easily</li>
<li>No software updates, no security patches to deal with</li>
<li>Start/stop additional resources quickly and easily.</li>
<li>Hot standby is really easy to setup</li>
<li>Read replica&#8217;s are super easy to setup too</li>
<li>Hot snapshots beat mysqldumps</li>
<li>Price. It&#8217;s nice to start and stop instances when you need more</li>
</ul>


<p><strong>Cons</strong></p>

<ul>
<li>You loose a lot of control so if something goes wrong you feel helpless.</li>
<li>Along the same lines it&#8217;s a shared box which puts you in the dark</li>
<li>You have to use a round-about system to changed mysql parameters.(turning on the slow query log for example)</li>
<li>Price. You&#8217;re paying more than an ec2 instance and you can only use it as a database server</li>
</ul>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Google Optimizer's strange noscript tag.]]></title>
    <link href="http://ryandetzel.com/google-optimizer-noscript-tag/"/>
    <updated>2011-10-20T13:30:00+00:00</updated>
    <id>http://ryandetzel.com/google-optimizer-noscript-tag</id>
    <content type="html"><![CDATA[<p>If you&#8217;ve ever installed Google Optimizer code you&#8217;ll notice they ask you to do something like this:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="o">&lt;</span><span class="nx">script</span><span class="o">&gt;</span>
</span><span class='line'>    <span class="nx">utmx_func</span><span class="p">(</span><span class="s1">&#39;name&#39;</span><span class="p">);</span>
</span><span class='line'><span class="o">&lt;</span><span class="err">/script&gt;</span>
</span><span class='line'><span class="nx">This</span> <span class="nx">is</span> <span class="nx">my</span> <span class="k">default</span> <span class="nx">version</span>
</span><span class='line'><span class="o">&lt;</span><span class="err">/noscript&gt; </span>
</span></code></pre></td></tr></table></div></figure>


<p>This breaks validation(do people still care about that?) and it looks odd but they are doing something pretty clever here. A quick stop over at jsbeautifier.org let me peek into their code to discover how this works.  Basically since there is no beginning noscript tag the default text will always show even if the JS above it breaks which is a must in case something goes wrong(Google shouldn&#8217;t break your site).  So how does the different version of the code get shown? Simple, when the function runs it prints the new content to the page along with the opening noscript tag which in turn hides the default text.  The new content ends up looking like:</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="o">&lt;</span><span class="nx">script</span><span class="o">&gt;</span>
</span><span class='line'>    <span class="nx">utmx_func</span><span class="p">(</span><span class="s1">&#39;name&#39;</span><span class="p">);</span>
</span><span class='line'><span class="o">&lt;</span><span class="err">/script&gt;</span>
</span><span class='line'><span class="nx">This</span> <span class="nx">is</span> <span class="nx">my</span> <span class="k">new</span> <span class="nx">text</span> <span class="nx">I</span> <span class="nx">want</span> <span class="nx">shown</span><span class="p">.</span>
</span><span class='line'><span class="o">&lt;</span><span class="nx">noscript</span><span class="o">&gt;</span>
</span><span class='line'>    <span class="nx">This</span> <span class="nx">is</span> <span class="nx">my</span> <span class="k">default</span> <span class="nx">version</span>
</span><span class='line'><span class="o">&lt;</span><span class="err">/noscript&gt; </span>
</span></code></pre></td></tr></table></div></figure>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Use RGB LEDs to create visual error codes for your Arduino projects.]]></title>
    <link href="http://ryandetzel.com/rgb-led-arduino/"/>
    <updated>2010-02-23T03:10:00+00:00</updated>
    <id>http://ryandetzel.com/rgb-led-arduino</id>
    <content type="html"><![CDATA[<p>If you own an xbox 360 then you’ve probably heard of the “three rings of death”. When Microsoft created the xbox 360 they built in a series of functions that blink the front lights in different sequences to indicate hardware issues. This is a great use of leds for visual feedback, as long as the xbox turns on you can get immediate feedback as to what’s wrong even if you can’t get video. So, I figured why not take this same approach and bring it my Arduino projects so that I can quickly and easily debug my projects even if it’s not hooked up to my computer or LCD display.</p>

<p><img src="http://ryandetzel.com/images/posts/arduino/led-error/led2.JPG" alt="" />
<img src="http://ryandetzel.com/images/posts/arduino/led-error/led5.JPG" alt="" /></p>

<blockquote><p>I’ve based this project off error codes but you could just as easy use it for normal operations. Maybe when your circuit goes into a certain mode you could change the colors, or when it’s starting up it could be red and when it’s ready to go it could turn to green. An example of this type of operation is the Playstation 3, when it’s turning on and off it flashes and changes colors giving some indication what’s going on while there is nothing on the screen.</p></blockquote>


<h2>Hardware Setup</h2>

<p>For my project I’m using a standard Arduino Duemilanove and two RGB LEDs. Since they’re RGB LEDs I’m capable of displaying nine basic error codes.</p>

<p><img src="http://ryandetzel.com/images/posts/arduino/led-error/led_board.jpg" alt="" /></p>

<blockquote><p>In addition to the three primary colors you could also display multiple colors at once and/or blink the leds giving an even greater selection of combinations. e.g. two fast blinks means X, while three fast blinks means Y.</p></blockquote>


<h2>Software</h2>

<p>This sketch it meant to show you how easy it is to use RGB LEDs to display error messages. This is not a complete sketch but simply a snippet of how I use this in my own projects.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
<span class='line-number'>66</span>
<span class='line-number'>67</span>
<span class='line-number'>68</span>
<span class='line-number'>69</span>
<span class='line-number'>70</span>
<span class='line-number'>71</span>
<span class='line-number'>72</span>
<span class='line-number'>73</span>
<span class='line-number'>74</span>
<span class='line-number'>75</span>
<span class='line-number'>76</span>
<span class='line-number'>77</span>
<span class='line-number'>78</span>
<span class='line-number'>79</span>
<span class='line-number'>80</span>
<span class='line-number'>81</span>
<span class='line-number'>82</span>
<span class='line-number'>83</span>
<span class='line-number'>84</span>
<span class='line-number'>85</span>
<span class='line-number'>86</span>
<span class='line-number'>87</span>
<span class='line-number'>88</span>
<span class='line-number'>89</span>
<span class='line-number'>90</span>
<span class='line-number'>91</span>
<span class='line-number'>92</span>
<span class='line-number'>93</span>
<span class='line-number'>94</span>
<span class='line-number'>95</span>
<span class='line-number'>96</span>
<span class='line-number'>97</span>
<span class='line-number'>98</span>
<span class='line-number'>99</span>
<span class='line-number'>100</span>
<span class='line-number'>101</span>
</pre></td><td class='code'><pre><code class='c'><span class='line'><span class="kt">int</span> <span class="n">led1_red</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
</span><span class='line'><span class="kt">int</span> <span class="n">led1_green</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span>
</span><span class='line'><span class="kt">int</span> <span class="n">led1_blue</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="kt">int</span> <span class="n">led2_red</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>
</span><span class='line'><span class="kt">int</span> <span class="n">led2_green</span> <span class="o">=</span> <span class="mi">11</span><span class="p">;</span>
</span><span class='line'><span class="kt">int</span> <span class="n">led2_blue</span> <span class="o">=</span> <span class="mi">12</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="cp">#define RED 0</span>
</span><span class='line'><span class="cp">#define GREEN 1</span>
</span><span class='line'><span class="cp">#define BLUE 2</span>
</span><span class='line'>
</span><span class='line'><span class="cp">/* I prefer to name my errors */</span>
</span><span class='line'><span class="cp">#define INVALID_INPUT 1</span>
</span><span class='line'><span class="cp">#define INPUT_OUT_OF_RANGE 2</span>
</span><span class='line'><span class="cp">#define BATTERY_LOW 3</span>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span> <span class="n">setup</span><span class="p">(){</span>
</span><span class='line'>  <span class="n">pinMode</span><span class="p">(</span><span class="n">led1_red</span><span class="p">,</span> <span class="n">OUTPUT</span><span class="p">);</span>
</span><span class='line'>  <span class="n">pinMode</span><span class="p">(</span><span class="n">led1_green</span><span class="p">,</span> <span class="n">OUTPUT</span><span class="p">);</span>
</span><span class='line'>  <span class="n">pinMode</span><span class="p">(</span><span class="n">led1_blue</span><span class="p">,</span> <span class="n">OUTPUT</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">pinMode</span><span class="p">(</span><span class="n">led2_red</span><span class="p">,</span> <span class="n">OUTPUT</span><span class="p">);</span>
</span><span class='line'>  <span class="n">pinMode</span><span class="p">(</span><span class="n">led2_green</span><span class="p">,</span> <span class="n">OUTPUT</span><span class="p">);</span>
</span><span class='line'>  <span class="n">pinMode</span><span class="p">(</span><span class="n">led2_blue</span><span class="p">,</span> <span class="n">OUTPUT</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>  <span class="n">reset_error</span><span class="p">();</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span> <span class="n">loop</span><span class="p">(){</span>
</span><span class='line'>  <span class="cm">/* My normal code, do some operations */</span>
</span><span class='line'>  <span class="cm">/* .... */</span>
</span><span class='line'>  <span class="cm">/* Opps, there was an error with the input, lets display an error message */</span>
</span><span class='line'>  <span class="n">display_error</span><span class="p">(</span><span class="n">INVALID_INPUT</span><span class="p">);</span>
</span><span class='line'>  <span class="n">delay</span><span class="p">(</span><span class="mi">5000</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>  <span class="cm">/* Later on, we accept some input and it&#39;s out of range */</span>
</span><span class='line'>  <span class="n">display_error</span><span class="p">(</span><span class="n">INPUT_OUT_OF_RANGE</span><span class="p">);</span>
</span><span class='line'>  <span class="n">delay</span><span class="p">(</span><span class="mi">5000</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'>  <span class="cm">/* Lets check the battery and issue a warning if it&#39;s low */</span>
</span><span class='line'>  <span class="n">display_error</span><span class="p">(</span><span class="n">BATTERY_LOW</span><span class="p">);</span>
</span><span class='line'>  <span class="n">delay</span><span class="p">(</span><span class="mi">5000</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span> <span class="n">reset_error</span><span class="p">(){</span>
</span><span class='line'>    <span class="n">digitalWrite</span><span class="p">(</span><span class="n">led1_red</span><span class="p">,</span> <span class="n">LOW</span><span class="p">);</span>
</span><span class='line'>    <span class="n">digitalWrite</span><span class="p">(</span><span class="n">led1_green</span><span class="p">,</span> <span class="n">LOW</span><span class="p">);</span>
</span><span class='line'>    <span class="n">digitalWrite</span><span class="p">(</span><span class="n">led1_blue</span><span class="p">,</span> <span class="n">LOW</span><span class="p">);</span>
</span><span class='line'>    <span class="n">digitalWrite</span><span class="p">(</span><span class="n">led2_red</span><span class="p">,</span> <span class="n">LOW</span><span class="p">);</span>
</span><span class='line'>    <span class="n">digitalWrite</span><span class="p">(</span><span class="n">led2_green</span><span class="p">,</span> <span class="n">LOW</span><span class="p">);</span>
</span><span class='line'>    <span class="n">digitalWrite</span><span class="p">(</span><span class="n">led2_blue</span><span class="p">,</span> <span class="n">LOW</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span> <span class="n">display_error</span><span class="p">(</span><span class="kt">int</span> <span class="n">error_code</span><span class="p">){</span>
</span><span class='line'>  <span class="kt">int</span> <span class="n">led1</span><span class="p">,</span><span class="n">led2</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">switch</span><span class="p">(</span><span class="n">error_code</span><span class="p">){</span>
</span><span class='line'>    <span class="k">case</span> <span class="mi">1</span>:  <span class="n">led1</span> <span class="o">=</span> <span class="n">RED</span><span class="p">;</span>    <span class="n">led2</span> <span class="o">=</span> <span class="n">RED</span><span class="p">;</span>    <span class="k">break</span><span class="p">;</span>
</span><span class='line'>    <span class="k">case</span> <span class="mi">2</span>:  <span class="n">led1</span> <span class="o">=</span> <span class="n">RED</span><span class="p">;</span>    <span class="n">led2</span> <span class="o">=</span> <span class="n">GREEN</span><span class="p">;</span>  <span class="k">break</span><span class="p">;</span>
</span><span class='line'>    <span class="k">case</span> <span class="mi">3</span>:  <span class="n">led1</span> <span class="o">=</span> <span class="n">RED</span><span class="p">;</span>    <span class="n">led2</span> <span class="o">=</span> <span class="n">BLUE</span><span class="p">;</span>   <span class="k">break</span><span class="p">;</span>
</span><span class='line'>    <span class="k">case</span> <span class="mi">4</span>:  <span class="n">led1</span> <span class="o">=</span> <span class="n">GREEN</span><span class="p">;</span>  <span class="n">led2</span> <span class="o">=</span> <span class="n">GREEN</span><span class="p">;</span>  <span class="k">break</span><span class="p">;</span>
</span><span class='line'>    <span class="k">case</span> <span class="mi">5</span>:  <span class="n">led1</span> <span class="o">=</span> <span class="n">GREEN</span><span class="p">;</span>  <span class="n">led2</span> <span class="o">=</span> <span class="n">BLUE</span><span class="p">;</span>   <span class="k">break</span><span class="p">;</span>
</span><span class='line'>    <span class="k">case</span> <span class="mi">6</span>:  <span class="n">led1</span> <span class="o">=</span> <span class="n">GREEN</span><span class="p">;</span>  <span class="n">led2</span> <span class="o">=</span> <span class="n">RED</span><span class="p">;</span>    <span class="k">break</span><span class="p">;</span>
</span><span class='line'>    <span class="k">case</span> <span class="mi">7</span>:  <span class="n">led1</span> <span class="o">=</span> <span class="n">BLUE</span><span class="p">;</span>   <span class="n">led2</span> <span class="o">=</span> <span class="n">BLUE</span><span class="p">;</span>   <span class="k">break</span><span class="p">;</span>
</span><span class='line'>    <span class="k">case</span> <span class="mi">8</span>:  <span class="n">led1</span> <span class="o">=</span> <span class="n">BLUE</span><span class="p">;</span>   <span class="n">led2</span> <span class="o">=</span> <span class="n">RED</span><span class="p">;</span>    <span class="k">break</span><span class="p">;</span>
</span><span class='line'>    <span class="k">case</span> <span class="mi">9</span>:  <span class="n">led1</span> <span class="o">=</span> <span class="n">BLUE</span><span class="p">;</span>   <span class="n">led2</span> <span class="o">=</span> <span class="n">GREEN</span><span class="p">;</span>  <span class="k">break</span><span class="p">;</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">if</span> <span class="p">(</span><span class="n">led1</span> <span class="o">==</span> <span class="n">RED</span><span class="p">){</span>
</span><span class='line'>    <span class="n">digitalWrite</span><span class="p">(</span><span class="n">led1_red</span><span class="p">,</span> <span class="n">HIGH</span><span class="p">);</span>
</span><span class='line'>    <span class="n">digitalWrite</span><span class="p">(</span><span class="n">led1_green</span><span class="p">,</span> <span class="n">LOW</span><span class="p">);</span>
</span><span class='line'>    <span class="n">digitalWrite</span><span class="p">(</span><span class="n">led1_blue</span><span class="p">,</span> <span class="n">LOW</span><span class="p">);</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">led1</span> <span class="o">==</span> <span class="n">GREEN</span><span class="p">){</span>
</span><span class='line'>    <span class="n">digitalWrite</span><span class="p">(</span><span class="n">led1_red</span><span class="p">,</span> <span class="n">LOW</span><span class="p">);</span>
</span><span class='line'>    <span class="n">digitalWrite</span><span class="p">(</span><span class="n">led1_green</span><span class="p">,</span> <span class="n">HIGH</span><span class="p">);</span>
</span><span class='line'>    <span class="n">digitalWrite</span><span class="p">(</span><span class="n">led1_blue</span><span class="p">,</span> <span class="n">LOW</span><span class="p">);</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">led1</span> <span class="o">==</span> <span class="n">BLUE</span><span class="p">){</span>
</span><span class='line'>    <span class="n">digitalWrite</span><span class="p">(</span><span class="n">led1_red</span><span class="p">,</span> <span class="n">LOW</span><span class="p">);</span>
</span><span class='line'>    <span class="n">digitalWrite</span><span class="p">(</span><span class="n">led1_green</span><span class="p">,</span> <span class="n">LOW</span><span class="p">);</span>
</span><span class='line'>    <span class="n">digitalWrite</span><span class="p">(</span><span class="n">led1_blue</span><span class="p">,</span> <span class="n">HIGH</span><span class="p">);</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>
</span><span class='line'>  <span class="k">if</span> <span class="p">(</span><span class="n">led2</span> <span class="o">==</span> <span class="n">RED</span><span class="p">){</span>
</span><span class='line'>    <span class="n">digitalWrite</span><span class="p">(</span><span class="n">led2_red</span><span class="p">,</span> <span class="n">HIGH</span><span class="p">);</span>
</span><span class='line'>    <span class="n">digitalWrite</span><span class="p">(</span><span class="n">led2_green</span><span class="p">,</span> <span class="n">LOW</span><span class="p">);</span>
</span><span class='line'>    <span class="n">digitalWrite</span><span class="p">(</span><span class="n">led2_blue</span><span class="p">,</span> <span class="n">LOW</span><span class="p">);</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">led2</span> <span class="o">==</span> <span class="n">GREEN</span><span class="p">){</span>
</span><span class='line'>    <span class="n">digitalWrite</span><span class="p">(</span><span class="n">led2_red</span><span class="p">,</span> <span class="n">LOW</span><span class="p">);</span>
</span><span class='line'>    <span class="n">digitalWrite</span><span class="p">(</span><span class="n">led2_green</span><span class="p">,</span> <span class="n">HIGH</span><span class="p">);</span>
</span><span class='line'>    <span class="n">digitalWrite</span><span class="p">(</span><span class="n">led2_blue</span><span class="p">,</span> <span class="n">LOW</span><span class="p">);</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'>  <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">led2</span> <span class="o">==</span> <span class="n">BLUE</span><span class="p">){</span>
</span><span class='line'>    <span class="n">digitalWrite</span><span class="p">(</span><span class="n">led2_red</span><span class="p">,</span> <span class="n">LOW</span><span class="p">);</span>
</span><span class='line'>    <span class="n">digitalWrite</span><span class="p">(</span><span class="n">led2_green</span><span class="p">,</span> <span class="n">LOW</span><span class="p">);</span>
</span><span class='line'>    <span class="n">digitalWrite</span><span class="p">(</span><span class="n">led2_blue</span><span class="p">,</span> <span class="n">HIGH</span><span class="p">);</span>
</span><span class='line'>  <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>Basically what this code does is it calls(displays) three different error messages. If this were a real project these errors would not just loop back and forth but they would only show up when something was wrong. Typically my projects contain 3-6 different errors, the table below shows the different combinations I can display using the above display_error</p>

<table style="width:500px;">
<tbody><tr>
<td><b>Led 1</b></td>
<td><b>Led 2</b></td>
<td><b>Error Code</b></td>
</tr>
<tr>
<td style="color:red">R</td>
<td style="color:red">R</td>
<td>1</td>
</tr>
<tr>
<td style="color:red">R</td>
<td style="color:green">G</td>
<td>2</td>
</tr>
<tr>
<td style="color:red">R</td>
<td style="color:blue">B</td>
<td>3</td>
</tr>
<tr>
<td style="color:green">G</td>
<td style="color:green">G</td>
<td>4</td>
</tr>
<tr>
<td style="color:green">G</td>
<td style="color:blue">B</td>
<td>5</td>
</tr>
<tr>
<td style="color:green">G</td>
<td style="color:red">R</td>
<td>6</td>
</tr>
<tr>
<td style="color:blue">B</td>
<td style="color:blue">B</td>
<td>7</td>
</tr>
<tr>
<td style="color:blue">B</td>
<td style="color:red">R</td>
<td>8</td>
</tr>
<tr>
<td style="color:blue">B</td>
<td style="color:green">G</td>
<td>9</td>
</tr>
</tbody></table>


<p>Below are some additional pictures and a video showing the circuit in action. Do you have any thoughts or ideas for this project, post them in the comments section below? I have a bunch of other ideas that I will be sharing shortly, the RGB LEDs are a great way to add feedback to your Arduino [or other] projects. Simply adding an additional two LEDs to this circuit we could generate over 80 combinations!</p>

<p><img src="http://ryandetzel.com/images/posts/arduino/led-error/led3.JPG" alt="" />
<img src="http://ryandetzel.com/images/posts/arduino/led-error/led4.JPG" alt="" /></p>

<object width="480" height="360"><param name="allowfullscreen" value="true"><param name="allowscriptaccess" value="always"><param name="movie" value="http://vimeo.com/moogaloop.swf?clip_id=9678138&amp;server=vimeo.com&amp;show_title=0&amp;show_byline=0&amp;show_portrait=1&amp;color=ffffff&amp;fullscreen=1"><embed src="http://vimeo.com/moogaloop.swf?clip_id=9678138&amp;server=vimeo.com&amp;show_title=0&amp;show_byline=0&amp;show_portrait=1&amp;color=ffffff&amp;fullscreen=1" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="480" height="360"></object>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Writing your first Arduino sketch; Hello World!]]></title>
    <link href="http://ryandetzel.com/arduino-first-sketch/"/>
    <updated>2010-02-18T02:20:00+00:00</updated>
    <id>http://ryandetzel.com/arduino-first-sketch</id>
    <content type="html"><![CDATA[<p>When starting a new hobby whether it’s programming or electronics it’s always a good idea to start with a basic program to make sure everything is working correctly. This workshop will verify that your Arduino hardware is working and that you’ve installed and setup the Arduino software correctly. We’ll walk you through the basic steps needed to write and install your first Arduino program.</p>

<h2>Supplies Needed</h2>

<ul>
<li>1 x Arduino Duemilanove or equivalent.</li>
<li>1 x USB cable to connect the Arduino to your computer</li>
<li>1 x Red LED light. Other colors will work but verify the resistor value.</li>
<li>1 x 150 ohm resistor</li>
</ul>


<blockquote><p>This workshop uses the built in LED on the Arduino Duemilanove. If you’re using an Arduino Duemilanove clone or you would rather use an external LED then you’ll need to connect an LED and a resistor to digital pin 13.</p></blockquote>


<h2>Prerequisites</h2>

<p>In order to write and install Arduino projects you’ll need the Arduino software. The software is rather straight forward to install so if you don’t already have it simply head over to the official Arduino website to download the most recent version. Follow the instructions on the Arduino getting started section to complete the software setup process.</p>

<h2>Step 1</h2>

<p>Lets first hook up the Arduino board. Plug the USB cable into the Arduino Duemilanove board and then into your computer. If everything is hooked up correctly the power led should be lit up on the Arduino board. If you’re using the standard Duemilanove board you are now done with the hardware setup and can proceed to step 2. If you’re using a Arduino clone that doesn’t have a built-in LED or you’ve chosen to use an external LED simply follow the schematic below to attach the resistor and LED to the Arduino.</p>

<p><img src="http://ryandetzel.com/images/posts/arduino/writing-your-first-arduino-sketch/arduino-hello-world-schematic.png" alt="" /></p>

<h2>Step 2</h2>

<p>Now that the hardware part is done we can now get started on writing the program(also known as a sketch. Open up the Arduino application and type the below code into the editor; we’ll go over what it does below.</p>

<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
</pre></td><td class='code'><pre><code class='c'><span class='line'><span class="kt">int</span> <span class="n">ledPin</span> <span class="o">=</span>  <span class="mi">13</span><span class="p">;</span>
</span><span class='line'><span class="kt">void</span> <span class="n">setup</span><span class="p">(){</span>
</span><span class='line'>  <span class="n">pinMode</span><span class="p">(</span><span class="n">ledPin</span><span class="p">,</span> <span class="n">OUTPUT</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span> <span class="n">loop</span><span class="p">(){</span>
</span><span class='line'>  <span class="n">digitalWrite</span><span class="p">(</span><span class="n">ledPin</span><span class="p">,</span> <span class="n">HIGH</span><span class="p">);</span>
</span><span class='line'>  <span class="n">delay</span><span class="p">(</span><span class="mi">1000</span><span class="p">);</span>
</span><span class='line'>  <span class="n">digitalWrite</span><span class="p">(</span><span class="n">ledPin</span><span class="p">,</span> <span class="n">LOW</span><span class="p">);</span>
</span><span class='line'>  <span class="n">delay</span><span class="p">(</span><span class="mi">1000</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>


<p>All Arduino sketches need to have two functions, setup() and loop(). These functions can be empty but they are required. The setup function shown on lines 3-5 is used to setup initial values and is only executed once at the start of your program. This function is called when the Arduino first boots up and then the loop() function is called continuously until the Arduino looses power.</p>

<p>Back to the top you can see that the first line initializes a variable named ledPin to the number 13. For this sketch we’re only using one digital pin and we’ve chosen 13 because on the Arduino Duemilanove this pin is attached to the built-in LED. Having variables at the top like this allows us to easily change them but for simple sketches you could always hardcode the value directly into the function call that use it; for example line 8 could just as well be written as digitalWrite(13, HIGH). Next we have the setup function which as mentioned above is only run when the Arduino boots. For this sketch we need to enable pin 13 as output using the pinMode function. This function accepts two arguments. The first argument is the pin number we want to set the mode for and the second is the mode we want to set that pin to which can either be INPUT or OUTPUT. Basically this tells the Microprocessor how to handle that pin, should it treat it as input and listen for changes or as output and write data to it.</p>

<p>Finally we have the loop function which is run after the setup function and will loop repeatedly as long as the Arduino has power. First we want to set digital pin 13 to high so we can light up the LED. In order to do this we call the digitalWrite function which accepts two arguments, the pin number we want to write to and the value we want to write to that pin which can either be HIGH or LOW. After we set the pin to high we want to pause the program for a certain amount of time so we can physical see the LED light up; the built-in function delay allows us to do just that. The argument passed into the delay function is the amount of time you want your program to pause in milliseconds. For this program we want to pause for 1 second so we delay for 1000 milliseconds but feel free to experiment with this value to make the LED blink faster or slower. Next we do a digital write again on pin 13 but this time we pull the pin LOW to shut the LED off. We delay for another 1 second and then the loop starts all over repeating the cycle of OFF, Delay, ON, Delay until the Arduino loses power.</p>

<p>Congratulations you’ve completed your first Arduino program. Go ahead and compile the sketch, install it on the Arduino and watch the LED blink!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Arduino Duemilanove Overview]]></title>
    <link href="http://ryandetzel.com/arduino-duemilanove-overview/"/>
    <updated>2010-02-17T07:20:00+00:00</updated>
    <id>http://ryandetzel.com/arduino-duemilanove-overview</id>
    <content type="html"><![CDATA[<blockquote><p>Please note that the information on this page is in regards to the official Arduino Duemilanove. Since the Duemilanoves release in 2009 there have been many clones that work and look very similar. For all intents and purposes these clones should work exactly the same but there may be slight variations in the pin layout and power requirements so please read the datasheet.</p></blockquote>


<h2>Arduino Duemilanove Introduction</h2>

<p>The Arduino Duemilanove (Duemilanove means 2009 in Italian) is a microcontroller board based on the ATmega168 or ATmega328. It has 14 digital pins (of which 6 can be used as PWM outputs), 6 analog inputs, a 16 MHz crystal oscillator, a USB connection, a power jack, an ICSP header, and a reset button. The Duemilanove comes built with everything you need to get started so using and programming the Arduino Duemilanove is as simple as connecting it to your computers USB port and installing the Arduino software.</p>

<p>While there are a many great things that make the Arduino Duemilanove great I think I can sum it up in two words; simple and flexible. The Arduino is such a great idea, it makes the complex world of microcontrollers so easy that it literally takes ~$30 and a computer to get started.</p>

<p>When the Arduino was born in 2005 the idea was to create an open-source prototyping platform that was built around available and affordable hardware and to release it to the world so that others could not only learn and benefit from it but also contribute back to it. One of the reasons I quickly fell in love with the Arduino was because a simple Internet search returned tons of results including demo circuits, example programs(sketches), and add-on boards(shields). Arduino has released a few boards since 2005 including the Diecimila(now superseded by the Duemilanove), the Arduino Mini/Nano and the Arduino Mega. These products are all great but the Arduino Duemilanove pulls everything the Arduino team has learned over the years into one complete easy to use embedded system.</p>

<h2>Arduino Board Breakdown</h2>

<p>The Arduino Duemilanove may look intimating at first glance but in reality you only need to know about some main components to take full advantage of what the Arduino has to offer. Lets take a look at the image below and I’ll explain what the numbers represent on the Arduino board.</p>

<p><img src="http://ryandetzel.com/images/posts/arduino/arduino-duemilanove/arduino_front.jpg" alt="" />
<img src="http://ryandetzel.com/images/posts/arduino/arduino-duemilanove/arduino_scale.jpg" alt="" /></p>

<ol>
<li>USB connector. The Arduino Duemilanove has a built in FT232RL chip which allows your computer to communicate via TTL serial data with the Arduino. This connector also provides the Arduino Duemilanove with 5v of power when connected to a computer so no external power supply is needed.</li>
<li>2.1mm center-positive barrel plug which allows you to power the Arduino from an external power supply like a wall-wart or battery pack. The Arduino Duemilanove can operate on an external supply of 6 to 20 volts but it’s recommended you provide it with at least 7v to keep it stable and under 12v to prevent overheating.</li>
<li>ATmega168/ATmega328 Microprocessor. This is the brains of the Arduino Duemilanove and since it’s in an easy to access DIP-28 package the chip can easily be removed and replaced if needed.</li>
<li>Digital pins(0-13) with a GND pin and the AREF(Reference voltage) pin. You can ignore the AREF pin for this is rarely used and it’s not worth discussing in this article.</li>
<li>Analog Pins(0-5).</li>
<li>Reset, 3.3v, 5v, GND, and Vin. When the reset pin is pulled low the Arduino resets. The 3.3v pin provides 3.3 volts with a max current draw of 50ma. The 5v pin can either be used as a 5v source if the Arduino is powered via an external power supply or a regulated 5v supply can be fed into the pin to provide power to the Arduino. Vin is the voltage in pin and can either be used to access the voltage of an external power source (if provided) or voltage can be supplied to this pin to power the Arduino.</li>
<li>The ICSP connector. These pins are used when you want to program the ATmega chip directly and for the most part we’ll be ignoring it.</li>
<li>Reset button. A press of this button pulls down the reset pin and resets the Arduino.</li>
<li>LED’s. To the left of the number 9 in the picture above we have an LED that is attached to digital pin 13 and the TX and RX LEDs so show when the serial connection is in use. Just under the number 8 is the power LED which illuminates when the Arduino has power.</li>
</ol>


<p><img src="http://ryandetzel.com/images/posts/arduino/arduino-duemilanove/arduino_analog_pins.jpg" alt="" />
<img src="http://ryandetzel.com/images/posts/arduino/arduino-duemilanove/arduino_digital_pins.jpg" alt="" /></p>

<p>Now that you’ve had a brief overview of what the Arduino Duemilanove is and what it’s made up of I suggest you head over to our first workshop on Writing your first Arduino sketch. We’ve given you the basics but to fully understand the power and beauty of the Arduino Duemilanove we suggest you get your hands dirty and start creating some stuff!</p>
]]></content>
  </entry>
  
</feed>
