King'ori's Code Minutae
http://kingori.co/favicon.ico
http://kingori.co/assets/images/logo-dark-24@2x.png
2023-12-19T13:03:55+00:00
King'ori Maina
http://kingori.co/
kingori.co:/feeds/minutae.xml
Copyright © 2013-2023, Job King'ori Maina; all rights reserved.
Programming Fatigue ∞
2016-02-19T00:00:00+00:00
kingori.co:/minutae/2016/02/programming-fatigue/
<p>This was published as “<a href="http://www.2ality.com/2016/02/js-fatigue-fatigue.html?imm_mid=0e0972&cmp=em-web-na-na-newsltr_20160217">JavaScript fatigue fatigue</a>” but I feel it
applies to programming in general.</p>
<blockquote>
<p>Enough with the fatigue – tips against feeling overwhelmed:</p>
<ul>
<li>Don’t try to know everything – it’s impossible in modern web development.
Given that there is always more to know, it doesn’t matter that much what
you learn (unless you have a specific need).
<ul>
<li>Go for depth in areas you love.</li>
<li>Go for breadth and on-demand learning in areas you are merely interested
in or think you should know more about.</li>
</ul>
</li>
<li>Wait for the critical mass. You can often afford to get started by reading
the opinions of people you trust and wait it out until new ideas prove
themselves.</li>
<li>Stick to things you understand: don’t use more than 1–2 new technologies
per project.
<ul>
<li>It’s important to retain at least some feeling of control.</li>
<li>Every technology that people need to learn before they can use your
project raises the barrier of entry and makes it more difficult to find
collaborators, colleagues and employees.</li>
</ul>
</li>
<li>Do exploratory toy projects: I like creating small projects that explore
technologies or aspects of technologies.</li>
<li>Diversify in life: Specializing is good, but it’s also good to have regular
activities not related to tech and/or brain. The advantage is that if you
are frustrated in one area of your life, you have others to fall back on.</li>
<li>Even with the last of the previous tips, I find it important to remain
human. Don’t overdo discipline, don’t become a life improvement machine.
Periods of boredom and doing nothing are important for recuperating and
inspiration.</li>
</ul>
<p>When in doubt about what to learn next, you can always go back to
fundamentals:</p>
<ul>
<li>JavaScript, CSS, etc. (which technologies are fundamental depends on your
work).</li>
<li>Non-technological skills: time management, social skills (communication,
team building, …), health (posture, breathing properly, moving well,
eating well, …), management processes and so on.</li>
</ul>
</blockquote>
<p>
<a title="Permalink to 'Programming Fatigue'" href="http://kingori.co/minutae/2016/02/programming-fatigue/" target="_blank">↩</a>
</p>
King'ori Maina
http://kingori.co/
Rails On Ubuntu
2014-07-14T00:00:00+00:00
kingori.co:/minutae/2014/07/rails-on-ubuntu/
<p>Ubuntu provides a package manager system for installing system software. You’ll
use this to prepare your computer before installing Ruby. However, don’t use
<code class="language-plaintext highlighter-rouge">apt-get</code> to install Ruby. The package manager will install an outdated version
of Ruby. And it will install Ruby at the system level (for all users). It’s
better to use RVM to install Ruby within your user environment.</p>
<p>But if you have an older version of Ruby installed on your computer, there’s no
need to remove it. RVM will leave your “system Ruby” untouched and use your
shell to intercept any calls to Ruby. Any older Ruby versions will remain on
your system and the RVM version will take precedence.</p>
<h3 id="installing-rvm--ruby">Installing RVM & Ruby</h3>
<p>Use <a href="https://rvm.io">RVM, the Ruby Version Manager</a>, to install Ruby and manage your Rails
versions as you might need an easy way to switch between Ruby versions. Just as
important, you’ll have a dependency mess if you install gems into the system
environment. RVM is popular, well-supported, and full-featured.</p>
<p>Here’s the simplest way:</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>curl <span class="nt">-L</span> https://get.rvm.io | bash <span class="nt">-s</span> stable <span class="nt">--ruby</span>
</code></pre></div></div>
<p>The “—ruby” flag will install the newest version of Ruby. RVM includes an
“autolibs” option to identify and install system software needed for your
operating system. If you already have RVM installed, update it to the latest
version and install Ruby:</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>rvm get stable <span class="nt">--autolibs</span><span class="o">=</span><span class="nb">enable</span>
<span class="gp">$</span><span class="w"> </span>rvm <span class="nb">install </span>ruby
<span class="gp">$</span><span class="w"> </span>rvm <span class="nt">--default</span> use ruby-2.1.2
</code></pre></div></div>
<p>To list available Ruby versions, run:</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>rvm list known
</code></pre></div></div>
<p>For example to change to Ruby version 2.0.0-p481, run:</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>rvm <span class="nb">install </span>ruby-2.0.0-p481
</code></pre></div></div>
<h3 id="gems--rubygems">Gems & RubyGems</h3>
<p><a href="http://rubygems.org">RubyGems</a> is the gem manager in Ruby. Use <code class="language-plaintext highlighter-rouge">gem update --system</code> to upgrade
the Ruby gem manager if necessary.</p>
<p>By default, when you install gems, documentation files will be installed.
Developers seldom use gem documentation files (they’ll browse the web instead).
Installing gem documentation files takes time, so many developers like to toggle
the default so no documentation is installed. Here’s how to speed up gem
installation by disabling the documentation step:</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span><span class="nb">echo</span> <span class="s2">"gem: --no-document"</span> <span class="o">>></span> ~/.gemrc
</code></pre></div></div>
<p>This adds the line <code class="language-plaintext highlighter-rouge">gem: --no-document</code> to the hidden <code class="language-plaintext highlighter-rouge">.gemrc</code> file in your home
directory.</p>
<h3 id="installing-rails">Installing Rails</h3>
<p>You can install Rails directly into the global gemset. However, many developers
prefer to keep the global gemset sparse and install Rails into project-specific
gemsets, so each project has the appropriate version of Rails.</p>
<p>If you install Rails at this point, you will install it into the global gemset.
Instead, make a gemset just for the current stable release:</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>rvm use ruby-2.0.0-p481@rails4.1 <span class="nt">--create</span>
</code></pre></div></div>
<p>Install most recent stable release:</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>gem <span class="nb">install </span>rails
<span class="gp">$</span><span class="w"> </span>rails <span class="nt">-v</span>
</code></pre></div></div>
<hr />
<ol>
<li><a href="https://railsapps.github.io/installrubyonrails-ubuntu.html">RailsApps by Daniel Kehoe</a></li>
<li><a href="https://rvm.io">RVM, Ruby Version Manager</a></li>
<li><a href="http://rubygems.org">RubyGems.org</a></li>
</ol>
King'ori Maina
http://kingori.co/
HasteBin
2014-04-11T00:00:00+00:00
kingori.co:/minutae/2014/04/hastebin/
<p>According to <a href="http://hastebin.com/about.md">the official site</a>:</p>
<blockquote>
<p>Haste is the prettiest, easiest to use pastebin ever made.</p>
</blockquote>
<p><a href="https://github.com/seejohnrun/haste-server/archive/master.zip">Download the source</a> and expand it.</p>
<p>Install the <a href="https://www.npmjs.org/">Node.js Package Manager</a> using <a href="http://brew.sh/">Homebrew</a> <em>(for Mac OS)</em>,
like so …</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>brew <span class="nb">install </span>npm
</code></pre></div></div>
<p>Different OS have different package managers, use whatever works for you. For
example … for <a href="http://en.wikipedia.org/wiki/List_of_Linux_distributions#Debian-based">Debian based distro’s</a> you’d probably use <code class="language-plaintext highlighter-rouge">apt-get install
npm</code> and for <a href="http://en.wikipedia.org/wiki/List_of_Linux_distributions#RPM-based">RPM based distro’s</a> would use <code class="language-plaintext highlighter-rouge">yum install npm</code> and so on.</p>
<p>While in the expanded directory install all the required dependencies:</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>npm <span class="nb">install</span>
</code></pre></div></div>
<p>Set the configuration. In my case I didn’t want to use <a href="http://redis.io/">Redis</a> as my data
store and opted to use the filesystem instead, saving the data in
<code class="language-plaintext highlighter-rouge">APP_ROOT/data/</code>. Note the <code class="language-plaintext highlighter-rouge">storage:</code> attribute.</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="nl">"host"</span><span class="p">:</span><span class="w"> </span><span class="s2">"0.0.0.0"</span><span class="p">,</span><span class="w">
</span><span class="nl">"port"</span><span class="p">:</span><span class="w"> </span><span class="mi">7777</span><span class="p">,</span><span class="w">
</span><span class="nl">"keyLength"</span><span class="p">:</span><span class="w"> </span><span class="mi">10</span><span class="p">,</span><span class="w">
</span><span class="nl">"maxLength"</span><span class="p">:</span><span class="w"> </span><span class="mi">400000</span><span class="p">,</span><span class="w">
</span><span class="nl">"staticMaxAge"</span><span class="p">:</span><span class="w"> </span><span class="mi">86400</span><span class="p">,</span><span class="w">
</span><span class="nl">"recompressStaticAssets"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">
</span><span class="nl">"logging"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
</span><span class="p">{</span><span class="w">
</span><span class="nl">"level"</span><span class="p">:</span><span class="w"> </span><span class="s2">"verbose"</span><span class="p">,</span><span class="w">
</span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Console"</span><span class="p">,</span><span class="w">
</span><span class="nl">"colorize"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">],</span><span class="w">
</span><span class="nl">"keyGenerator"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"phonetic"</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="nl">"storage"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"path"</span><span class="p">:</span><span class="w"> </span><span class="s2">"./data"</span><span class="p">,</span><span class="w">
</span><span class="nl">"type"</span><span class="p">:</span><span class="w"> </span><span class="s2">"file"</span><span class="w">
</span><span class="p">},</span><span class="w">
</span><span class="nl">"documents"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
</span><span class="nl">"about"</span><span class="p">:</span><span class="w"> </span><span class="s2">"./about.md"</span><span class="w">
</span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<p>Then start the server:</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>npm start
</code></pre></div></div>
<p>Server should now be running on <em>0.0.0.0:7777</em>.</p>
<p>The above example shows a local deployment, if you want to set up the server in
a publicly accessible (via a network or the internet) … just change the host
and port accordingly.</p>
<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
</span><span class="nl">"host"</span><span class="p">:</span><span class="w"> </span><span class="s2">"example.com"</span><span class="p">,</span><span class="w">
</span><span class="nl">"port"</span><span class="p">:</span><span class="w"> </span><span class="mi">80</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>
<p>Server should now be running on <em>example.com</em> since port 80 is usually the
default port.</p>
<hr />
<ol>
<li><a href="http://hastebin.com/about.md">About HasteBin</a></li>
<li><a href="https://github.com/seejohnrun/haste-server">HasteBin Server source on GitHub</a></li>
<li><a href="https://github.com/seejohnrun/haste-client">HasteBin Client source on GitHub</a></li>
</ol>
King'ori Maina
http://kingori.co/
Minify Jekyll Assets On GitHub Pages Using Sprockets
2014-04-03T00:00:00+00:00
kingori.co:/minutae/2014/04/minify-assets-github-pages/
<p>While there are <a href="http://jekyllrb.com/docs/plugins/">Jekyll plugins</a> to minify assets just like the <a href="http://guides.rubyonrails.org/asset_pipeline.html">Rails Asset
Pipeline</a>, GitHub generates sites using the <code class="language-plaintext highlighter-rouge">--safe</code> option to disable custom
plugins for security reasons. This means that those plugins won’t work.</p>
<p>However, you could store some assets in <code class="language-plaintext highlighter-rouge">_assets/</code>, run the
<code class="language-plaintext highlighter-rouge">_build/preprocess_assets.rb</code> script below to generate the minified files in
<code class="language-plaintext highlighter-rouge">assets</code>.</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">require</span> <span class="s1">'sprockets'</span>
<span class="c1"># Get relevant paths</span>
<span class="n">project_root</span> <span class="o">=</span> <span class="no">File</span><span class="p">.</span><span class="nf">expand_path</span><span class="p">(</span><span class="s1">'..'</span><span class="p">,</span> <span class="no">File</span><span class="p">.</span><span class="nf">dirname</span><span class="p">(</span><span class="kp">__FILE__</span><span class="p">))</span>
<span class="n">app_css_file</span> <span class="o">=</span> <span class="no">File</span><span class="p">.</span><span class="nf">join</span><span class="p">(</span><span class="n">project_root</span><span class="p">,</span> <span class="s1">'assets'</span><span class="p">,</span> <span class="s1">'stylesheets'</span><span class="p">,</span> <span class="s1">'application.css'</span><span class="p">)</span>
<span class="n">app_js_file</span> <span class="o">=</span> <span class="no">File</span><span class="p">.</span><span class="nf">join</span><span class="p">(</span><span class="n">project_root</span><span class="p">,</span> <span class="s1">'assets'</span><span class="p">,</span> <span class="s1">'javascripts'</span><span class="p">,</span> <span class="s1">'application.js'</span><span class="p">)</span>
<span class="c1"># Initialize Sprockets</span>
<span class="n">environment</span> <span class="o">=</span> <span class="no">Sprockets</span><span class="o">::</span><span class="no">Environment</span><span class="p">.</span><span class="nf">new</span>
<span class="n">environment</span><span class="p">.</span><span class="nf">append_path</span><span class="p">(</span><span class="no">File</span><span class="p">.</span><span class="nf">join</span><span class="p">(</span><span class="n">project_root</span><span class="p">,</span> <span class="s1">'_assets'</span><span class="p">,</span> <span class="s1">'javascripts'</span><span class="p">))</span>
<span class="n">environment</span><span class="p">.</span><span class="nf">append_path</span><span class="p">(</span><span class="no">File</span><span class="p">.</span><span class="nf">join</span><span class="p">(</span><span class="n">project_root</span><span class="p">,</span> <span class="s1">'_assets'</span><span class="p">,</span> <span class="s1">'stylesheets'</span><span class="p">))</span>
<span class="c1"># Set configuration</span>
<span class="n">environment</span><span class="p">.</span><span class="nf">js_compressor</span> <span class="o">=</span> <span class="ss">:uglifier</span>
<span class="n">environment</span><span class="p">.</span><span class="nf">css_compressor</span> <span class="o">=</span> <span class="ss">:yui</span>
<span class="c1"># Write minifies JS & CSS into files</span>
<span class="no">File</span><span class="p">.</span><span class="nf">open</span><span class="p">(</span><span class="n">app_css_file</span><span class="p">,</span> <span class="s1">'w'</span><span class="p">)</span> <span class="p">{</span> <span class="o">|</span><span class="n">f</span><span class="o">|</span> <span class="n">f</span><span class="p">.</span><span class="nf">write</span> <span class="n">environment</span><span class="p">[</span><span class="s1">'application.css'</span><span class="p">].</span><span class="nf">to_s</span> <span class="p">}</span>
<span class="no">File</span><span class="p">.</span><span class="nf">open</span><span class="p">(</span><span class="n">app_js_file</span><span class="p">,</span> <span class="s1">'w'</span><span class="p">)</span> <span class="p">{</span> <span class="o">|</span><span class="n">f</span><span class="o">|</span> <span class="n">f</span><span class="p">.</span><span class="nf">write</span> <span class="n">environment</span><span class="p">[</span><span class="s1">'application.js'</span><span class="p">].</span><span class="nf">to_s</span> <span class="p">}</span>
<span class="c1"># See; https://gist.github.com/itskingori/9954229</span>
</code></pre></div></div>
<p>Then push to GitHub. Comment, discuss or view this script <a href="https://gist.github.com/itskingori/9954229">here</a>.</p>
King'ori Maina
http://kingori.co/
Highlight.js & Turbolinks ∞
2014-02-22T00:00:00+00:00
kingori.co:/minutae/2014/02/highlightjs-on-turbolinks/
<p>Seems like <a href="http://highlightjs.org/usage/">highlight.js</a> relies on the conventional on the <code class="language-plaintext highlighter-rouge">ready()</code> event
(or something close to that) to trigger … which is obviously broken by
<a href="https://github.com/rails/turbolinks">Turbolinks</a>.</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">$</span><span class="p">(</span><span class="nb">document</span><span class="p">).</span><span class="nx">on</span><span class="p">(</span><span class="dl">'</span><span class="s1">page:change</span><span class="dl">'</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">hljs</span><span class="p">.</span><span class="nx">initHighlightingOnLoad</span><span class="p">();</span>
<span class="p">});</span>
<span class="nx">$</span><span class="p">(</span><span class="nb">document</span><span class="p">).</span><span class="nx">on</span><span class="p">(</span><span class="dl">'</span><span class="s1">page:restore</span><span class="dl">'</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">hljs</span><span class="p">.</span><span class="nx">initHighlightingOnLoad</span><span class="p">();</span>
<span class="p">});</span>
</code></pre></div></div>
<p>Instead do this …</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">$</span><span class="p">(</span><span class="nb">document</span><span class="p">).</span><span class="nx">on</span><span class="p">(</span><span class="dl">'</span><span class="s1">page:change</span><span class="dl">'</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">$</span><span class="p">(</span><span class="dl">'</span><span class="s1">pre code</span><span class="dl">'</span><span class="p">).</span><span class="nx">each</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">i</span><span class="p">,</span> <span class="nx">e</span><span class="p">)</span> <span class="p">{</span><span class="nx">hljs</span><span class="p">.</span><span class="nx">highlightBlock</span><span class="p">(</span><span class="nx">e</span><span class="p">)});</span>
<span class="p">});</span>
<span class="nx">$</span><span class="p">(</span><span class="nb">document</span><span class="p">).</span><span class="nx">on</span><span class="p">(</span><span class="dl">'</span><span class="s1">page:restore</span><span class="dl">'</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">$</span><span class="p">(</span><span class="dl">'</span><span class="s1">pre code</span><span class="dl">'</span><span class="p">).</span><span class="nx">each</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">i</span><span class="p">,</span> <span class="nx">e</span><span class="p">)</span> <span class="p">{</span><span class="nx">hljs</span><span class="p">.</span><span class="nx">highlightBlock</span><span class="p">(</span><span class="nx">e</span><span class="p">)});</span>
<span class="p">});</span>
</code></pre></div></div>
<p>
<a title="Permalink to 'Highlight.js & Turbolinks'" href="http://kingori.co/minutae/2014/02/highlightjs-on-turbolinks/" target="_blank">↩</a>
</p>
King'ori Maina
http://kingori.co/
Install AWS Command Line Tools Using Homebrew
2013-11-22T00:00:00+00:00
kingori.co:/minutae/2013/11/aws-cli-homebrew/
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>brew <span class="nb">install </span>auto-scaling
<span class="gp">$</span><span class="w"> </span>brew <span class="nb">install </span>aws-cfn-tools
<span class="gp">$</span><span class="w"> </span>brew <span class="nb">install </span>aws-elasticache
<span class="gp">$</span><span class="w"> </span>brew <span class="nb">install </span>aws-elasticbeanstalk
<span class="gp">$</span><span class="w"> </span>brew <span class="nb">install </span>aws-iam-tools
<span class="gp">$</span><span class="w"> </span>brew <span class="nb">install </span>aws-sns-cli
<span class="gp">$</span><span class="w"> </span>brew <span class="nb">install </span>cloud-watch
<span class="gp">$</span><span class="w"> </span>brew <span class="nb">install </span>ec2-ami-tools
<span class="gp">$</span><span class="w"> </span>brew <span class="nb">install </span>ec2-api-tools
<span class="gp">$</span><span class="w"> </span>brew <span class="nb">install </span>elb-tools
<span class="gp">$</span><span class="w"> </span>brew <span class="nb">install </span>rds-command-line-tools
</code></pre></div></div>
<p>Add these to your environment …</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">export </span><span class="nv">JAVA_HOME</span><span class="o">=</span><span class="s2">"</span><span class="si">$(</span>/usr/libexec/java_home<span class="si">)</span><span class="s2">"</span>
<span class="nb">export </span><span class="nv">EC2_PRIVATE_KEY</span><span class="o">=</span><span class="s2">"</span><span class="si">$(</span>/bin/ls <span class="s2">"</span><span class="nv">$HOME</span><span class="s2">"</span>/.ec2/pk-<span class="k">*</span>.pem | /usr/bin/head <span class="nt">-1</span><span class="si">)</span><span class="s2">"</span>
<span class="nb">export </span><span class="nv">EC2_CERT</span><span class="o">=</span><span class="s2">"</span><span class="si">$(</span>/bin/ls <span class="s2">"</span><span class="nv">$HOME</span><span class="s2">"</span>/.ec2/cert-<span class="k">*</span>.pem | /usr/bin/head <span class="nt">-1</span><span class="si">)</span><span class="s2">"</span>
<span class="nb">export </span><span class="nv">AWS_AUTO_SCALING_HOME</span><span class="o">=</span><span class="s2">"/usr/local/Cellar/auto-scaling/1.0.61.3/libexec"</span>
<span class="nb">export </span><span class="nv">AWS_CLOUDFORMATION_HOME</span><span class="o">=</span><span class="s2">"/usr/local/Cellar/aws-cfn-tools/1.0.12/libexec"</span>
<span class="nb">export </span><span class="nv">AWS_CREDENTIAL_FILE</span><span class="o">=</span><span class="s2">"<Path to the credentials file>"</span>
<span class="nb">export </span><span class="nv">AWS_ELASTICACHE_HOME</span><span class="o">=</span><span class="s2">"/usr/local/Cellar/aws-elasticache/1.9.000/libexec"</span>
<span class="nb">export </span><span class="nv">AWS_ELB_HOME</span><span class="o">=</span><span class="s2">"/usr/local/Cellar/elb-tools/1.0.23.0/libexec"</span>
<span class="nb">export </span><span class="nv">EC2_HOME</span><span class="o">=</span><span class="s2">"/usr/local/Cellar/ec2-api-tools/1.6.12.0/libexec"</span>
<span class="nb">export </span><span class="nv">AWS_IAM_HOME</span><span class="o">=</span><span class="s2">"/usr/local/opt/aws-iam-tools/jars"</span>
<span class="nb">export </span><span class="nv">AWS_CREDENTIAL_FILE</span><span class="o">=</span><span class="nv">$HOME</span>/.aws-credentials-master
<span class="nb">export </span><span class="nv">AWS_SNS_HOME</span><span class="o">=</span><span class="s2">"/usr/local/Cellar/aws-sns-cli/2013-09-27/libexec"</span>
<span class="nb">export </span><span class="nv">AWS_CLOUDWATCH_HOME</span><span class="o">=</span><span class="s2">"/usr/local/Cellar/cloud-watch/1.0.13.4/libexec"</span>
<span class="nb">export </span><span class="nv">SERVICE_HOME</span><span class="o">=</span><span class="s2">"</span><span class="nv">$AWS_CLOUDWATCH_HOME</span><span class="s2">"</span>
<span class="nb">export </span><span class="nv">EC2_AMITOOL_HOME</span><span class="o">=</span><span class="s2">"/usr/local/Cellar/ec2-ami-tools/1.4.0.9/libexec"</span>
<span class="nb">export </span><span class="nv">AWS_RDS_HOME</span><span class="o">=</span><span class="s2">"/usr/local/Cellar/rds-command-line-tools/1.14.001/libexec"</span>
</code></pre></div></div>
<p>Thanks to <a href="http://clayrichardson.me/2013/03/29/brew-install-all-available-aws-tools/">this guy …</a></p>
King'ori Maina
http://kingori.co/
How To Filter Out What's Been Archived From All Mail (In GMail)
2013-11-04T00:00:00+00:00
kingori.co:/minutae/2013/11/clean-up-gmail-archive/
<p>In the Gmail search box, type …</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>-label:inbox -label:sent -label:drafts -label:trash -label:notes
</code></pre></div></div>
<p>This should give you all your archived messages (excluding the emails in the
inbox, sent, drafts, trash and notes).</p>
<p>You also probably want to consider changing the IMAP action after an email is
deleted from archiving the email (default) to sending the deleted email to
‘Trash’.</p>
<p>I prefer the latter, since it places the deleted email in the most sensible
place - ‘Trash’. And deleting the email from ‘Trash’ now permanently deletes it
and archiving does the obvious - archive. Keeping your ‘All Mail’ much cleaner.</p>
<p><em>Ps: If you have other custom labels you’ll need to add them in there as well.</em></p>
King'ori Maina
http://kingori.co/
Set MySQL Instead Of SQLite3 As Default In New Rails App
2013-08-12T00:00:00+00:00
kingori.co:/minutae/2013/08/rails-with-mysql/
<p>Normally we would do something like <code class="language-plaintext highlighter-rouge">rails new APP_PATH</code> but we have the option
to preconfigure for selected database namely: mysql, oracle, postgresql,
sqlite3, frontbase, ibm_db, sqlserver, jdbcmysql, jdbcsqlite3, jdbcpostgresql,
jdbc</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Usage:
rails new APP_PATH [options]
Options:
-d, [--database=DATABASE]
</code></pre></div></div>
<p>So we could use <code class="language-plaintext highlighter-rouge">$rails new projectname -d mysql</code> the specify the port in the
database config file, <code class="language-plaintext highlighter-rouge">config/database.yml</code>.</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">development</span><span class="pi">:</span>
<span class="na">adapter</span><span class="pi">:</span> <span class="s">mysql2</span>
<span class="na">encoding</span><span class="pi">:</span> <span class="s">utf8</span>
<span class="na">database</span><span class="pi">:</span> <span class="s"><YOURDBNAME_development></span>
<span class="na">pool</span><span class="pi">:</span> <span class="m">5</span>
<span class="na">username</span><span class="pi">:</span> <span class="s"><YOUR_USERNAME></span>
<span class="na">password</span><span class="pi">:</span> <span class="s"><YOUR_PASSWORD></span>
<span class="na">host</span><span class="pi">:</span> <span class="s">localhost</span>
<span class="na">port</span><span class="pi">:</span> <span class="m">3306</span>
<span class="na">test</span><span class="pi">:</span>
<span class="na">adapter</span><span class="pi">:</span> <span class="s">mysql2</span>
<span class="na">encoding</span><span class="pi">:</span> <span class="s">utf8</span>
<span class="na">database</span><span class="pi">:</span> <span class="s"><YOURDBNAME_test></span>
<span class="na">pool</span><span class="pi">:</span> <span class="m">5</span>
<span class="na">username</span><span class="pi">:</span> <span class="s"><YOUR_USERNAME></span>
<span class="na">password</span><span class="pi">:</span> <span class="s"><YOUR_PASSWORD></span>
<span class="na">host</span><span class="pi">:</span> <span class="s">localhost</span>
<span class="na">port</span><span class="pi">:</span> <span class="m">3306</span>
<span class="na">production</span><span class="pi">:</span>
<span class="na">adapter</span><span class="pi">:</span> <span class="s">mysql2</span>
<span class="na">encoding</span><span class="pi">:</span> <span class="s">utf8</span>
<span class="na">database</span><span class="pi">:</span> <span class="s"><YOURDBNAME_production></span>
<span class="na">pool</span><span class="pi">:</span> <span class="m">5</span>
<span class="na">username</span><span class="pi">:</span> <span class="s"><YOUR_USERNAME></span>
<span class="na">password</span><span class="pi">:</span> <span class="s"><YOUR_PASSWORD></span>
<span class="na">host</span><span class="pi">:</span> <span class="s">localhost</span>
<span class="na">port</span><span class="pi">:</span> <span class="m">3306</span>
</code></pre></div></div>
<p>If you are using MAMP, you can use the sockets instead;</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">development</span><span class="pi">:</span>
<span class="na">adapter</span><span class="pi">:</span> <span class="s">mysql2</span>
<span class="na">encoding</span><span class="pi">:</span> <span class="s">utf8</span>
<span class="na">database</span><span class="pi">:</span> <span class="s"><YOURDBNAME_development></span>
<span class="na">pool</span><span class="pi">:</span> <span class="m">5</span>
<span class="na">username</span><span class="pi">:</span> <span class="s"><YOUR_USERNAME></span>
<span class="na">password</span><span class="pi">:</span> <span class="s"><YOUR_PASSWORD></span>
<span class="na">host</span><span class="pi">:</span> <span class="s">localhost</span>
<span class="na">socket</span><span class="pi">:</span> <span class="s1">'</span><span class="s">/Applications/MAMP/tmp/mysql/mysql.sock'</span>
<span class="na">test</span><span class="pi">:</span>
<span class="na">adapter</span><span class="pi">:</span> <span class="s">mysql2</span>
<span class="na">encoding</span><span class="pi">:</span> <span class="s">utf8</span>
<span class="na">database</span><span class="pi">:</span> <span class="s"><YOURDBNAME_test></span>
<span class="na">pool</span><span class="pi">:</span> <span class="m">5</span>
<span class="na">username</span><span class="pi">:</span> <span class="s"><YOUR_USERNAME></span>
<span class="na">password</span><span class="pi">:</span> <span class="s"><YOUR_PASSWORD></span>
<span class="na">host</span><span class="pi">:</span> <span class="s">localhost</span>
<span class="na">socket</span><span class="pi">:</span> <span class="s1">'</span><span class="s">/Applications/MAMP/tmp/mysql/mysql.sock'</span>
<span class="na">production</span><span class="pi">:</span>
<span class="na">adapter</span><span class="pi">:</span> <span class="s">mysql2</span>
<span class="na">encoding</span><span class="pi">:</span> <span class="s">utf8</span>
<span class="na">database</span><span class="pi">:</span> <span class="s"><YOURDBNAME_production></span>
<span class="na">pool</span><span class="pi">:</span> <span class="m">5</span>
<span class="na">username</span><span class="pi">:</span> <span class="s"><YOUR_USERNAME></span>
<span class="na">password</span><span class="pi">:</span> <span class="s"><YOUR_PASSWORD></span>
<span class="na">host</span><span class="pi">:</span> <span class="s">localhost</span>
<span class="na">socket</span><span class="pi">:</span> <span class="s1">'</span><span class="s">/Applications/MAMP/tmp/mysql/mysql.sock'</span>
</code></pre></div></div>
<p>Check out <a href="/minutae/2013/07/rails-on-osx/">this other post</a> that has details on installation of Rails on OS X
(MySQL included).</p>
<p><em>Ps: Find out more options from <code class="language-plaintext highlighter-rouge">rails --help</code></em></p>
<p><em>Ps 2: For those using Rails & MAMP (using sockets, which seems to be the easier
option) … I’m not quite sure if it works out of the box. I was tinkering with
an actual MySQL install using homebrew by the time I found this solution. If it
doesn’t, try install MySQL using homebrew first. There have been a few articles
on the web discussing the fact that the MySQL bundled with MAMP doesn’t have
everything reuired for a full MySQL installation (which might be necessary for
the mysql2 gem install).</em></p>
<hr />
<ol>
<li><a href="http://stackoverflow.com/questions/1670154/convert-a-ruby-on-rails-app-from-sqlite-to-mysql">Stack Overflow: Convert a Ruby on Rails app from sqlite to MySQL?</a> …
shows you step by step guide on how to migrate an existing SQLite DB to
MySQL.</li>
<li><a href="http://stackoverflow.com/questions/5781482/using-sqlite-vs-mysql-with-ruby">Stack Overflow: Using SQLite vs. MySQL with Ruby?</a> … debate on which is
the better way to go. Personally I prefer MySQL.</li>
</ol>
King'ori Maina
http://kingori.co/
Rails On OS X (Mountain Lion)
2013-07-31T00:00:00+00:00
kingori.co:/minutae/2013/07/rails-on-osx/
<p>Start by <a href="https://github.com/mxcl/homebrew/wiki/Installation">installing homebrew</a> :-)</p>
<h3 id="installing-ruby">Installing Ruby</h3>
<p>OS X comes with <a href="http://www.ruby-lang.org/en/">Ruby</a> installed but it’s an older version, and you don’t
want to be messing with core files so it’s better to use <a href="https://github.com/sstephenson/rbenv">rbenv</a> and <a href="https://github.com/sstephenson/ruby-build">ruby-
build</a> to manage and install your Ruby development environments.</p>
<p>Install both using <a href="http://brew.sh/">Homebrew</a>. Once done, add a line to your
<code class="language-plaintext highlighter-rouge">~/.bash_profile</code> and reload your terminal profile.</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>brew <span class="nb">install </span>rbenv ruby-build
<span class="gp">$</span><span class="w"> </span><span class="nb">echo</span> <span class="s1">'eval "$(rbenv init -)"'</span> <span class="o">>></span> ~/.bash_profile
<span class="gp">$</span><span class="w"> </span><span class="nb">source</span> ~/.bash_profile
</code></pre></div></div>
<p>They allow you to install different versions of Ruby and specify which version
to use on a per project basis. This is very useful to keep a consistent
development environment if you need to work in a particular Ruby version.</p>
<p>Install the latest stable of Ruby (<a href="http://www.ruby-lang.org/en/downloads/">check the Ruby website</a>). To see a list
of all available versions to install use <code class="language-plaintext highlighter-rouge">rbenv install --list</code>.</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>rbenv <span class="nb">install </span>2.0.0-p247
<span class="gp">$</span><span class="w"> </span>rbenv rehash
</code></pre></div></div>
<p>To set this version as the one to use globally so that you can make use of it in
your terminal, do this:</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>rbenv global 2.0.0-p247
</code></pre></div></div>
<p><em>Ps: You need to run the <code class="language-plaintext highlighter-rouge">rbenv rehash</code> after you install a new version of
Ruby.</em></p>
<p><em>Ps 2: Check out more commands in the <code class="language-plaintext highlighter-rouge">rbenv</code> <a href="https://github.com/sstephenson/rbenv#command-reference">readme on Github</a>. It’s worth
bookmarking that page for reference later, or there is always <code class="language-plaintext highlighter-rouge">rbenv --help</code>.
The most common are:</em></p>
<h3 id="installing-bundler">Installing Bundler</h3>
<p><a href="http://bundler.io/">Bundler</a> is a <a href="http://docs.rubygems.org/read/chapter/1">Ruby gem</a> manages an application’s dependencies, kind of
like a shopping list of other libraries the application needs to work. If you’re
just starting out with Ruby on Rails you will see just how important and helpful
this gem is.</p>
<p>You can use the <code class="language-plaintext highlighter-rouge">rbenv shell</code> command to ensure we have the correct version of
Ruby loaded in our terminal window, it sets a shell-specific Ruby version by
setting the <code class="language-plaintext highlighter-rouge">BENV_VERSION</code> environment variable in your shell. This version
overrides application-specific versions and the global version. If you’re
paranoid you can always check your Ruby version with <code class="language-plaintext highlighter-rouge">ruby --version</code>.</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>rbenv shell 2.0.0-p247
<span class="gp">$</span><span class="w"> </span>gem <span class="nb">install </span>bundler
<span class="gp">$</span><span class="w"> </span>rbenv rehash
</code></pre></div></div>
<p>To configure Bundler to install gems in a location relative to your projects
instead of globally, in this case the vendor folder of a Rails project, do this:</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span><span class="nb">mkdir</span> ~/.bundle
<span class="gp">$</span><span class="w"> </span><span class="nb">touch</span> ~/.bundle/config
<span class="gp">$</span><span class="w"> </span><span class="nb">echo</span> <span class="s1">'BUNDLE_PATH: vendor/bundle'</span> <span class="o">>></span> ~/.bundle/config
</code></pre></div></div>
<h4 id="skip-rdoc-generation">Skip rdoc generation</h4>
<p>If you use Google for finding your Gem documentation you might consider saving a
bit of time when installing gems by skipping the documentation.</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span><span class="nb">echo</span> <span class="s1">'gem: --no-rdoc --no-ri'</span> <span class="o">>></span> ~/.gemrc
</code></pre></div></div>
<p><em>Ps: Notice <code class="language-plaintext highlighter-rouge">rbenv rehash</code> has been used again when installing bundler, you need
to do this whenever you install a new gem that provides binaries. So if you’ve
installed a gem and the terminal tells you it can’t find it run <code class="language-plaintext highlighter-rouge">rbenv rehash</code>.</em></p>
<p><em>Ps 2: As you’ll see from <code class="language-plaintext highlighter-rouge">rbenv install --list</code> there are loads of Ruby
versions available including JRuby just remember you will need to re-install
your gems for each version as they are not shared.</em></p>
<h3 id="installing-rails">Installing Rails</h3>
<p>Check out the <a href="http://rubyonrails.org/">Rails website</a> for the whole story on Rails.</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>gem <span class="nb">install </span>rails
<span class="gp">$</span><span class="w"> </span>rbenv rehash
</code></pre></div></div>
<p>Rails has a numberq of dependencies to install so don’t be surprised if you
see loads of other gems being installed at the same time.</p>
<h3 id="installing-mysql">Installing MySQL</h3>
<p>Most people prefer MySQL as their DB of choice.</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>gem <span class="nb">install </span>mysql2
</code></pre></div></div>
<p>To connect:</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>mysql <span class="nt">-u</span> root
</code></pre></div></div>
<p>A few things that you should know:</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">#</span><span class="w"> </span>To have launchd start mysql at login:
<span class="gp">$</span><span class="w"> </span><span class="nb">ln</span> <span class="nt">-sfv</span> /usr/local/opt/mysql/<span class="k">*</span>.plist ~/Library/LaunchAgents
<span class="go">
</span><span class="gp">#</span><span class="w"> </span>Then to load mysql now:
<span class="gp">$</span><span class="w"> </span>launchctl load ~/Library/LaunchAgents/homebrew.mxcl.mysql.plist
<span class="go">
</span><span class="gp">#</span><span class="w"> </span>Or, <span class="k">if </span>you don<span class="s1">'t want/need launchctl, you can just run:
</span><span class="gp">#</span><span class="w"> </span><span class="s1">mysql.server {start|stop|restart|reload|force-reload|status}
</span><span class="gp">$</span><span class="w"> </span><span class="s1">mysql.server start
</span></code></pre></div></div>
<p>If you are using MAMP and don’t need MySQL, check out the config file details
<a href="/minutae/2013/08/rails-with-mysql/">in this other post</a>.</p>
<p><em>Ps: For those using Rails & MAMP (using sockets, which seems to be the easier
option) … I’m not quite sure if it works out of the box. I was tinkering with
an actual MySQL install using homebrew by the time I found this solution. If it
doesn’t, try install MySQL using homebrew first. There have been a few articles
on the web discussing the fact that the MySQL bundled with MAMP doesn’t have
everything reuired for a full MySQL installation (which might be necessary for
the mysql2 gem install).</em></p>
<h3 id="your-first-rails-project">Your First Rails Project</h3>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>rails new helloworld
<span class="gp">$</span><span class="w"> </span><span class="nb">cd </span>helloworld
</code></pre></div></div>
<p>Set the local Ruby version for this project to make sure this stays constant,
even if we change the global version later on. This command will write
automatically to <code class="language-plaintext highlighter-rouge">.ruby-version</code> in your project directory. This file will
automatically change the Ruby version within this folder and warn you if you
don’t have it installed.</p>
<p>Then run Bundler to install all the project gems into vendor/bundle, they are
kept with the project locally and won’t interfere with anything else outside.</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>rbenv <span class="nb">local </span>2.0.0-p247
<span class="gp">$</span><span class="w"> </span>bundle <span class="nb">install</span>
</code></pre></div></div>
<p>If your gems ever stop working you can just delete the vendor/bundle directory
and run the command again to re-install them. It’s also worth updating your
.gitignore file so you don’t commit all of those gems!</p>
<p>Now to test if the application is working:</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>rails server
</code></pre></div></div>
<hr />
<ol>
<li><a href="http://www.ruby-lang.org/en/downloads/">Official Ruby website</a></li>
<li>This post is borrowed heavily from <a href="http://createdbypete.com/articles/ruby-on-rails-development-with-mac-os-x-mountain-lion/">Ruby on Rails development with Mac OS X
Mountain Lion</a>. He deserves the credit. This is merely my own personal
reference of the procedure.</li>
<li><a href="https://github.com/sstephenson/rbenv#command-reference"><code class="language-plaintext highlighter-rouge">rbenv</code> Command Reference</a></li>
<li><a href="http://bundler.io/">Bundler Ruby Gem</a></li>
<li><a href="http://docs.rubygems.org/read/chapter/1">Rails Ruby Gem</a></li>
<li><a href="https://github.com/mxcl/homebrew/wiki/Installation">Installing Homebrew</a></li>
</ol>
King'ori Maina
http://kingori.co/
Return values of $(selector) if selector doesn't exist? ∞
2013-07-10T00:00:00+00:00
kingori.co:/minutae/2013/07/values-of-jquery-selectors/
<h3 id="problem">Problem</h3>
<p>Always wondered why jQuery returns true if you are trying to find elements by a
selector that doesn’t exist in the DOM structure. Like this example using an id-
selector:</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><div</span> <span class="na">id=</span><span class="s">"one"</span><span class="nt">></span>one<span class="nt"></div></span>
<span class="nt"><script></span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span> <span class="o">!!</span><span class="nx">$</span><span class="p">(</span><span class="dl">'</span><span class="s1">#one</span><span class="dl">'</span><span class="p">)</span> <span class="p">)</span> <span class="c1">// prints true</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span> <span class="o">!!</span><span class="nx">$</span><span class="p">(</span><span class="dl">'</span><span class="s1">#two</span><span class="dl">'</span><span class="p">)</span> <span class="p">)</span> <span class="c1">// is also true! (empty jQuery object)</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span> <span class="o">!!</span><span class="nb">document</span><span class="p">.</span><span class="nx">getElementById</span><span class="p">(</span><span class="dl">'</span><span class="s1">two</span><span class="dl">'</span><span class="p">)</span> <span class="p">)</span> <span class="c1">// prints false</span>
<span class="nt"></script></span>
</code></pre></div></div>
<p>You can use <code class="language-plaintext highlighter-rouge">!!$('#two').length since length === 0</code> if the object is empty, but
it seems logical to that a selector would return the element if found, otherwise
null (like the native <code class="language-plaintext highlighter-rouge">document.getElementById</code> does).</p>
<p>Consequentially, as an example, this logic can’t be done in jQuery:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">div</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="dl">'</span><span class="s1">#two</span><span class="dl">'</span><span class="p">)</span> <span class="o">||</span> <span class="nx">$</span><span class="p">(</span><span class="dl">'</span><span class="s1"><div id="two"></div></span><span class="dl">'</span><span class="p">);</span>
</code></pre></div></div>
<p>Wouldn’t it be more logical if the id-selector returned null if not found?</p>
<h3 id="explanation">Explanation</h3>
<p>Almost all jQuery functions return a jQuery object as a wrapper around the DOM
elements in question, so you can use dot notation. This behaviour was chosen
because otherwise jQuery would regularly throw errors.</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">$</span><span class="p">(</span><span class="dl">"</span><span class="s2">#balloon</span><span class="dl">"</span><span class="p">).</span><span class="nx">css</span><span class="p">({</span><span class="dl">"</span><span class="s2">color</span><span class="dl">"</span><span class="p">:</span><span class="dl">"</span><span class="s2">red</span><span class="dl">"</span><span class="p">});</span>
</code></pre></div></div>
<p>Now imagine <code class="language-plaintext highlighter-rouge">$("#balloon")</code> returned null. That means that
<code class="language-plaintext highlighter-rouge">$("#balloon").css({"color":"red"});</code> would throw an error, rather than silently
doing nothing as you would normally want.</p>
<p>Hence, you just gotta use <code class="language-plaintext highlighter-rouge">.length</code> or <code class="language-plaintext highlighter-rouge">.size()</code>.</p>
<hr />
<ol>
<li><a href="http://stackoverflow.com/questions/2076988/why-does-id-return-true-if-id-doesnt-exist">Stack Overflow: Why does $(‘#id’) return true if id doesn’t exist?</a></li>
</ol>
<p>
<a title="Permalink to 'Return values of $(selector) if selector doesn't exist?'" href="http://kingori.co/minutae/2013/07/values-of-jquery-selectors/" target="_blank">↩</a>
</p>
King'ori Maina
http://kingori.co/
Audio Formats and Browser Support
2013-07-10T00:00:00+00:00
kingori.co:/minutae/2013/07/audio-formats-and-browser-support/
<h3 id="problem">Problem</h3>
<blockquote>
<p>The <code class="language-plaintext highlighter-rouge"><audio></code> and <code class="language-plaintext highlighter-rouge"><video></code> elements provide support for playing audio and
video media without requiring plug-ins. Video codecs and audio codecs are used
to handle video and audio, and different codecs offer different levels of
compression and quality. A container format is used to store and transmit the
coded video and audio together. Many codecs and container formats exists, and
there are even more combinations of them. For use on the web, only a handful
of combinations are relevant.</p>
</blockquote>
<blockquote>
<p>Different browsers do not support the same media formats in their
implementations of HTML 5 video and audio, mainly because of patent issues.</p>
</blockquote>
<h3 id="the-state-of-things">The State Of Things</h3>
<p>Currently, there are 3 supported file formats for the <code class="language-plaintext highlighter-rouge"><audio></code> element: MP3,
WAV, and OGG:</p>
<table>
<thead>
<tr>
<th>Browser</th>
<th>MP3</th>
<th>WAV</th>
<th>OGG</th>
</tr>
</thead>
<tbody>
<tr>
<td>Internet Explorer 9+</td>
<td>YES</td>
<td>NO</td>
<td>NO</td>
</tr>
<tr>
<td>Chrome 6+</td>
<td>YES</td>
<td>YES</td>
<td>YES</td>
</tr>
<tr>
<td>Firefox 3.6+</td>
<td>NO</td>
<td>YES</td>
<td>YES</td>
</tr>
<tr>
<td>Safari 5+</td>
<td>YES</td>
<td>YES</td>
<td>NO</td>
</tr>
<tr>
<td>Opera 10+</td>
<td>NO</td>
<td>YES</td>
<td>YES</td>
</tr>
</tbody>
</table>
<p><em>Ps: <a href="https://developer.mozilla.org/en-US/docs/HTML/Supported_media_formats#Browser_compatibility">See here</a> for a more detailed breakdown of different format
compatibility across different browsers (desktop-mobile, audio-video).</em></p>
<h3 id="progressing-enhancement-graceful-degradation">Progressing Enhancement/ Graceful Degradation</h3>
<blockquote>
<p>If audio support is detected, <a href="http://modernizr.com/">Modernizr</a> assesses which formats the
current browser will play. Currently, <a href="http://modernizr.com/">Modernizr</a> tests OGG, MP3, WAV and
M4A.</p>
</blockquote>
<blockquote>
<p><strong>Important:</strong> The values of these properties are not true booleans. Instead,
<a href="http://modernizr.com/">Modernizr</a> matches the HTML5 spec in returning a string representing the >
browser’s level of confidence that it can handle that codec. These return >
values are an empty string (negative response), <em>“maybe”</em> and <em>“probably”</em>. >
The empty string is falsy, in other words: <code class="language-plaintext highlighter-rouge">Modernizr.audio.ogg == ''</code> and > <code class="language-plaintext highlighter-rouge">''
== false</code></p>
</blockquote>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">audio</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Audio</span><span class="p">();</span>
<span class="nx">audio</span><span class="p">.</span><span class="nx">src</span> <span class="o">=</span> <span class="nx">Modernizr</span><span class="p">.</span><span class="nx">audio</span><span class="p">.</span><span class="nx">ogg</span> <span class="p">?</span> <span class="dl">'</span><span class="s1">background.ogg</span><span class="dl">'</span> <span class="p">:</span>
<span class="nx">Modernizr</span><span class="p">.</span><span class="nx">audio</span><span class="p">.</span><span class="nx">mp3</span> <span class="p">?</span> <span class="dl">'</span><span class="s1">background.mp3</span><span class="dl">'</span> <span class="p">:</span>
<span class="dl">'</span><span class="s1">background.m4a</span><span class="dl">'</span><span class="p">;</span>
<span class="nx">audio</span><span class="p">.</span><span class="nx">play</span><span class="p">();</span>
</code></pre></div></div>
<p>That allows you to serve the appropriate format based on browser support for a
particular format.</p>
<hr />
<ol>
<li><a href="http://www.w3schools.com/html/html5_audio.asp">W3Schools: HTML5 Audio</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/HTML/Supported_media_formats">Mozilla Developer Network: Media formats supported by the HTML audio and
video elements</a></li>
<li><a href="http://en.wikipedia.org/wiki/HTML5_Audio">Wikipedia: HTML5 Audio</a></li>
<li><a href="http://modernizr.com/docs/#features-html5">Modernizr: HTML5 Features</a></li>
</ol>
King'ori Maina
http://kingori.co/
Syncing A Fork To An Upstream Repo (GitHub) ∞
2013-06-27T00:00:00+00:00
kingori.co:/minutae/2013/06/syncing-a-fork/
<blockquote>
<p>You forked a repository on Github. Now, the original has some updates. How do
you pull the changes from the original (upstream) repository into yours?</p>
</blockquote>
<blockquote>
<p>And if your source is in conflict with the original source, do you have a
chance to edit it manually?</p>
</blockquote>
<p>If you’re asking these questions … then this is for you.</p>
<hr />
<ol>
<li><a href="https://help.github.com/articles/syncing-a-fork">GitHub / Collaborating / Syncing a fork</a></li>
<li><a href="http://stackoverflow.com/questions/11646080/keep-sync-with-another-git-repository">Stack Overflow: Keep sync with another git repository?</a></li>
</ol>
<p>
<a title="Permalink to 'Syncing A Fork To An Upstream Repo (GitHub)'" href="http://kingori.co/minutae/2013/06/syncing-a-fork/" target="_blank">↩</a>
</p>
King'ori Maina
http://kingori.co/
Serialize Javascript Array/Objects To JSON & Vice Versa
2013-06-04T00:00:00+00:00
kingori.co:/minutae/2013/06/javascript-arrays-objects-json/
<h3 id="json-object">JSON Object</h3>
<blockquote>
<p>The JSON object contains methods for parsing JSON and converting values to
JSON.</p>
</blockquote>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">assert</span><span class="p">(</span><span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">({})</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">{}</span><span class="dl">'</span><span class="p">);</span>
<span class="nx">assert</span><span class="p">(</span><span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="kc">true</span><span class="p">)</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">true</span><span class="dl">'</span><span class="p">);</span>
<span class="nx">assert</span><span class="p">(</span><span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="dl">"</span><span class="s2">foo</span><span class="dl">"</span><span class="p">)</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">"foo"</span><span class="dl">'</span><span class="p">);</span>
<span class="nx">assert</span><span class="p">(</span><span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">([</span><span class="mi">1</span><span class="p">,</span> <span class="dl">"</span><span class="s2">false</span><span class="dl">"</span><span class="p">,</span> <span class="kc">false</span><span class="p">])</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">[1,"false",false]</span><span class="dl">'</span><span class="p">);</span>
<span class="nx">assert</span><span class="p">(</span><span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">({</span> <span class="na">x</span><span class="p">:</span> <span class="mi">5</span> <span class="p">})</span> <span class="o">===</span> <span class="dl">'</span><span class="s1">{"x":5}</span><span class="dl">'</span><span class="p">);</span>
<span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">({</span><span class="na">x</span><span class="p">:</span> <span class="mi">5</span><span class="p">,</span> <span class="na">y</span><span class="p">:</span> <span class="mi">6</span><span class="p">});</span> <span class="c1">// '{"x":5,"y":6}' or '{"y":6,"x":5}'</span>
</code></pre></div></div>
<blockquote>
<p>Return a JSON string corresponding to the specified value, optionally
including only certain properties or replacing property values in a user-
defined manner.</p>
</blockquote>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="dl">'</span><span class="s1">{}</span><span class="dl">'</span><span class="p">);</span> <span class="c1">// {}</span>
<span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="dl">'</span><span class="s1">true</span><span class="dl">'</span><span class="p">);</span> <span class="c1">// true</span>
<span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="dl">'</span><span class="s1">"foo"</span><span class="dl">'</span><span class="p">);</span> <span class="c1">// "foo"</span>
<span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="dl">'</span><span class="s1">[1, 5, "false"]</span><span class="dl">'</span><span class="p">);</span> <span class="c1">// [1, 5, "false"]</span>
<span class="nx">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="dl">'</span><span class="s1">null</span><span class="dl">'</span><span class="p">);</span> <span class="c1">// null</span>
</code></pre></div></div>
<blockquote>
<p>Parse a string as JSON, optionally transform the produced value and its
properties, and return the value.</p>
</blockquote>
<h3 id="browser-compatibility">Browser Compatibility</h3>
<p><a href="http://caniuse.com/json">Newer browsers</a> support the <a href="https://developer.mozilla.org/en-US/docs/JSON">JSON object</a> natively. Well-known polyfills
for the JSON object are <a href="https://github.com/douglascrockford/JSON-js">JSON2</a> and <a href="http://bestiejs.github.io/json3/#section_2">JSON3</a> that will only define
<a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/JSON/stringify"><code class="language-plaintext highlighter-rouge">JSON.stringify</code></a> and <a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/JSON/parse"><code class="language-plaintext highlighter-rouge">JSON.parse</code></a> if they’re not already defined,
leaving any browser native implementation intact.</p>
<hr />
<ol>
<li><a href="https://developer.mozilla.org/en-US/docs/JSON">Mozilla Developer Network: JSON</a></li>
<li><a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/JSON/stringify"><code class="language-plaintext highlighter-rouge">JSON.stringify</code> method</a></li>
<li><a href="https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/JSON/parse"><code class="language-plaintext highlighter-rouge">JSON.parse</code> method</a></li>
<li><a href="http://stackoverflow.com/questions/191881/serializing-to-json-in-jquery">Serializing to JSON in jQuery</a></li>
</ol>
King'ori Maina
http://kingori.co/
PHPMyAdmin On Nginx (on Ubuntu) For RDS
2013-05-28T00:00:00+00:00
kingori.co:/minutae/2013/05/phpymyadmin-on-nginx-and-buntu-for-rds/
<h3 id="installing-phpmyadmin">Installing PHPMyAdmin</h3>
<p>An example using conditional filter expressions that have multiple conditional
paths. Here is a simple conditional that can quickly become a drain on
performance because of the order of parsing;</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>apt-get <span class="nb">install </span>phpmyadmin
</code></pre></div></div>
<p>Preconfigure with <code class="language-plaintext highlighter-rouge">apache</code> or <code class="language-plaintext highlighter-rouge">lighttpd</code>? - I hit <code class="language-plaintext highlighter-rouge">ESC</code>.</p>
<p>Configure database for phpmyadmin with dbconfig-common? No.</p>
<h3 id="configure-amazon-rds">Configure Amazon RDS</h3>
<blockquote>
<p>The one thing I had trouble with was the DB Security Group setup. When you go
to add access for an CIDR/IP it provides a recommended value. It took some
messing around to determine that this default value isn’t actually what needed
to be there. If you’re not able to connect to your instance when it’s all
said and done, be sure to double check this value. The IP they provided did
not match the IP address that was provided to us by our ISP. Once you’ve
created your DB Instance and setup the security group you’re good to go.</p>
</blockquote>
<p>In summary, just add your EC2 Security group … i.e. the one that you want to
be able to access RDS.</p>
<h3 id="configure-phpmyadmin">Configure PHPMyAdmin</h3>
<p>Modify <code class="language-plaintext highlighter-rouge">/etc/config.inc.php</code>. It should look something like this.</p>
<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/* Configure according to dbconfig-common if enabled */</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nb">empty</span><span class="p">(</span><span class="nv">$dbname</span><span class="p">))</span> <span class="p">{</span>
<span class="cm">/* Authentication type */</span>
<span class="nv">$cfg</span><span class="p">[</span><span class="s1">'Servers'</span><span class="p">][</span><span class="nv">$i</span><span class="p">][</span><span class="s1">'auth_type'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'config'</span><span class="p">;</span>
<span class="nv">$cfg</span><span class="p">[</span><span class="s1">'Servers'</span><span class="p">][</span><span class="nv">$i</span><span class="p">][</span><span class="s1">'user'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'YOUR_USERNAME'</span><span class="p">;</span>
<span class="nv">$cfg</span><span class="p">[</span><span class="s1">'Servers'</span><span class="p">][</span><span class="nv">$i</span><span class="p">][</span><span class="s1">'password'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'YOUR_PASSWORD'</span><span class="p">;</span>
<span class="nv">$cfg</span><span class="p">[</span><span class="s1">'Servers'</span><span class="p">][</span><span class="nv">$i</span><span class="p">][</span><span class="s1">'hide_db'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'(mysql|information_schema|phpmyadmin)'</span><span class="p">;</span>
<span class="cm">/* Server parameters */</span>
<span class="k">if</span> <span class="p">(</span><span class="nb">empty</span><span class="p">(</span><span class="nv">$dbserver</span><span class="p">))</span> <span class="nv">$dbserver</span> <span class="o">=</span> <span class="s1">'localhost'</span><span class="p">;</span>
<span class="nv">$cfg</span><span class="p">[</span><span class="s1">'Servers'</span><span class="p">][</span><span class="nv">$i</span><span class="p">][</span><span class="s1">'host'</span><span class="p">]</span> <span class="o">=</span> <span class="nv">$dbserver</span><span class="p">;</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nb">empty</span><span class="p">(</span><span class="nv">$dbport</span><span class="p">))</span> <span class="p">{</span>
<span class="nv">$cfg</span><span class="p">[</span><span class="s1">'Servers'</span><span class="p">][</span><span class="nv">$i</span><span class="p">][</span><span class="s1">'connect_type'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'tcp'</span><span class="p">;</span>
<span class="nv">$cfg</span><span class="p">[</span><span class="s1">'Servers'</span><span class="p">][</span><span class="nv">$i</span><span class="p">][</span><span class="s1">'port'</span><span class="p">]</span> <span class="o">=</span> <span class="nv">$dbport</span><span class="p">;</span>
<span class="p">}</span>
<span class="c1">//$cfg['Servers'][$i]['compress'] = false;</span>
<span class="cm">/* Select mysqli if your server has it */</span>
<span class="nv">$cfg</span><span class="p">[</span><span class="s1">'Servers'</span><span class="p">][</span><span class="nv">$i</span><span class="p">][</span><span class="s1">'extension'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'mysqli'</span><span class="p">;</span>
<span class="cm">/* Optional: User for advanced features */</span>
<span class="c1">//$cfg['Servers'][$i]['controluser'] = $dbuser;</span>
<span class="c1">//$cfg['Servers'][$i]['controlpass'] = $dbpass;</span>
<span class="cm">/* Optional: Advanced phpMyAdmin features */</span>
<span class="nv">$cfg</span><span class="p">[</span><span class="s1">'Servers'</span><span class="p">][</span><span class="nv">$i</span><span class="p">][</span><span class="s1">'pmadb'</span><span class="p">]</span> <span class="o">=</span> <span class="nv">$dbname</span><span class="p">;</span>
<span class="nv">$cfg</span><span class="p">[</span><span class="s1">'Servers'</span><span class="p">][</span><span class="nv">$i</span><span class="p">][</span><span class="s1">'bookmarktable'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'pma_bookmark'</span><span class="p">;</span>
<span class="nv">$cfg</span><span class="p">[</span><span class="s1">'Servers'</span><span class="p">][</span><span class="nv">$i</span><span class="p">][</span><span class="s1">'relation'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'pma_relation'</span><span class="p">;</span>
<span class="nv">$cfg</span><span class="p">[</span><span class="s1">'Servers'</span><span class="p">][</span><span class="nv">$i</span><span class="p">][</span><span class="s1">'table_info'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'pma_table_info'</span><span class="p">;</span>
<span class="nv">$cfg</span><span class="p">[</span><span class="s1">'Servers'</span><span class="p">][</span><span class="nv">$i</span><span class="p">][</span><span class="s1">'table_coords'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'pma_table_coords'</span><span class="p">;</span>
<span class="nv">$cfg</span><span class="p">[</span><span class="s1">'Servers'</span><span class="p">][</span><span class="nv">$i</span><span class="p">][</span><span class="s1">'pdf_pages'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'pma_pdf_pages'</span><span class="p">;</span>
<span class="nv">$cfg</span><span class="p">[</span><span class="s1">'Servers'</span><span class="p">][</span><span class="nv">$i</span><span class="p">][</span><span class="s1">'column_info'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'pma_column_info'</span><span class="p">;</span>
<span class="nv">$cfg</span><span class="p">[</span><span class="s1">'Servers'</span><span class="p">][</span><span class="nv">$i</span><span class="p">][</span><span class="s1">'history'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'pma_history'</span><span class="p">;</span>
<span class="nv">$cfg</span><span class="p">[</span><span class="s1">'Servers'</span><span class="p">][</span><span class="nv">$i</span><span class="p">][</span><span class="s1">'designer_coords'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'pma_designer_coords'</span><span class="p">;</span>
<span class="cm">/* Uncomment the following to enable logging in to passwordless accounts,
* after taking note of the associated security risks. */</span>
<span class="c1">// $cfg['Servers'][$i]['AllowNoPassword'] = TRUE;</span>
<span class="cm">/* Advance to next server for rest of config */</span>
<span class="nv">$i</span><span class="o">++</span><span class="p">;</span>
<span class="p">}</span>
<span class="nv">$cfg</span><span class="p">[</span><span class="s1">'Servers'</span><span class="p">][</span><span class="nv">$i</span><span class="p">][</span><span class="s1">'auth_type'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'HTTP'</span><span class="p">;</span>
<span class="nv">$cfg</span><span class="p">[</span><span class="s1">'Servers'</span><span class="p">][</span><span class="nv">$i</span><span class="p">][</span><span class="s1">'hide_db'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'(mysql|information_schema|phpmyadmin)'</span><span class="p">;</span>
<span class="nv">$cfg</span><span class="p">[</span><span class="s1">'Servers'</span><span class="p">][</span><span class="nv">$i</span><span class="p">][</span><span class="s1">'host'</span><span class="p">]</span> <span class="o">=</span> <span class="s1">'EXAMPLE.JUMBLE.us-east-1.rds.amazonaws.com'</span><span class="p">;</span>
</code></pre></div></div>
<h3 id="configure-nginx">Configure Nginx</h3>
<p>Add serverblock to Nginx config.</p>
<div class="language-nginx highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">server</span> <span class="p">{</span>
<span class="kn">listen</span> <span class="mi">80</span><span class="p">;</span>
<span class="kn">server_name</span> <span class="s">YOUR.DOMAIN.DOT</span><span class="p">;</span>
<span class="kn">index</span> <span class="s">index.php</span><span class="p">;</span>
<span class="kn">root</span> <span class="n">/usr/share/phpmyadmin</span><span class="p">;</span>
<span class="kn">location</span> <span class="n">/</span> <span class="p">{</span>
<span class="kn">try_files</span> <span class="nv">$uri</span> <span class="nv">$uri</span><span class="n">/</span> <span class="s">@phpmyadmin</span><span class="p">;</span>
<span class="p">}</span>
<span class="kn">location</span> <span class="s">@phpmyadmin</span> <span class="p">{</span>
<span class="kn">fastcgi_pass</span> <span class="s">unix:/var/run/php5-fpm.sock</span><span class="p">;</span>
<span class="kn">fastcgi_param</span> <span class="s">SCRIPT_FILENAME</span> <span class="n">/usr/share/phpmyadmin/index.php</span><span class="p">;</span>
<span class="kn">include</span> <span class="n">/etc/nginx/fastcgi_params</span><span class="p">;</span>
<span class="kn">fastcgi_param</span> <span class="s">SCRIPT_NAME</span> <span class="n">/index.php</span><span class="p">;</span>
<span class="p">}</span>
<span class="kn">location</span> <span class="p">~</span> <span class="sr">\.php$</span> <span class="p">{</span>
<span class="kn">try_files</span> <span class="nv">$uri</span> <span class="s">@phpmyadmin</span><span class="p">;</span>
<span class="kn">fastcgi_pass</span> <span class="s">unix:/var/run/php5-fpm.sock</span><span class="p">;</span>
<span class="kn">fastcgi_index</span> <span class="s">index.php</span><span class="p">;</span>
<span class="kn">fastcgi_param</span> <span class="s">SCRIPT_FILENAME</span> <span class="n">/usr/share/phpmyadmin</span><span class="nv">$fastcgi_script_name</span><span class="p">;</span>
<span class="kn">include</span> <span class="s">fastcgi_params</span><span class="p">;</span>
<span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>
<hr />
<ol>
<li>There’s the assumption that you already have Nginx up and running on an
Ubuntu box.</li>
<li>This was done practially on Ubuntu 13.04</li>
<li><a href="https://help.ubuntu.com/community/phpMyAdmin">Ubuntu Community Help Wiki: phpMyAdmin</a></li>
<li><a href="http://www.howtoforge.com/installing-nginx-with-php5-and-php-fpm-and-mysql-support-lemp-on-ubuntu-12.">Installing Nginx With PHP5 (And PHP-FPM) And MySQL Support (LEMP) On Ubuntu
12.10</a></li>
<li><a href="http://blog.benkuhl.com/2010/12/how-to-remotely-manage-an-amazon-rds-instance-with-phpmyadmin/">How to remotely manage an Amazon RDS instance with PHPMyAdmin</a></li>
</ol>
King'ori Maina
http://kingori.co/
The Different Javascript Event Handlers ∞
2013-05-20T00:00:00+00:00
kingori.co:/minutae/2013/05/different-javascript-event-handlers/
<p><code class="language-plaintext highlighter-rouge"><ul id="items"><li> Click Me </li></ul></code></p>
<blockquote>
<p>Bind attaches an event handler only to the elements that match a particular
selector. This, expectedly, excludes any dynamically generated elements.</p>
</blockquote>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">$</span><span class="p">(</span><span class="dl">"</span><span class="s2">#items li</span><span class="dl">"</span><span class="p">).</span><span class="nx">click</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">parent</span><span class="p">().</span><span class="nx">append</span><span class="p">(</span><span class="dl">"</span><span class="s2"><li>New Element</li></span><span class="dl">"</span><span class="p">);</span>
<span class="p">});</span>
</code></pre></div></div>
<blockquote>
<p>Live(), introduced in 1.3, allows for the binding of event handlers to all
elements that match a selector, including those created in the future. It
does this by attaching the handler to the document. Unfortunately, it does not
work well with chaining. Don’t expect to chain live() after calls like
children().next()…etc.</p>
</blockquote>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">$</span><span class="p">(</span><span class="dl">"</span><span class="s2">li</span><span class="dl">"</span><span class="p">).</span><span class="nx">live</span><span class="p">(</span><span class="dl">"</span><span class="s2">click</span><span class="dl">"</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">parent</span><span class="p">().</span><span class="nx">append</span><span class="p">(</span><span class="dl">"</span><span class="s2"><li>New Element</li></span><span class="dl">"</span><span class="p">);</span>
<span class="p">});</span>
</code></pre></div></div>
<blockquote>
<p>Delegate, new to version 1.4, perhaps should have been a complete replacement
for Live(). However, that obviously would have broken a lot of code!
Nonetheless, delegate remedies many of the short-comings found in live(). It
attaches the event handler directly to the context, rather than the document.
It also doesn’t suffer from the chaining issues that live does. There are many
performance benefits to using this method over live().</p>
</blockquote>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">$</span><span class="p">(</span><span class="dl">'</span><span class="s1">#items</span><span class="dl">'</span><span class="p">).</span><span class="nx">delegate</span><span class="p">(</span><span class="dl">'</span><span class="s1">li</span><span class="dl">'</span><span class="p">,</span> <span class="dl">'</span><span class="s1">click</span><span class="dl">'</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">parent</span><span class="p">().</span><span class="nx">append</span><span class="p">(</span><span class="dl">'</span><span class="s1"><li>New Element</li></span><span class="dl">'</span><span class="p">);</span>
<span class="p">});</span>
</code></pre></div></div>
<blockquote>
<p>By passing a DOM element as the context of our selector, we can make Live()
behave (almost) the same way that delegate() does. It attaches the handler to
the context, not the document - which is the default context. The code below
is equivalent to the delegate() version shown above.</p>
</blockquote>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">$</span><span class="p">(</span><span class="dl">"</span><span class="s2">li</span><span class="dl">"</span><span class="p">,</span> <span class="nx">$</span><span class="p">(</span><span class="dl">"</span><span class="s2">#items</span><span class="dl">"</span><span class="p">)[</span><span class="mi">0</span><span class="p">]).</span><span class="nx">live</span><span class="p">(</span><span class="dl">"</span><span class="s2">click</span><span class="dl">"</span><span class="p">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">parent</span><span class="p">().</span><span class="nx">append</span><span class="p">(</span><span class="dl">"</span><span class="s2"><li>New Element</li></span><span class="dl">"</span><span class="p">);</span>
<span class="p">});</span>
</code></pre></div></div>
<p>
<a title="Permalink to 'The Different Javascript Event Handlers'" href="http://kingori.co/minutae/2013/05/different-javascript-event-handlers/" target="_blank">↩</a>
</p>
King'ori Maina
http://kingori.co/
Nginx With PHP5 (And PHP-FPM) on Ubuntu 13.04
2013-05-17T00:00:00+00:00
kingori.co:/minutae/2013/05/nginx-phpfpm-ubuntu/
<p>Having a working install of Ubuntu 13.04, proceed with the below;</p>
<h4 id="1-update-and-upgrade-ubuntu">1. Update and upgrade Ubuntu</h4>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span><span class="nb">sudo </span>apt-get update
<span class="gp">$</span><span class="w"> </span><span class="nb">sudo </span>apt-get upgrade
</code></pre></div></div>
<h4 id="2-install-nginx">2. Install Nginx</h4>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span><span class="nb">sudo </span>apt-get <span class="nb">install </span>nginx
<span class="gp">$</span><span class="w"> </span><span class="nb">sudo</span> /etc/init.d/nginx start
</code></pre></div></div>
<p>Nginx should be working now. Try access the server from a browser.</p>
<h4 id="3-install-php-fpm">3. Install PHP-FPM</h4>
<p>PHP-FPM is a daemon process (with the init script <code class="language-plaintext highlighter-rouge">/etc/init.d/php5-fpm</code>) that
runs a FastCGI server on the socket <code class="language-plaintext highlighter-rouge">/var/run/php5-fpm.sock</code>.</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span><span class="nb">sudo </span>apt-get <span class="nb">install </span>php5-fpm
</code></pre></div></div>
<p>Now create the following PHP file in the document root /usr/share/nginx/www</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>vim /usr/share/nginx/www/info.php
</code></pre></div></div>
<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Enclosed in PHP tags of course</span>
<span class="nb">phpinfo</span><span class="p">();</span>
</code></pre></div></div>
<p><em>Ps: See <a href="http://www.howtoforge.com/installing-nginx-with-php5-and-php-fpm-and-mysql-support-lemp-on-ubuntu-12.10">link 1</a> below for more detail & some other extra stuff you could
do.</em></p>
<hr />
<ol>
<li><a href="http://www.howtoforge.com/installing-nginx-with-php5-and-php-fpm-and-mysql-support-lemp-on-ubuntu-12.10">Installing Nginx With PHP5 (And PHP-FPM) And MySQL Support (LEMP) On Ubuntu
12.10</a></li>
</ol>
King'ori Maina
http://kingori.co/
Pass Variables To External JS Script
2013-05-16T00:00:00+00:00
kingori.co:/minutae/2013/05/pass-variable-to-external-javascript/
<h3 id="solution-1">Solution 1:</h3>
<blockquote>
<p>You can process those GET parameters on the server where the <em>**.js is hosted,
so that it will dynamically change the js file. And your server somehow
processes the file, replacing that **</em>.js template file dependent on what
request was sent.</p>
</blockquote>
<h3 id="solution-2">Solution 2:</h3>
<blockquote>
<p>Set the global variables on the page where ***.js is loaded, like this. This
will then be available in the JS script.</p>
</blockquote>
<p>In the HTML document … somewhere.</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">window</span><span class="p">.</span><span class="nx">YourVariableName</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">Value</span><span class="dl">'</span><span class="p">;</span>
</code></pre></div></div>
<p>Access it in the script …</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">handle</span> <span class="o">=</span> <span class="nb">window</span><span class="p">.</span><span class="nx">YourVariableName</span> <span class="o">||</span> <span class="kc">null</span><span class="p">;</span>
</code></pre></div></div>
<hr />
<ol>
<li><a href="http://stackoverflow.com/questions/4493319/in-javascript-is-it-possible-to-pass-a-variable-into-script-src-parameter?answertab=votes#tab-top">In Javascript, is it possible to pass a variable into script “src”
parameter?</a></li>
</ol>
King'ori Maina
http://kingori.co/
Javascript Variable Hoisting
2013-05-16T00:00:00+00:00
kingori.co:/minutae/2013/05/javascript-variable-hoisting/
<h3 id="example-problem">Example Problem:</h3>
<p>Global variable has undefined in certain case.</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">value</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>
<span class="kd">function</span> <span class="nx">test</span><span class="p">()</span> <span class="p">{</span>
<span class="c1">//A</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">value</span><span class="p">);</span>
<span class="c1">//B</span>
<span class="kd">var</span> <span class="nx">value</span> <span class="o">=</span> <span class="mi">20</span><span class="p">;</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">value</span><span class="p">);</span>
<span class="p">}</span>
<span class="nx">test</span><span class="p">();</span>
</code></pre></div></div>
<p>Gives output as.</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kc">undefined</span>
<span class="mi">20</span>
</code></pre></div></div>
<h3 id="explanation">Explanation</h3>
<p>This phenomenon is known as <strong>Javascript Variable Hoisting</strong>. At no point are
you accessing the global variable in your function; you’re only ever
accessing the local value variable. Your code is equivalent to the
following:</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">value</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>
<span class="kd">function</span> <span class="nx">test</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">value</span><span class="p">;</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">value</span><span class="p">);</span>
<span class="kd">var</span> <span class="nx">value</span> <span class="o">=</span> <span class="mi">20</span><span class="p">;</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">value</span><span class="p">);</span>
<span class="p">}</span>
<span class="nx">test</span><span class="p">();</span>
</code></pre></div></div>
<h4 id="simple-explanation">Simple Explanation:</h4>
<blockquote>
<p>Variables in JavaScript always have function-wide scope. Even if they were
defined in the middle of the function, they are visible before. Similar
phenomena may be observed with function hoisting.</p>
</blockquote>
<blockquote>
<p>That being said, the first <code class="language-plaintext highlighter-rouge">console.log(value)</code> sees the value variable (the
inner one which shadows the outer value), but it has not yet been initialized.
You can think of it as if all variable declarations were implicitly moved to
the beginning of the function (not inner-most code block), while the
definitions are left on the same place.</p>
</blockquote>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">a</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">a</span><span class="dl">'</span><span class="p">;</span>
<span class="c1">// lines of code</span>
<span class="kd">var</span> <span class="nx">b</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">b</span><span class="dl">'</span><span class="p">;</span>
<span class="c1">// more lines of code</span>
<span class="kd">var</span> <span class="nx">c</span><span class="o">=</span> <span class="dl">'</span><span class="s1">c</span><span class="dl">'</span><span class="p">;</span> <span class="c1">// antipattern</span>
<span class="c1">// final lines of scripting</span>
<span class="p">})();</span>
</code></pre></div></div>
<p>Will be rewritten by the interpreter as;</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">a</span><span class="p">,</span> <span class="nx">b</span><span class="p">,</span> <span class="nx">c</span><span class="p">;</span> <span class="c1">// variables declared</span>
<span class="nx">a</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">a</span><span class="dl">'</span><span class="p">;</span>
<span class="c1">// lines of code</span>
<span class="nx">b</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">b</span><span class="dl">'</span><span class="p">;</span> <span class="c1">// initialized</span>
<span class="c1">// more lines of code</span>
<span class="nx">c</span><span class="o">=</span> <span class="dl">'</span><span class="s1">c</span><span class="dl">'</span><span class="p">;</span> <span class="c1">// initialized</span>
<span class="c1">// final lines of scripting</span>
<span class="p">})();</span>
</code></pre></div></div>
<h4 id="complex-explanation">Complex Explanation:</h4>
<blockquote>
<p>This is something that every Javascript programmer bumps into sooner or later.
Simply put, whatever variables you declare are always hoisted to the top of
your local closure. So, even though you declared your variable after the first
<code class="language-plaintext highlighter-rouge">console.log</code> call, it’s still considered as if you had declared it before
that. However, only the declaration part is being hoisted; the assignment, on
the other hand, is not.</p>
</blockquote>
<blockquote>
<p>So, when you first called <code class="language-plaintext highlighter-rouge">console.log(value)</code>, you were referencing your
locally declared variable, which has got nothing assigned to it yet; hence
undefined.</p>
</blockquote>
<h4 id="other-function-hoisting">Other: Function Hoisting</h4>
<p>Function hoisting means that functions are moved to the top of their scope. That
is;</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">b</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">a</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>
<span class="k">return</span><span class="p">;</span>
<span class="kd">function</span> <span class="nx">a</span><span class="p">()</span> <span class="p">{}</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Will be rewritten by the interpreter as;</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">b</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">function</span> <span class="nx">a</span><span class="p">()</span> <span class="p">{}</span>
<span class="nx">a</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span>
<span class="k">return</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>
<p>Also;</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">function</span> <span class="nx">a</span><span class="p">()</span> <span class="p">{}</span>
</code></pre></div></div>
<p>behaves the same as;</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">a</span> <span class="o">=</span> <span class="kd">function</span> <span class="p">()</span> <span class="p">{};</span>
</code></pre></div></div>
<p>So all the function declarations are eventually assigned to a variable. In
Javascript, functions are first class objects, just like strings and numbers.
That means they are defined as variables and can be passed to other functions,
be stored in arrays, and so on.</p>
<hr />
<ol>
<li><a href="http://www.adequatelygood.com/JavaScript-Scoping-and-Hoisting.html">Adequately Good Decent Programming Advice: JavaScript Scoping and
Hoisting</a></li>
<li><a href="http://net.tutsplus.com/tutorials/javascript-ajax/quick-tip-javascript-hoisting-explained/">Nettuts: Quick Tip: JavaScript Hoisting Explained</a></li>
<li><a href="http://stackoverflow.com/questions/9085839/surprised-that-global-variable-has-undefined-value-in-">Stack Overflow: Surprised that global variable has undefined value in
JavaScript</a></li>
<li><a href="http://stackoverflow.com/questions/7506844/javascript-function-scoping-and-hoisting">Stack Overflow: Javascript function scoping and hoisting</a></li>
<li><a href="http://stackoverflow.com/questions/8351293/javascript-variable-declarations-at-the-head-of-a-function">Stack Overflow: Javascript variable declarations at the head of a
function</a></li>
</ol>
King'ori Maina
http://kingori.co/
Image Attachments as files in Apple Mail ∞
2013-05-09T00:00:00+00:00
kingori.co:/minutae/2013/05/apple-mail-image-attachments/
<blockquote>
<p>Mail.app by default displays images inline, and most email clients won’t
recognize them as attachments. If you right click (or ctrl click with a one
button mouse) on the image you can select to view the image as icon, which
makes it behave like a normal attachment. To make this the default behavior
you’ll need to use the Terminal to set the preference. Terminal is in
<code class="language-plaintext highlighter-rouge">Applications Utilities</code>. Open Terminal and type:</p>
</blockquote>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>defaults write com.apple.mail DisableInlineAttachmentViewing <span class="nt">-bool</span> <span class="nb">yes</span>
</code></pre></div></div>
<p>If you decide this isn’t what you’re looking for, to restore inline attachment
viewing type:</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>defaults write com.apple.mail DisableInlineAttachmentViewing <span class="nt">-bool</span> <span class="nb">false</span>
</code></pre></div></div>
<p>Restart Mail and you’re back to normal.</p>
<p>
<a title="Permalink to 'Image Attachments as files in Apple Mail'" href="http://kingori.co/minutae/2013/05/apple-mail-image-attachments/" target="_blank">↩</a>
</p>
King'ori Maina
http://kingori.co/
Fast counting of rows on InnoDB
2013-05-06T00:00:00+00:00
kingori.co:/minutae/2013/05/mysql-count-innodb/
<p>See, MyISAM always stores the number of rows on the table header. So, whenever
we ask “how many rows are there?”, it can just grab the count and return it. Not
InnoDB. This makes InnoDB very slow in count queries without a where clause.</p>
<blockquote>
<p>So if you have query like SELECT COUNT(*) FROM USER It will be much faster for
MyISAM (MEMORY and some others) tables because they would simply read number
of rows in the table from stored value. Innodb will however need to perform
full table scan or full index scan because it does not have such counter, it
also can’t be solved by simple singe counter for Innodb tables as different
transactions may see different number of rows in the table.</p>
</blockquote>
<blockquote>
<p>If you have query like SELECT COUNT(*) FROM IMAGE WHERE USER_ID=5 this query
will be executed same way both for MyISAM and Innodb tables by performing
index rage scan. This can be faster or slower both for MyISAM and Innodb
depending on various conditions.</p>
</blockquote>
<blockquote>
<p>The trick is to hint it at a specific index. So, if you’re getting poor
response times from InnoDB count, it means you’ve got lots of rows that have
to be counted one at a time. And since you’ve got a lot of rows, you have at
least one index. Just pick an index that will never contain a NULL value, and
tell MySQL to ‘use index (index_name)’.</p>
</blockquote>
<div class="language-sql highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">mysql</span><span class="o">></span> <span class="k">SELECT</span> <span class="k">count</span><span class="p">(</span><span class="o">*</span><span class="p">)</span> <span class="k">FROM</span> <span class="n">messages</span> <span class="n">USE</span> <span class="k">INDEX</span> <span class="p">(</span><span class="n">index_messages_on_remote_created_at</span><span class="p">);</span>
</code></pre></div></div>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>+----------+
| count(*) |
+----------+
| 1276831 |
+----------+
1 row in set (3.19 sec)
</code></pre></div></div>
<hr />
<ol>
<li><a href="http://www.cloudspace.com/blog/2009/08/06/fast-mysql-innodb-count-really-fast/">Fast MySQL InnoDB count. Really fast</a></li>
<li><a href="http://www.mysqlperformanceblog.com/2006/12/01/count-for-innodb-tables/">MySQL Performance Blog: COUNT(*) for Innodb Tables</a></li>
<li><a href="http://dev.mysql.com/doc/refman/5.1/en/counting-rows.html">MySQL 5.1 Reference Manual: Counting Rows</a></li>
<li>COUNT doesn’t count NULL values, so if you are counting values <em>by a field</em> that has NULL values, those rows won’t be counted by COUNT.</li>
</ol>
King'ori Maina
http://kingori.co/
Fit relative positioned parent to height of absolute positioned child
2013-05-03T00:00:00+00:00
kingori.co:/minutae/2013/05/relative-parent-absolute-children/
<p><em>Parent elements cannot use <code class="language-plaintext highlighter-rouge">"height:auto"</code> when their children are positioned
absolute/ fixed.</em></p>
<blockquote>
<p>Absolutely-positioned items are logically-associated with their parent, but
not “physically”. They’re not part of the layout, so the parent item can’t
really see how big they are. You need to code the size yourself, or sniff it
with JavaScript and set it at run-time.</p>
</blockquote>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">var</span> <span class="nx">biggestHeight</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">0</span><span class="dl">"</span><span class="p">;</span>
<span class="c1">// Loop through elements children to find & set the biggest height</span>
<span class="nx">$</span><span class="p">(</span><span class="dl">"</span><span class="s2">.container *</span><span class="dl">"</span><span class="p">).</span><span class="nx">each</span><span class="p">(</span><span class="kd">function</span><span class="p">(){</span>
<span class="c1">// If this elements height is bigger than the biggestHeight</span>
<span class="k">if</span> <span class="p">(</span><span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">height</span><span class="p">()</span> <span class="o">></span> <span class="nx">biggestHeight</span> <span class="p">)</span> <span class="p">{</span>
<span class="c1">// Set the biggestHeight to this Height</span>
<span class="nx">biggestHeight</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">).</span><span class="nx">height</span><span class="p">();</span>
<span class="p">}</span>
<span class="p">});</span>
<span class="c1">// Set the container height</span>
<span class="nx">$</span><span class="p">(</span><span class="dl">"</span><span class="s2">.container</span><span class="dl">"</span><span class="p">).</span><span class="nx">height</span><span class="p">(</span><span class="nx">biggestHeight</span><span class="p">);</span>
</code></pre></div></div>
<p><em>Ps: The above snippet shows a concept and is not a one-size-fits-all solution.
You need to adapt it to your use case appropriately. I know I did.</em></p>
<hr />
<ol>
<li><a href="http://stackoverflow.com/questions/8577090/css-fit-relative-positioned-parent-to-height-of-absolute-positioned-child">CSS: fit relative positioned parent to height of absolute positioned
child</a></li>
<li><a href="http://stackoverflow.com/questions/9061520/auto-height-on-parent-container-with-absolute-fixed-children">Auto height on parent container with Absolute/Fixed Children</a></li>
</ol>
King'ori Maina
http://kingori.co/
Handling MODX conditionals efficiently ∞
2013-05-01T00:00:00+00:00
kingori.co:/minutae/2013/05/modx-conditionals/
<h3 id="build-tags-as-a-result-of-a-conditional-not-in-conditional-results">Build tags as a result of a conditional, not in conditional results</h3>
<p>An example using conditional filter expressions that have multiple conditional
paths. Here is a simple conditional that can quickly become a drain on
performance because of the order of parsing;</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[[*field:is=`0`:then=`[[!SomeScript]]`:else=`[[$SomeChunk]]`]]
</code></pre></div></div>
<p>When MODX parses this tag, each of the tags contained in the then and the else
conditional paths are parsed, The <code class="language-plaintext highlighter-rouge">*field</code> tag itself is parsed and finally, the
conditional filter is applied. In other words, regardless of the result of your
conditional comparison, everything in both conditional paths is executed
recursively to it’s logical end!</p>
<p>How big of an unnecessary burden this becomes depends entirely on the nature of
the tags involved. But you can see how it can quickly get out of control when
many conditionals are involved.</p>
<p>The brilliantly simple way to avoid this problem? Just return what’s between the
MODX tags and have the result of your conditional build what is going to be
parsed next by MODX.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>[[[[*field:is=`0`:then=`!SomeScript`:else=`$SomeChunk`]]]]
</code></pre></div></div>
<p>MODX shouldn’t take your tags and run with them when embedded as results in
conditional paths. Make it wait until you’ve evaluated your condition to do
anything about it.</p>
<hr />
<ol>
<li><a href="https://gist.github.com/opengeek/3744346">Example of optimizing conditional filters using a Chunk wrapper</a></li>
<li>Check out the <a href="http://modx.com/blog/2012/09/14/tags-as-the-result-or-how-conditionals-are-like-mosquitoes/#comments">comments</a> on the original post as well</li>
</ol>
<p>
<a title="Permalink to 'Handling MODX conditionals efficiently'" href="http://kingori.co/minutae/2013/05/modx-conditionals/" target="_blank">↩</a>
</p>
King'ori Maina
http://kingori.co/
Loading LESS files from Amazon S3 (cross-domain)
2013-04-30T00:00:00+00:00
kingori.co:/minutae/2013/04/less-cross-domain-access/
<h3 id="problem">Problem</h3>
<p>If you have a static file server on S3 … this loads fine:</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><link</span> <span class="na">rel=</span><span class="s">"stylesheet"</span>
<span class="na">href=</span><span class="s">"http://static.example.com/css/screen.less"</span>
<span class="na">type=</span><span class="s">"text/css"</span>
<span class="na">media=</span><span class="s">"screen, projection, print"</span><span class="nt">></span>
</code></pre></div></div>
<p>This … does not load.</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><link</span> <span class="na">rel=</span><span class="s">"stylesheet/less"</span>
<span class="na">href=</span><span class="s">"http://static.example.com/css/screen.less"</span>
<span class="na">type=</span><span class="s">"text/css"</span>
<span class="na">media=</span><span class="s">"screen, projection, print"</span><span class="nt">></span>
</code></pre></div></div>
<h3 id="reason">Reason</h3>
<blockquote>
<p>Cross-site HTTP requests are HTTP requests for resources from a different
domain than the domain of the resource making the request. For instance, a
resource loaded from Domain A (http://domaina.example) such as an HTML web
page, makes a request for a resource on Domain B (http://domainb.foo), such as
an image, using the img element (http://domainb.foo/image.jpg). This occurs
very commonly on the web today — pages load a number of resources in a cross-
site manner, including CSS stylesheets, images and scripts, and other
resources.</p>
</blockquote>
<blockquote>
<p>Cross-site HTTP requests initiated from within scripts have been subject to
well-known restrictions, for well-understood security reasons. For example
HTTP Requests made using the XMLHttpRequest object were subject to the same-
origin policy. In particular, this meant that a web application using
XMLHttpRequest could only make HTTP requests to the domain it was loaded from,
and not to other domains. Developers expressed the desire to safely evolve
capabilities such as XMLHttpRequest to make cross-site requests, for better,
safer mash-ups within web applications.</p>
</blockquote>
<p><a href="https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS">Read more here …</a></p>
<h3 id="fix-amazon-s3-only">Fix (Amazon S3 Only)</h3>
<p>If you’re using Amazon S3, they <a href="https://forums.aws.amazon.com/ann.jspa?annID=1620">announced Cross-Origin Resource Sharing (CORS)
support</a> … enable cross domain using a CORs policy just like the one
below … (for GET requests, see official documentation for more examples and
details).</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><CORSConfiguration></span>
<span class="nt"><CORSRule></span>
<span class="nt"><AllowedOrigin></span>http://domain1.com<span class="nt"></AllowedOrigin></span>
<span class="nt"><AllowedOrigin></span>http://domain2<span class="nt"></AllowedOrigin></span>
<span class="nt"><AllowedMethod></span>GET<span class="nt"></AllowedMethod></span>
<span class="nt"><AllowedHeader></span>*<span class="nt"></AllowedHeader></span>
<span class="nt"><MaxAgeSeconds></span>3000<span class="nt"></MaxAgeSeconds></span>
<span class="nt"><ExposeHeader></span>x-amz-server-side-encryption<span class="nt"></ExposeHeader></span>
<span class="nt"><ExposeHeader></span>x-amz-request-id<span class="nt"></ExposeHeader></span>
<span class="nt"><ExposeHeader></span>x-amz-id-2<span class="nt"></ExposeHeader></span>
<span class="nt"></CORSRule></span>
<span class="nt"></CORSConfiguration></span>
</code></pre></div></div>
<p>S3 will then send the appropriate <a href="https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS#The_HTTP_response_headers"><code class="language-plaintext highlighter-rouge">The_HTTP_response_headers</code></a>.</p>
<hr />
<ol>
<li><a href="https://github.com/cloudhead/less.js/issues/161">In-browser rel=”stylesheet/less” not loading from static file server</a></li>
<li><a href="https://forums.aws.amazon.com/ann.jspa?annID=1620">Announcement: Announcing Amazon S3 Support for Cross-Origin Resource Sharing
(CORS)</a></li>
<li><a href="http://docs.aws.amazon.com/AmazonS3/latest/dev/cors.html#how-do-i-enable-cors">How Do I Enable CORS On My Bucket?</a></li>
<li><a href="https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS">HTTP access control (CORS)</a> - <a href="https://developer.mozilla.org/">Mozilla Developer Network</a></li>
</ol>
King'ori Maina
http://kingori.co/
Getting Eclipse to play nicely with the MacBook Pro with Retina Display ∞
2013-04-25T00:00:00+00:00
kingori.co:/minutae/2013/04/eclipse-retina/
<p>Comment <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=382972#c4">#4</a>.</p>
<blockquote>
<p>that did, indeed, fix it for me.</p>
</blockquote>
<p>Read comment <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=382972#c5">#5</a> & <a href="https://bugs.eclipse.org/bugs/show_bug.cgi?id=382972#c6">#6</a> as well.</p>
<hr />
<ol>
<li>Credit should be given where it’s due, <a href="http://www.mjbshaw.com/2012/11/getting-android-emulator-and-macbook.html">this post</a> pointed me in
the right direction</li>
</ol>
<p>
<a title="Permalink to 'Getting Eclipse to play nicely with the MacBook Pro with Retina Display'" href="http://kingori.co/minutae/2013/04/eclipse-retina/" target="_blank">↩</a>
</p>
King'ori Maina
http://kingori.co/
Autoscaling on EC2 with ELB & Cloudwatch on Ubuntu
2013-04-22T00:00:00+00:00
kingori.co:/minutae/2013/04/aws-autoscaling/
<p><em>Please note that this is not a detailed guide … relevant links are included
if you want detail. The objective is to highlight the key steps or rather, the
‘points-to-note ‘throughout the process. A LOT is assumed.</em></p>
<h3 id="basic-expected-setup">Basic Expected Setup</h3>
<p>The first obvious assumption is that you are running Ubuntu. Running <a href="http://www.ubuntu.com/cloud/public-cloud/guest">Ubuntu
Cloud Guest</a> on <a href="https://aws.amazon.com/">Amazon Web Services</a> requires you to go through
the following steps;</p>
<ol>
<li>Create your account on Amazon (if you do not already have one) and setup your
credentials - <a href="http://docs.aws.amazon.com/gettingstarted/latest/awsgsg-intro/getstarted.html">Getting Started With Aws</a></li>
<li><a href="https://help.ubuntu.com/community/EC2StartersGuide">Install Amazon EC2 API Tools</a></li>
<li>Instantiate your <a href="http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/AMIs.html">images(s)</a></li>
<li>Configure your <a href="http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/Instances.html">instance</a></li>
</ol>
<p>Details of the above steps can be <a href="https://help.ubuntu.com/community/EC2StartersGuide">found here</a> … though they
seem a bit complicated due to reliance on the CLI, but if its any consolation,
<em>some</em> of the tasks can be done via the <a href="https://aws.amazon.com/console/">Amazon Web Console</a>.</p>
<p>Double check you have the following environment variables set up in your shell
profile. You should have something close to … (see below code block) … in
your <code class="language-plaintext highlighter-rouge">~/.bashrc</code> if you use bash as your shell.</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c"># WHERE YOUR JAVA IS</span>
<span class="nb">export </span><span class="nv">JAVA_HOME</span><span class="o">=</span>/usr
<span class="c">##################</span>
<span class="c">## Amazon Paths ##</span>
<span class="c">##################</span>
<span class="c"># Set variables for each service</span>
<span class="nb">export </span><span class="nv">EC2_HOME</span><span class="o">=</span>/usr/local/aws/ec2
<span class="nb">export </span><span class="nv">AWS_IAM_HOME</span><span class="o">=</span>/usr/local/aws/iam
<span class="nb">export </span><span class="nv">AWS_RDS_HOME</span><span class="o">=</span>/usr/local/aws/rds
<span class="nb">export </span><span class="nv">AWS_ELB_HOME</span><span class="o">=</span>/usr/local/aws/elb
<span class="nb">export </span><span class="nv">AWS_CLOUDFORMATION_HOME</span><span class="o">=</span>/usr/local/aws/cfn
<span class="nb">export </span><span class="nv">AWS_AUTO_SCALING_HOME</span><span class="o">=</span>/usr/local/aws/as
<span class="nb">export </span><span class="nv">CS_HOME</span><span class="o">=</span>/usr/local/aws/cloudsearch
<span class="nb">export </span><span class="nv">AWS_CLOUDWATCH_HOME</span><span class="o">=</span>/usr/local/aws/cloudwatch
<span class="nb">export </span><span class="nv">AWS_ELASTICACHE_HOME</span><span class="o">=</span>/usr/local/aws/elasticache
<span class="nb">export </span><span class="nv">AWS_SNS_HOME</span><span class="o">=</span>/usr/local/aws/sns
<span class="nb">export </span><span class="nv">AWS_ROUTE53_HOME</span><span class="o">=</span>/usr/local/aws/route53
<span class="nb">export </span><span class="nv">AWS_CLOUDFRONT_HOME</span><span class="o">=</span>/usr/local/aws/cloudfront
<span class="c"># This iterates through the list passed into it and sets the PATHs</span>
<span class="k">for </span>i <span class="k">in</span> <span class="nv">$EC2_HOME</span> <span class="nv">$AWS_IAM_HOME</span> <span class="nv">$AWS_RDS_HOME</span> <span class="nv">$AWS_ELB_HOME</span> <span class="nv">$AWS_CLOUDFORMATION_HOME</span> <span class="nv">$AWS_AUTO_SCALING_HOME</span> <span class="nv">$CS_HOME</span> <span class="nv">$AWS_CLOUDWATCH_HOME</span> <span class="nv">$AWS_ELASTICACHE_HOME</span> <span class="nv">$AWS_SNS_HOME</span> <span class="nv">$AWS_ROUTE53_HOME</span> <span class="nv">$AWS_CLOUDFRONT_HOME</span> /usr/local/aws/s3
<span class="k">do
</span><span class="nv">PATH</span><span class="o">=</span><span class="nv">$i</span>/bin:<span class="nv">$PATH</span>
<span class="k">done
</span><span class="nv">PATH</span><span class="o">=</span>/usr/local/aws/elasticbeanstalk/eb/linux/python2.7:<span class="nv">$PATH</span>
<span class="nv">PATH</span><span class="o">=</span>/usr/local/aws/elasticmapreduce:<span class="nv">$PATH</span>
<span class="c">########################</span>
<span class="c">## Amazon Credentials ##</span>
<span class="c">########################</span>
<span class="c"># Choose whatever path, in this case it is `$HOME/.aws/...` this then set</span>
<span class="c"># the relevant paths for authentification stuff</span>
<span class="nb">export </span><span class="nv">EC2_PRIVATE_KEY</span><span class="o">=</span><span class="si">$(</span><span class="nb">echo</span> <span class="nv">$HOME</span>/.aws/pk-<span class="k">*</span>.pem<span class="si">)</span>
<span class="nb">export </span><span class="nv">EC2_CERT</span><span class="o">=</span><span class="si">$(</span><span class="nb">echo</span> <span class="nv">$HOME</span>/.aws/cert-<span class="k">*</span>.pem<span class="si">)</span>
<span class="nb">export </span><span class="nv">AWS_CREDENTIAL_FILE</span><span class="o">=</span><span class="nv">$HOME</span>/.aws/aws-credential-file.txt
<span class="nb">export </span><span class="nv">ELASTIC_MAPREDUCE_CREDENTIALS</span><span class="o">=</span><span class="nv">$HOME</span>/.aws/aws-credentials.json
</code></pre></div></div>
<p>Refresh environment variables after editing <code class="language-plaintext highlighter-rouge">~/.bashrc</code> file. Just to be sure.</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span><span class="nb">source</span> ~/.bashrc
</code></pre></div></div>
<p>There’s probably something I’ve left out but that’s the general idea + the set
up process is well documented online, <a href="https://www.google.com/search?q=setting+up+amazon+api+tools&aq=f&oq=setting+up+amazon+api+tools">a simple google search should
do</a>.</p>
<p><em>Ps: If you have services in other regions (from the US default) you have to set
some URLs in the <code class="language-plaintext highlighter-rouge">~/.bashrc</code> file. Don’t worry, keep reading … I’ve mentioned
this with a litlle more detail ahead.</em></p>
<h3 id="adding-support-for-the-other-services">Adding Support For The Other Services</h3>
<p>To put it simply, the <a href="http://packages.ubuntu.com/search?keywords=ec2-api-tools"><code class="language-plaintext highlighter-rouge">ec2-api-tools</code></a> only install <code class="language-plaintext highlighter-rouge">ec2-*</code> commands.</p>
<p>What I mean is that, after installing the api-tools you should have access to
<code class="language-plaintext highlighter-rouge">ec2-*</code> type commands but no <code class="language-plaintext highlighter-rouge">as-*</code> (autoscaling), <code class="language-plaintext highlighter-rouge">elb-*</code> (elastic load
balancer) etc. type commands - i.e. the other services. That’s because you have
to manually install them. Check the <a href="http://aws.amazon.com/developertools">AWS Developer Tools</a> for
official documentation on the tools, changelog & download links or check out
this <a href="http://www.linux-support.com/cms/ubuntu-developers-eric-hammond-installing-aws-command-line-tools-from-amazon-downloads/">blog- post</a>. Below is a list of commonly used API tools …</p>
<ul>
<li><a href="http://aws.amazon.com/developertools/351">Amazon EC2 Command Line Tool</a></li>
<li><a href="http://aws.amazon.com/developertools/2535">Auto Scaling Command Line Tool</a></li>
<li><a href="http://aws.amazon.com/developertools/2536">Elastic Load Balancing Command Line Tool</a></li>
<li><a href="http://aws.amazon.com/developertools/2534">Amazon CloudWatch Command Line Tool</a></li>
</ul>
<p>Assuming you are the super user & taking the Elastic Load Balanacer as an
example, copy the files from the <code class="language-plaintext highlighter-rouge">bin/</code> & <code class="language-plaintext highlighter-rouge">lib/</code> folders (you see them after
unzipping the downloaded file) into the respective folder for the service as was
seen in the <code class="language-plaintext highlighter-rouge">~/.bashrc</code> file earlier. Please note that after installing the <code class="language-plaintext highlighter-rouge">ec2
-api-tools</code>, the <code class="language-plaintext highlighter-rouge">/usr/local/aws/</code> folder should not exist (unless you made them
yourself) since its actually never been created. The following commands
therefore should create the folders (with sub- folders) for you.</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>wget <span class="nt">--quiet</span> http://ec2-downloads.s3.amazonaws.com/ElasticLoadBalancing.zip
<span class="gp">$</span><span class="w"> </span>unzip <span class="nt">-qq</span> ElasticLoadBalancing.zip
<span class="gp">$</span><span class="w"> </span>rsync <span class="nt">-a</span> <span class="nt">--no-o</span> <span class="nt">--no-g</span> ElasticLoadBalancing-<span class="k">*</span>/ /usr/local/aws/elb/
</code></pre></div></div>
<p>And so on - repeat for each service that you wnat to add.</p>
<p>Once your done, the commands for each service should now be available to your
shell.</p>
<p>Now we begin …</p>
<h3 id="configuring-autoscaling-using-elb--ec2">Configuring Autoscaling Using ELB & EC2</h3>
<h4 id="prerequisite-1-createchoose-custom-ami">Prerequisite 1: Create/Choose Custom AMI</h4>
<p>If you haven’t created an AMI from one of your running EC2 instances, create one
now, or click over to your AMIs page on the AWS Console to retrieve the AMI ID
to be used as a template, and write it down. You’ll need an AMI ID later. Think
of it as your autoscaling-instance-template.</p>
<p><em>Ps: If you already have a running EBS-backed instance, you can save this Amazon
Machine Image (AMI) and autoscale with it … <a href="http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/creating-an-ami.html">find steps on how to create your
own AMIs here</a></em></p>
<h4 id="prerequisite-2-set-up-your-your-elb">Prerequisite 2: Set Up Your Your ELB</h4>
<p>The ELB name that is displayed on the AWS Console will also be required at some
point. You can use the AWS Console to <a href="http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/gs-ec2classic.html">create an ELB</a> if you don’t have
one. Once your ELB is up, you will most likely create a CNAME record at your DNS
provider pointing your landing page or vanity domain to the DNS name given in
the AWS Console. Visit <a href="http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/using-domain-names-with-elb.html">‘Use Domain Names with Elastic Load Balancing’</a>
at Amazon AWS Documentation page for details on this.</p>
<h4 id="prerequisite-3-check-credentials-keys-authorizations-are-in-order">Prerequisite 3: Check Credentials/ Keys/ Authorizations Are In Order</h4>
<p>Some services will fail if the credentials are not in order. Common mistake is
to set the key & secret and assume that’s all that the other services
require. For example, <a href="http://docs.aws.amazon.com/AutoScaling/latest/GettingStartedGuide/SetupCLI.html#AS_Generic_GSG_Configure">check out the set up process for autoscaling</a> …
it requires the <code class="language-plaintext highlighter-rouge">aws-credential-file.txt</code> that’s referenced in <code class="language-plaintext highlighter-rouge">~/.bashrc</code>.</p>
<p>When setting up the credential file, check in the unzipped folder of the service
for the <code class="language-plaintext highlighter-rouge">credential-file-path.template</code> to use as a reference for your own
credentials file.</p>
<p>Also … By default, the Auto Scaling command line interface (CLI) uses the
Eastern United States Region (us-east-1) with the autoscaling.us-
east-1.amazonaws.com service endpoint URL. If your instances are in a different
region, you must specify the region where your instances reside by setting the
AWS_AUTO_SCALING_URL environment variable.</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span><span class="nb">export </span><span class="nv">AWS_AUTO_SCALING_URL</span><span class="o">=</span>https://autoscaling.eu-west-1.amazonaws.com
</code></pre></div></div>
<p>Same as the ELB …</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span><span class="nb">export </span><span class="nv">AWS_ELB_URL</span><span class="o">=</span>https://elasticloadbalancing.eu-west-1.amazonaws.com
</code></pre></div></div>
<p>Same as CloudWatch</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span><span class="nb">export </span><span class="nv">AWS_CLOUDWATCH_URL</span><span class="o">=</span>https://monitoring.eu-west-1.amazonaws.com
</code></pre></div></div>
<h4 id="step-1-create-an-elastic-load-balancer">Step 1: Create An Elastic Load Balancer</h4>
<p>That’s if you haven’t already … <a href="http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/gs-ec2classic.html">spend some time here</a>.</p>
<h4 id="step-2-create-launch-config">Step 2: Create Launch Config</h4>
<blockquote>
<p>The launch configuration specifies the template that Auto Scaling uses to
launch Amazon EC2 instances. This template contains all the information
necessary for Auto Scaling to launch instances that run your application.</p>
</blockquote>
<blockquote>
<p>A launch configuration is a template that the Auto Scaling group uses to
launch Amazon EC2 instances. You create the launch configuration by including
information such as the Amazon machine image ID to use for launching the EC2
instance, the instance type, key pairs, security groups, and block device
mappings, among other configuration settings. When you create your Auto
Scaling group, you must associate it with a launch configuration. You can
attach only one launch configuration to an Auto Scaling group at a time.
Launch configurations cannot be modified. They are immutable. If you want to
change the launch configuration of your Auto Scaling group, you have to first
create a new launch configuration and then update your Auto Scaling group by
attaching the new launch configuration. When you attach a new launch
configuration to your Auto Scaling group, any new instances will be launched
using the new configuration parameters. Existing instances are not affected.</p>
</blockquote>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>as-create-launch-config AutoscaleLC <span class="se">\</span>
<span class="nt">--image-id</span><span class="o">=</span><span class="s2">"ami-xxxxxxxxc"</span> <span class="se">\</span>
<span class="nt">--instance-type</span><span class="o">=</span><span class="s2">"m1.small"</span> <span class="se">\</span>
<span class="nt">--group</span><span class="o">=</span><span class="s2">"your-security-group"</span> <span class="se">\</span>
<span class="nt">--key</span><span class="o">=</span><span class="s2">"~/.aws/your-key.pem"</span>
<span class="go">OK-Created launch config
</span></code></pre></div></div>
<p>Don’t forget to set the <code class="language-plaintext highlighter-rouge">--key YourKey</code> especially if you want to ssh into the
instances … you can get a list of your keys from here in case you don’t
remember.</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>ec2-describe-keypairs
</code></pre></div></div>
<h4 id="step-3-create-an-auto-scaling-group">Step 3: Create an Auto Scaling Group</h4>
<blockquote>
<p>An Auto Scaling group is a collection of Amazon EC2 instances. You can specify
settings like the minimum, maximum, and desired number of EC2 instances for an
Auto Scaling group to which you want to apply certain scaling actions.</p>
</blockquote>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>as-create-auto-scaling-group AutoScalingGroup <span class="se">\</span>
<span class="nt">--availability-zones</span><span class="o">=</span><span class="s2">"eu-west-1a"</span> <span class="se">\</span>
<span class="nt">--launch-configuration</span><span class="o">=</span><span class="s2">"AutoscaleLC"</span> <span class="se">\</span>
<span class="nt">--min-size</span><span class="o">=</span><span class="s2">"1"</span> <span class="se">\</span>
<span class="nt">--max-size</span><span class="o">=</span><span class="s2">"2"</span> <span class="se">\</span>
<span class="nt">--load-balancers</span><span class="o">=</span><span class="s2">"AutoscaleLB"</span> <span class="se">\</span>
<span class="nt">--desired-capacity</span><span class="o">=</span><span class="s2">"1"</span> <span class="se">\</span>
<span class="nt">--default-cooldown</span><span class="o">=</span><span class="s2">"300"</span> <span class="se">\</span>
<span class="nt">--grace-period</span><span class="o">=</span><span class="s2">"300"</span> <span class="se">\</span>
<span class="nt">--health-check-type</span><span class="o">=</span><span class="s2">"ELB"</span>
<span class="go">OK-Created AutoScalingGroup
</span></code></pre></div></div>
<h4 id="step-4-scale-up--down">Step 4: Scale Up & Down</h4>
<p>Scaling policie tells the Auto Scaling group what to do when the specified
conditions change.</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>as-put-scaling-policy <span class="se">\</span>
<span class="nt">--auto-scaling-group</span><span class="o">=</span><span class="s2">"AutoScalingGroup"</span> <span class="se">\</span>
<span class="nt">--name</span><span class="o">=</span><span class="s2">"scale-up"</span> <span class="se">\</span>
<span class="nt">--adjustment</span><span class="o">=</span><span class="s2">"1"</span> <span class="se">\</span>
<span class="nt">--type</span><span class="o">=</span><span class="s2">"ChangeInCapacity"</span> <span class="se">\</span>
<span class="nt">--cooldown</span><span class="o">=</span><span class="s2">"300"</span>
<span class="go">arn:aws:autoscaling:eu-west-1:xxxxxxxxxxxx:scalingPolicy:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:autoScalingGroupName/AutoscaleG:policyNameScaleUp
</span></code></pre></div></div>
<p>Basic upscale policy defined, named “scale-up,” a ChangeInCapacity policy to add
1 server and wait 3 minutes before another policy can be triggered. Below is the
reverse operation, or a “scale-down” policy to remove 1 server from the group.</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>as-put-scaling-policy <span class="se">\</span>
<span class="nt">--auto-scaling-group</span><span class="o">=</span><span class="s2">"AutoScalingGroup"</span> <span class="se">\</span>
<span class="nt">--name</span><span class="o">=</span><span class="s2">"scale-dn"</span> <span class="se">\</span>
<span class="nt">--adjustment</span><span class="o">=</span><span class="s2">"-1"</span> <span class="se">\</span>
<span class="nt">--type</span><span class="o">=</span><span class="s2">"ChangeInCapacity"</span> <span class="se">\</span>
<span class="nt">--cooldown</span><span class="o">=</span><span class="s2">"300"</span>
<span class="go">arn:aws:autoscaling:eu-west-1:xxxxxxxxxxxx:scalingPolicy:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:autoScalingGroupName/AutoscaleG:policyNameScaleUp
</span></code></pre></div></div>
<p>For details on the possible variations that can be applied such as the various
adjustment types you can <a href="http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/as-scale-based-on-demand.html">read this …</a></p>
<p><em>Ps: Cooldown period is in seconds.</em></p>
<h4 id="step-5-link-a-cloudwatch-event-to-an-auto-scaling-policy">Step 5: Link a CloudWatch event to an auto scaling policy</h4>
<p>Use the CloudWatch command mon-put-metric-alarm to create an alarm to for
increasing the size of the Auto Scaling group when the average CPU usage of all
the instances goes up to 80 percent.</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>mon-put-metric-alarmScaleUpAlarm <span class="se">\</span>
<span class="nt">--alarm-description</span><span class="o">=</span><span class="s2">"Scale up at 80% load"</span> <span class="se">\</span>
<span class="nt">--comparison-operator</span><span class="o">=</span><span class="s2">"GreaterThanOrEqualToThreshold"</span> <span class="se">\</span>
<span class="nt">--evaluation-periods</span><span class="o">=</span><span class="s2">"2"</span> <span class="se">\</span>
<span class="nt">--metric-name</span><span class="o">=</span><span class="s2">"CPUUtilization"</span> <span class="se">\</span>
<span class="nt">--namespace</span><span class="o">=</span><span class="s2">"AWS/EC2"</span> <span class="se">\</span>
<span class="nt">--period</span><span class="o">=</span><span class="s2">"120"</span> <span class="se">\</span>
<span class="nt">--statistic</span><span class="o">=</span><span class="s2">"Average"</span> <span class="se">\</span>
<span class="nt">--threshold</span><span class="o">=</span><span class="s2">"80"</span> <span class="se">\</span>
<span class="nt">--alarm-actions</span><span class="o">=</span><span class="s2">"arn:aws:autoscaling:eu-west-1:xxxxxxxxxxxx:scalingPolicy:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:autoScalingGroupName/AutoscaleG:policyNameScaleUp"</span> <span class="se">\</span>
<span class="nt">--dimensions</span><span class="o">=</span><span class="s2">"AutoScalingGroupName=AutoscaleG"</span>
<span class="go">OK-Created Alarm
</span></code></pre></div></div>
<p>Use the CloudWatch command mon-put-metric-alarm to create an alarm for
decreasing the size of the Auto Scaling group when the average CPU usage of all
the instances goes down 40 percent.</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>mon-put-metric-alarmScaleDownAlarm <span class="se">\</span>
<span class="nt">--alarm-description</span><span class="o">=</span><span class="s2">"Scale down at 40% load"</span> <span class="se">\</span>
<span class="nt">--comparison-operator</span><span class="o">=</span><span class="s2">"LessThanOrEqualToThreshold"</span> <span class="se">\</span>
<span class="nt">--evaluation-periods</span><span class="o">=</span><span class="s2">"2"</span> <span class="se">\</span>
<span class="nt">--metric-name</span><span class="o">=</span><span class="s2">"CPUUtilization"</span> <span class="se">\</span>
<span class="nt">--namespace</span><span class="o">=</span><span class="s2">"AWS/EC2"</span> <span class="se">\</span>
<span class="nt">--period</span><span class="o">=</span><span class="s2">"120"</span> <span class="se">\</span>
<span class="nt">--statistic</span><span class="o">=</span><span class="s2">"Average"</span> <span class="se">\</span>
<span class="nt">--threshold</span><span class="o">=</span><span class="s2">"40"</span> <span class="se">\</span>
<span class="nt">--alarm-actions</span><span class="o">=</span><span class="s2">"arn:aws:autoscaling:eu-west-1:xxxxxxxxxxxx:scalingPolicy:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx:autoScalingGroupName/AutoscaleG:policyNameScaleDown"</span> <span class="se">\</span>
<span class="nt">--dimensions</span><span class="o">=</span><span class="s2">"AutoScalingGroupName=AutoscaleG"</span>
<span class="go">OK-Created Alarm
</span></code></pre></div></div>
<p>You can create your own SNS notification for auto-scaling events from the
console if you want ie. send an email when X happens. Create a topic via the
console, this gives you an ARN something like this
<code class="language-plaintext highlighter-rouge">arn:aws:sns:************************</code></p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>as-put-notification-configuration <span class="se">\</span>
<span class="nt">--topic-arn</span><span class="o">=</span><span class="s2">"arn:aws:sns:************************"</span> <span class="se">\</span>
<span class="nt">--auto-scaling-group</span><span class="o">=</span><span class="s2">"MYTEST-SG"</span> <span class="se">\</span>
<span class="nt">--notification-types</span><span class="o">=</span><span class="s2">"autoscaling:EC2_INSTANCE_LAUNCH, autoscaling:EC2_INSTANCE_TERMINATE, autoscaling:EC2_INSTANCE_TERMINATE_ERROR, autoscaling:EC2_INSTANCE_LAUNCH_ERROR"</span>
<span class="go">OK-Put Notification Configuration
</span></code></pre></div></div>
<h3 id="considerations-when-scaling-lamp-type-servers">Considerations When Scaling LAMP-type Servers</h3>
<p>When migrating a single-server LAMP app to an autoscaling deployment often takes
some planning and changing some of the configuration a bit. For example, you’ll
need to store shared data, particularly sessions, on a separate instance, or
better yet, use Amazon’s shared MySQL cluster, called RDS.</p>
<p>By default, PHP stores sessions on disk as files, but that won’t work in your
example, because User A’s session token got written to the first server, while
User B’s is on server 2. But on their second or third request, the user’s
request can be served by a different server instance, so they’ll instantly be
logged out. That’s <a href="http://stackoverflow.com/questions/13911210/why-is-it-good-save-session-in-database">why you’ll want to use the database sessions</a>, and
use the same connection info from all your instances to a single database server
or RDS.</p>
<p>If you enable <a href="http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/US_StickySessions.html#US_EnableStickySessionsAppCookies">Application-Controlled Session Stickiness</a>;</p>
<blockquote>
<p>The load balancer uses a special cookie to associate the session with the
original server that handled the request, but follows the lifetime of the
application-generated cookie corresponding to the cookie name specified in the
policy configuration. The load balancer only inserts a new stickiness cookie
if the application response includes a new application cookie. The load
balancer stickiness cookie does not update with each request. If the
application cookie is explicitly removed or expires, the session stops being
sticky until a new application cookie is issued.</p>
</blockquote>
<blockquote>
<p>If an application server fails or is removed, the load balancer will try to
route the sticky session to another healthy application server. The load
balancer will try to stick to new healthy application server and continue
routing to currently stick application server even after the failed
application server comes back. However, it is up to the new application server
on how it’ll respond to a request which it has not seen previously.</p>
</blockquote>
<p>… so if your PHP app has a specific cookie it uses to manage settings, the ELB
will make sure the request is passed to the same server that issued the request.</p>
<p>Your AMI should only have Apache & PHP on it, and each instance will have the
same, shared MySQL server or RDS connection info, baked into the AMI. If users
can upload images, you’ll need to move them from the instance to a shared server
(rsync) or S3 bucket (cron script), and map that origin as your CloudFront
endpoint for caching …</p>
<p>- OR -</p>
<p>… you could just have each instance upload the shared-data directly to a
location that all the instances reference like S3. While AWS does a lot of the
heavy lifting it is expected that you at least understand how your
infrastructure is configured to achieve the desired result.</p>
<p>There are, of course, other ways of achieving the same end result, but the above
suggestions are the most common, easiest techniques within Amazon Web Services.</p>
<h3 id="points-to-note">Points To Note</h3>
<ul>
<li>
<p>Your original instance doesn’t have anything to do with Auto Scaling. It lives
outside of your Auto Scaling setup and will not be touched. When Auto Scaling
launches a new instance, it will always use the AMI you have defined in the
launch configuration. That AMI never changes. You simply get a copy of the data
from that point in time whenever an instance is launched.</p>
</li>
<li>
<p>Each instance is entirely separate. There is no connection between them. If
you make changes on one instance, you will need to walk through all of them
manually. These changes will not be persistent though. When a new instance is
launched, it will be a copy of the original AMI. So you will probably want to
replace the AMI instead. If you have some application code that can change, you
might want to consider building an AMI that can fetch everything on boot, and
maybe also react on changes somehow. If you can avoid having to replace the AMI
“all the time”, that is going to make it easier for you.</p>
</li>
<li>
<p>You don’t need an Elastic IP when you are using Elastic Load Balancing.</p>
</li>
<li>
<p>When you have a new AMI, you will need to create a new launch configuration
and update the Auto Scaling group. You can then, say, double the capacity, wait
for the new instances to become available, and finally have the old instances
terminated.</p>
</li>
</ul>
<hr />
<ol>
<li><a href="http://aws.amazon.com/developertools">AWS Developer Tools</a></li>
<li><a href="http://www.linux-support.com/cms/ubuntu-developers-eric-hammond-installing-aws-command-line-tools-from-amazon-downloads/">Ubuntu developers: Eric Hammond: Installing AWS Command Line Tools from
Amazon Downloads</a></li>
<li><a href="https://help.ubuntu.com/community/EC2StartersGuide">EC2StartersGuide</a></li>
<li><a href="http://kkpradeeban.blogspot.com/2011/01/auto-scaling-with-amazon-ec2.html">Autoscaling with EC2</a></li>
<li><a href="http://alestic.com/2012/09/aws-command-line-tools">Installing AWS Command Line Tools from Amazon Downloads</a></li>
<li><a href="http://www.loudsteve.com/2009/05/20/amazon-elastic-load-balancer-setup/">Amazon Elastic Load Balancer Setup</a></li>
<li><a href="http://www.cardinalpath.com/autoscaling-your-website-with-amazon-web-services-part-1/">Autoscaling your website with Amazon Web Services – Part 1</a></li>
<li><a href="http://www.cardinalpath.com/autoscaling-your-website-with-amazon-web-services-part-2/">Autoscaling your website with Amazon Web Services – Part 2</a></li>
<li><a href="http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/creating-an-ami.html">Create Your Own AMIs</a></li>
<li><a href="http://engineering.gnip.com/chef-ec2-auto-scaling-and-spot-instances-for-fun-and-profit/">Chef, EC2 Auto Scaling, and Spot Instances for Fun and Profit</a></li>
<li><a href="http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/using-domain-names-with-elb.html">Use Domain Names with Elastic Load Balancing</a></li>
<li><a href="http://aws.amazon.com/documentation/autoscaling/">Autoscaling Documentation - Amazon AWS</a></li>
<li><a href="http://aws.amazon.com/ec2/instance-types/">Amazon EC2 Instance Types</a></li>
<li><a href="http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/SettingUp_CommandLine.html">Setting Up the Amazon EC2 Command Line Tools</a></li>
<li><a href="http://docs.aws.amazon.com/AutoScaling/latest/GettingStartedGuide/SetupCLI.html#AS_Generic_GSG_Configure">Autoscaling Documentation: Set the AWS_CREDENTIAL_FILE environment
variable</a></li>
<li><a href="http://www.andrew-kirkpatrick.com/2011/09/register-ec2-instances-to-more-than-one-elastic-load-balancer/">Register EC2 Instances to more than one Elastic Load Balancer</a></li>
<li><a href="http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/as-scale-based-on-demand.html">Amazon AutoScaling Documentation: Scaling Based On Demand</a></li>
<li><a href="http://docs.aws.amazon.com/AutoScaling/latest/DeveloperGuide/AS_Concepts.html#Cooldown">Amazon AutoScaling Documentation: Cooldown Period</a></li>
<li><a href="http://docs.aws.amazon.com/ElasticLoadBalancing/latest/DeveloperGuide/US_StickySessions.html#US_EnableStickySessionsAppCookies">Enable Application-Controlled Session Stickiness</a></li>
<li><a href="http://stackoverflow.com/questions/13911210/why-is-it-good-save-session-in-database">Why Is It Good To Save Session in Database?</a></li>
<li><a href="https://forums.aws.amazon.com/thread.jspa?threadID=122659">Understanding autoscaled instances</a></li>
</ol>
King'ori Maina
http://kingori.co/
Image Magick, Imagick, Homebrew & MAMP-Pro ∞
2013-04-20T00:00:00+00:00
kingori.co:/minutae/2013/04/imagick-on-mamp-pro/
<p>Install <a href="https://developer.apple.com/xcode/">XCode</a> + the Command-Line Tools. (CL tools are not bundled with
<a href="http://developer.apple.com/library/ios/#documentation/DeveloperTools/Conceptual/WhatsNewXcode/Articles/xcode_4_3.html">Xcode 4.3</a> by default anymore and should contain build tools such as
<code class="language-plaintext highlighter-rouge">gcc</code> (confirm with whatever version you are using). XCode app (found on the
AppStore) is easy to install but the CL Tools can only be installed within XCode
as an optional install on the Components tab of the Downloads preferences
panel.</p>
<p>Install <a href="http://brew.sh/">Homebrew</a> which will be used to install libs/components as
well as manage the dependencies for us.</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>ruby <span class="nt">-e</span> <span class="s2">"</span><span class="si">$(</span>curl <span class="nt">-fsSL</span> https://raw.github.com/mxcl/homebrew/go<span class="si">)</span><span class="s2">"</span>
</code></pre></div></div>
<p>Install <a href="http://www.imagemagick.org/script/index.php">ImageMagick</a>.</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>brew <span class="nb">install </span>imagemagick
</code></pre></div></div>
<p>Installing a PHP53 compatible version of <a href="http://pecl.php.net/package/imagick">Imagick</a> … first let
Homebrew search the formula for you</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>brew search php53-imagick
</code></pre></div></div>
<p>… OR …</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>brew search imagick
</code></pre></div></div>
<p>The above searches should return something like ‘josegonzalez/php/php53-imagick’
… use this for the next step:</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>brew <span class="nb">install </span>josegonzalez/php/php53-imagick
</code></pre></div></div>
<p>If you get “No formula & taping” errors …</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>Error: No available formula for XYZ
Please tap it and then try again: brew tap XYZ
</code></pre></div></div>
<p>… do as you’ve been told, and run the ‘brew tap’ … command exactly as the
error told you. After that, repeat the step which caused that error.</p>
<p>Now edit MAMP config & add the extension to MAMP Pro’s php.ini. In MAMP Pro go
to the menubar, and choose <code class="language-plaintext highlighter-rouge">File > Edit Templates > PHP > PHP x.x.x php.ini</code>. A
simple editor window will popup where you can edit the ini file. A search for
the term ‘extension=’, will lead you to a block with various lines of
‘extension=…’. Now simply ad the following one and save the file:</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span><span class="nv">extension</span><span class="o">=</span><span class="s2">"/usr/local/Cellar/php53-imagick/3.1.0RC2/imagick.so"</span>
</code></pre></div></div>
<p>Copy libfreetype to MAMP lib (freetype version in path may vary)</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span><span class="nb">cp</span> /usr/local/Cellar/freetype/2.4.11/lib/libfreetype.6.dylib /Applications/MAMP/Library/lib/
</code></pre></div></div>
<p>Fix library version incompatibilities by open the file
<code class="language-plaintext highlighter-rouge">/Applications/MAMP/Library/bin/envvars</code> in the editor, and comment out the
following lines:</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span><span class="nv">cDYLD_LIBRARY_PATH</span><span class="o">=</span><span class="s2">"/Applications/MAMP/Library/lib:</span><span class="nv">$DYLD_LIBRARY_PATH</span><span class="s2">"</span>
<span class="gp">$</span><span class="w"> </span><span class="nb">export </span>DYLD_LIBRARY_PATH
</code></pre></div></div>
<p>Restart MAMP and check the phpinfo tab: a search for the term <code class="language-plaintext highlighter-rouge">imagick</code> should
bring you to a section reading like so:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>imagick module version 3.1.0RC2
imagick classes Imagick, ImagickDraw, ImagickPixel, ImagickPixelIterator
ImageMagick version ImageMagick 6.7.7-6 2012-09-18 Q16 http://www.imagemagick.org
ImageMagick copyright Copyright (C) 1999-2012 ImageMagick Studio LLC
ImageMagick release date 2012-09-18
ImageMagick number of supported formats: 191
</code></pre></div></div>
<p><em>Ps: Original post - see footnote #4, has extra’s on enabling tiff support</em></p>
<h4 id="update-7th052013-">Update <sup>7th/05/2013</sup> :</h4>
<p>After installing Imagemagick using Homebrew on Lion, everything is fine except
that it doesn’t work at all when being called from php.</p>
<div class="language-php highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">exec</span> <span class="p">(</span><span class="s1">'/usr/local/bin/convert'</span><span class="p">)</span> <span class="c1">// works, but</span>
<span class="nb">exec</span> <span class="p">(</span><span class="s1">'which convert'</span><span class="p">)</span> <span class="c1">// doesn't</span>
</code></pre></div></div>
<p>Turns out, for php to work convert should be in /usr/bin/ so this solved it:</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span><span class="nb">ln</span> <span class="nt">-s</span> /usr/local/bin/convert /usr/bin/convert
</code></pre></div></div>
<h4 id="update-25th122013-">Update <sup>25th/12/2013</sup> :</h4>
<p>This article was originally linked to <a href="https://github.com/jdlx/install_Imagick_on_MAMP/wiki/Imagick-for-MAMP-Pro---installation-guide">this</a> … which is now broken. I’ve
also update Homebrew links which seem to have moved. Thanks to
<a href="https://twitter.com/CreativityKills">@CreativityKills</a> for the heads up.</p>
<hr />
<ol>
<li>This was done on MacOSX 10.8.3 (other versions may vary)</li>
<li>Tested with MAMP Pro 2.1.2 (other versions may vary)</li>
<li><a href="http://www.imagemagick.org/script/index.php">Image Magick</a> & <a href="http://pecl.php.net/package/imagick">Imagick</a> are two very different
things. The former is the core library and the latter is a PHP Wrapper that
uses the API of the former, so you do need to install the former before the
latter</li>
<li><a href="http://holgr.com/blog/2012/02/xcode-4-3-and-homebrew-where-did-my-
command-line-tools-go/">Xcode 4.3 and Homebrew: Where did my command line tools
go?</a></li>
<li><a href="http://stackoverflow.com/questions/7163497/resolved-mamp-php-cant-exec-convert-after-homebrew-imagemagick-install">Resolved: MAMP Php can’t exec (‘convert’) after Homebrew ImageMagick
install</a></li>
<li><a href="http://www.lullabot.com/blog/articles/installing-php-pear-and-pecl-extensions-mamp-mac-os-x-107-lion">Installing PHP PEAR and PECL extensions on MAMP for Mac OS X 10.7
(Lion)</a></li>
</ol>
<p>
<a title="Permalink to 'Image Magick, Imagick, Homebrew & MAMP-Pro'" href="http://kingori.co/minutae/2013/04/imagick-on-mamp-pro/" target="_blank">↩</a>
</p>
King'ori Maina
http://kingori.co/
Shifting colors (Chameleon)
2013-04-13T00:00:00+00:00
kingori.co:/minutae/2013/04/shifting-colors/
<div style="width: 100%; height: 30px; background-color: hsl( 10, 90%, 60% );"></div>
<div style="width: 100%; height: 30px; background-color: hsl( 30, 90%, 60% );"></div>
<div style="width: 100%; height: 30px; background-color: hsl( 152, 25%, 53% );"></div>
<div style="width: 100%; height: 30px; background-color: hsl( 210, 90%, 60% );"></div>
<div style="width: 100%; height: 30px; background-color: hsl( 230, 90%, 60% );"></div>
<div style="width: 100%; height: 30px; background-color: hsl( 270, 90%, 60% );"></div>
<div style="width: 100%; height: 30px; background-color: hsl( 290, 90%, 60% );"></div>
<div style="width: 100%; height: 30px; background-color: hsl( 310, 90%, 60% );"></div>
<div style="width: 100%; height: 30px; background-color: hsl( 330, 90%, 60% );"></div>
<div style="width: 100%; height: 30px; background-color: hsl( 350, 90%, 60% );"></div>
<h3 id="update">Update:</h3>
<p>Just realized this won’t make much sense a few years later if I change the theme
& so … the JS;</p>
<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cm">/* SHIFTING COLORS ~ Chameleon */</span>
<span class="c1">// Initialize object</span>
<span class="kd">var</span> <span class="nx">Chameleon</span> <span class="o">=</span> <span class="p">{};</span>
<span class="nx">Chameleon</span><span class="p">.</span><span class="nx">noOfColors</span> <span class="o">=</span> <span class="mi">10</span><span class="p">;</span> <span class="c1">// should be in CSS, with the transitions</span>
<span class="nx">Chameleon</span><span class="p">.</span><span class="nx">duration</span> <span class="o">=</span> <span class="mi">4</span><span class="p">;</span> <span class="c1">// should match the transition duration in css</span>
<span class="nx">Chameleon</span><span class="p">.</span><span class="nx">init</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="c1">// Check if we support CSS transitions on the browser</span>
<span class="k">if</span> <span class="p">(</span> <span class="nx">Modernizr</span><span class="p">.</span><span class="nx">csstransitions</span> <span class="p">)</span> <span class="p">{</span>
<span class="c1">// Grab the body, we will be using it a lot</span>
<span class="nx">Chameleon</span><span class="p">.</span><span class="nx">bodyElement</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="dl">"</span><span class="s2">body</span><span class="dl">"</span><span class="p">);</span>
<span class="c1">// ~~ faster than Math.floor() -> http://rocha.la/JavaScript-bitwise-operators-in-practice</span>
<span class="nx">Chameleon</span><span class="p">.</span><span class="nx">colorT</span> <span class="o">=</span> <span class="o">~~</span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span><span class="o">*</span><span class="nx">Chameleon</span><span class="p">.</span><span class="nx">noOfColors</span><span class="p">);</span>
<span class="nx">Chameleon</span><span class="p">.</span><span class="nx">changeColor</span><span class="p">();</span>
<span class="p">}</span>
<span class="c1">// Defaults to @orange and @skyblue on hover if we aren't doing this.</span>
<span class="p">}</span>
<span class="c1">// Switch colors</span>
<span class="nx">Chameleon</span><span class="p">.</span><span class="nx">changeColor</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">Chameleon</span><span class="p">.</span><span class="nx">bodyElement</span><span class="p">.</span><span class="nx">removeClass</span><span class="p">(</span> <span class="dl">'</span><span class="s1">color</span><span class="dl">'</span> <span class="o">+</span> <span class="nx">Chameleon</span><span class="p">.</span><span class="nx">colorT</span> <span class="o">%</span> <span class="nx">Chameleon</span><span class="p">.</span><span class="nx">noOfColors</span> <span class="p">);</span>
<span class="nx">Chameleon</span><span class="p">.</span><span class="nx">colorT</span><span class="o">++</span><span class="p">;</span>
<span class="nx">Chameleon</span><span class="p">.</span><span class="nx">bodyElement</span><span class="p">.</span><span class="nx">addClass</span><span class="p">(</span> <span class="dl">'</span><span class="s1">color</span><span class="dl">'</span> <span class="o">+</span> <span class="nx">Chameleon</span><span class="p">.</span><span class="nx">colorT</span> <span class="o">%</span> <span class="nx">Chameleon</span><span class="p">.</span><span class="nx">noOfColors</span> <span class="p">);</span>
<span class="nx">setTimeout</span><span class="p">(</span> <span class="nx">Chameleon</span><span class="p">.</span><span class="nx">changeColor</span><span class="p">,</span> <span class="nx">Chameleon</span><span class="p">.</span><span class="nx">duration</span> <span class="o">*</span> <span class="mi">1000</span> <span class="p">);</span>
<span class="p">};</span>
<span class="c1">// Get ready, set ... GO!</span>
<span class="nx">Chameleon</span><span class="p">.</span><span class="nx">init</span><span class="p">();</span>
</code></pre></div></div>
<p>The CSS (necessary bits only);</p>
<div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">a</span> <span class="p">{</span>
<span class="nl">-webkit-transition</span><span class="p">:</span> <span class="n">color</span> <span class="m">4.0s</span> <span class="n">linear</span><span class="p">;</span>
<span class="nl">-moz-transition</span><span class="p">:</span> <span class="n">color</span> <span class="m">4.0s</span> <span class="n">linear</span><span class="p">;</span>
<span class="nl">-o-transition</span><span class="p">:</span> <span class="n">color</span> <span class="m">4.0s</span> <span class="n">linear</span><span class="p">;</span>
<span class="nl">transition</span><span class="p">:</span> <span class="n">color</span> <span class="m">4.0s</span> <span class="n">linear</span><span class="p">;</span>
<span class="p">}</span>
<span class="nc">.color0</span> <span class="nt">a</span> <span class="p">{</span> <span class="nl">color</span><span class="p">:</span> <span class="n">hsl</span><span class="p">(</span> <span class="m">10</span><span class="p">,</span> <span class="m">90%</span><span class="p">,</span> <span class="m">60%</span> <span class="p">);</span> <span class="p">}</span> <span class="o">//</span> <span class="err">1</span>
<span class="nc">.color1</span> <span class="nt">a</span> <span class="p">{</span> <span class="nl">color</span><span class="p">:</span> <span class="n">hsl</span><span class="p">(</span> <span class="m">30</span><span class="p">,</span> <span class="m">90%</span><span class="p">,</span> <span class="m">60%</span> <span class="p">);</span> <span class="p">}</span> <span class="o">//</span> <span class="err">2</span>
<span class="nc">.color2</span> <span class="nt">a</span> <span class="p">{</span> <span class="nl">color</span><span class="p">:</span> <span class="n">hsl</span><span class="p">(</span> <span class="m">152</span><span class="p">,</span> <span class="m">25%</span><span class="p">,</span> <span class="m">53%</span> <span class="p">);</span> <span class="p">}</span> <span class="o">//</span> <span class="err">3</span>
<span class="nc">.color3</span> <span class="nt">a</span> <span class="p">{</span> <span class="nl">color</span><span class="p">:</span> <span class="n">hsl</span><span class="p">(</span> <span class="m">210</span><span class="p">,</span> <span class="m">90%</span><span class="p">,</span> <span class="m">60%</span> <span class="p">);</span> <span class="p">}</span> <span class="o">//</span> <span class="err">4</span>
<span class="nc">.color4</span> <span class="nt">a</span> <span class="p">{</span> <span class="nl">color</span><span class="p">:</span> <span class="n">hsl</span><span class="p">(</span> <span class="m">230</span><span class="p">,</span> <span class="m">90%</span><span class="p">,</span> <span class="m">60%</span> <span class="p">);</span> <span class="p">}</span> <span class="o">//</span> <span class="err">5</span>
<span class="nc">.color5</span> <span class="nt">a</span> <span class="p">{</span> <span class="nl">color</span><span class="p">:</span> <span class="n">hsl</span><span class="p">(</span> <span class="m">270</span><span class="p">,</span> <span class="m">90%</span><span class="p">,</span> <span class="m">60%</span> <span class="p">);</span> <span class="p">}</span> <span class="o">//</span> <span class="err">6</span>
<span class="nc">.color6</span> <span class="nt">a</span> <span class="p">{</span> <span class="nl">color</span><span class="p">:</span> <span class="n">hsl</span><span class="p">(</span> <span class="m">290</span><span class="p">,</span> <span class="m">90%</span><span class="p">,</span> <span class="m">60%</span> <span class="p">);</span> <span class="p">}</span> <span class="o">//</span> <span class="err">7</span>
<span class="nc">.color7</span> <span class="nt">a</span> <span class="p">{</span> <span class="nl">color</span><span class="p">:</span> <span class="n">hsl</span><span class="p">(</span> <span class="m">310</span><span class="p">,</span> <span class="m">90%</span><span class="p">,</span> <span class="m">60%</span> <span class="p">);</span> <span class="p">}</span> <span class="o">//</span> <span class="err">8</span>
<span class="nc">.color8</span> <span class="nt">a</span> <span class="p">{</span> <span class="nl">color</span><span class="p">:</span> <span class="n">hsl</span><span class="p">(</span> <span class="m">330</span><span class="p">,</span> <span class="m">90%</span><span class="p">,</span> <span class="m">60%</span> <span class="p">);</span> <span class="p">}</span> <span class="o">//</span> <span class="err">9</span>
<span class="nc">.color9</span> <span class="nt">a</span> <span class="p">{</span> <span class="nl">color</span><span class="p">:</span> <span class="n">hsl</span><span class="p">(</span> <span class="m">350</span><span class="p">,</span> <span class="m">90%</span><span class="p">,</span> <span class="m">60%</span> <span class="p">);</span> <span class="p">}</span> <span class="o">//</span> <span class="err">10</span>
</code></pre></div></div>
<hr />
<ol>
<li><a href="http://metafizzy.co/">Metafizzy: Business end</a> of <a href="http://desandro.com/">David
Desandro</a> - he deserves the credit for the idea of
changing font colors site-wide</li>
<li><a href="http://rocha.la/JavaScript-bitwise-operators-in-
practice">Tilde (~~) or the Floor?</a> - hint: tilde is faster</li>
<li><a href="http://modernizr.com/docs/#features-css">Modernizr: CSS3 feature detection</a></li>
</ol>
King'ori Maina
http://kingori.co/
Do we need to call HttpURLConnection.disconnect()?
2013-04-12T00:00:00+00:00
kingori.co:/minutae/2013/04/httpurlconnection-disconnect/
<p>Well, it kinda depends but usually …</p>
<p><strong>no.</strong></p>
<p>As per <a href="http://docs.oracle.com/javase/7/docs/api/java/net/HttpURLConnection.html">javadoc</a>;</p>
<blockquote>
<p>Each HttpURLConnection instance is used to make a single request but the
underlying network connection to the HTTP server may be transparently shared
by other instances. Calling the <code class="language-plaintext highlighter-rouge">close()</code> methods on the InputStream or
OutputStream of an HttpURLConnection after a request may free network
resources associated with this instance but <em>has no effect on any shared
persistent connection</em>. Calling the <code class="language-plaintext highlighter-rouge">disconnect()</code> method <em>may close the
underlying socket</em> if a persistent connection is otherwise idle at that time.</p>
</blockquote>
<p>In simpler terms …</p>
<blockquote>
<p>I don’t say it is a mistake. But, disconnect is extreme case (socket close
open operations are costly), unless you really want I wouldn’t go for it.
<code class="language-plaintext highlighter-rouge">stream.close()</code> releases most of the network resources and should be enough.
Again, if your requirement is ok to create socket everytime, there is nothing
wrong in calling disconnect.</p>
</blockquote>
<blockquote>
<p>~ <a href="http://stackoverflow.com/questions/11056088/do-i-need-to-call-httpurlconnection-disconnect-after-finish-using-it#comment14465352_11056207">Nambari</a></p>
</blockquote>
<p>Example;</p>
<div class="language-java highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">//Initialize variables</span>
<span class="nc">InputStream</span> <span class="n">responseInputStream</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span>
<span class="nc">HttpURLConnection</span> <span class="n">conn</span> <span class="o">=</span> <span class="kc">null</span><span class="o">;</span>
<span class="kt">int</span> <span class="n">responseCode</span> <span class="o">=</span> <span class="o">-</span><span class="mi">1</span><span class="o">;</span>
<span class="k">try</span> <span class="o">{</span>
<span class="c1">// Create a connection</span>
<span class="no">URL</span> <span class="n">url</span> <span class="o">=</span> <span class="k">new</span> <span class="no">URL</span><span class="o">(</span><span class="n">targetURL</span><span class="o">);</span>
<span class="n">conn</span> <span class="o">=</span> <span class="o">(</span><span class="nc">HttpURLConnection</span><span class="o">)</span> <span class="n">url</span><span class="o">.</span><span class="na">openConnection</span><span class="o">();</span>
<span class="c1">// SET FANCY DETAILS HERE</span>
<span class="c1">// Starts the connection</span>
<span class="n">conn</span><span class="o">.</span><span class="na">connect</span><span class="o">();</span>
<span class="c1">// Get the response code</span>
<span class="n">responseCode</span> <span class="o">=</span> <span class="n">conn</span><span class="o">.</span><span class="na">getResponseCode</span><span class="o">();</span>
<span class="c1">// Check the response code, if the HTTP response code is 4nn</span>
<span class="c1">// (Client Error) or 5nn (Server Error), then you may want to</span>
<span class="c1">// read the HttpURLConnection#getErrorStream() to see if the</span>
<span class="c1">// server has sent any useful error information.</span>
<span class="k">if</span> <span class="o">(</span><span class="n">responseCode</span> <span class="o"><</span> <span class="mi">400</span><span class="o">)</span> <span class="o">{</span>
<span class="c1">// Get the response InputStream if all is well</span>
<span class="n">responseInputStream</span> <span class="o">=</span> <span class="n">conn</span><span class="o">.</span><span class="na">getInputStream</span><span class="o">();</span>
<span class="o">}</span>
<span class="k">else</span> <span class="nf">if</span> <span class="o">(</span><span class="n">responseCode</span> <span class="o">>=</span> <span class="mi">400</span><span class="o">)</span> <span class="o">{</span>
<span class="c1">// Get the response ErrorStream if we got an error instead</span>
<span class="n">responseInputStream</span> <span class="o">=</span> <span class="n">conn</span><span class="o">.</span><span class="na">getErrorStream</span><span class="o">();</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="k">catch</span> <span class="o">(</span><span class="nc">IOException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
<span class="c1">// YOU CAN DO WHATEVER HERE</span>
<span class="n">e</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">();</span>
<span class="o">}</span>
<span class="k">finally</span> <span class="o">{</span>
<span class="c1">// Makes sure that the InputStream is closed after</span>
<span class="c1">// we are done with it</span>
<span class="k">if</span> <span class="o">(</span><span class="n">responseInputStream</span> <span class="o">!=</span> <span class="kc">null</span><span class="o">)</span> <span class="o">{</span>
<span class="k">try</span> <span class="o">{</span>
<span class="n">responseInputStream</span><span class="o">.</span><span class="na">close</span><span class="o">();</span>
<span class="o">}</span>
<span class="k">catch</span> <span class="o">(</span><span class="nc">IOException</span> <span class="n">e</span><span class="o">)</span> <span class="o">{</span>
<span class="c1">// YOU CAN DO WHATEVER HERE</span>
<span class="n">e</span><span class="o">.</span><span class="na">printStackTrace</span><span class="o">();</span>
<span class="o">}</span>
<span class="o">}</span>
<span class="o">}</span>
</code></pre></div></div>
<p>That should do.</p>
<hr />
<ol>
<li><a href="http://stackoverflow.com/questions/11056088/do-i-need-to-call-httpurlconnection-disconnect-after-finish-using-it">Do I need to call HttpURLConnection.disconnect after finish using it?</a></li>
<li><a href="http://docs.oracle.com/javase/7/docs/api/java/net/HttpURLConnection.html">Java Class HttpURLConnection</a></li>
<li><a href="http://developer.android.com/training/basics/network-ops/connecting.html#download">Android Training: Connecting & download from the network</a></li>
</ol>
King'ori Maina
http://kingori.co/
To globally ignore or not to?
2013-04-12T00:00:00+00:00
kingori.co:/minutae/2013/04/global-ignores/
<p>I found myself <a href="https://github.com/bshaffer/oauth2-server-php" title="bshaffer/oauth2-server-php">contributing to an open source project</a>
recently … <a href="https://github.com/itskingori/oauth2-server-php/commit/640498926f2ebe8499c14184b89d613acf60ae59" title="Update README with more info on grant types">here</a> & <a href="https://github.com/itskingori/oauth2-server-php/commit/31fc8c2a2f9dcf1d3a0a58736c7b6d7cd88bb74a" title="Place the realm & scope values in ...">here</a>. First thing that I thought
awkward was that the project’s <code class="language-plaintext highlighter-rouge">.gitignore</code> file paid no attention to OS-
generated or editor-generated files. So I happily contributed those exclusions
to the project’s <code class="language-plaintext highlighter-rouge">.gitignore</code> so we ended up with <a href="https://github.com/itskingori/oauth2-server-php/commit/f26798ce7007c19671e7fed5bfe42d5c63240639" title="Ignore editor, OS and test files">this</a> …</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code># Editor Files #
*.komodoproject
# OS generated files #
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
Icon?
ehthumbs.db
Thumbs.db
</code></pre></div></div>
<p>Which isn’t elegant. At all.</p>
<blockquote>
<p>I have a slight problem with this, though. The .DS_Store isn’t related to your
project, it is related to the system you’re coding on. <em>Your .gitignore file
will be a lot more elegant if it only lists files that are related to the
projects</em>.</p>
</blockquote>
<h3 id="solution">Solution</h3>
<p>Git has a global configuration that applies rules to all of your projects.</p>
<p>On linux for example:</p>
<div class="language-console highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="gp">$</span><span class="w"> </span>git config <span class="nt">--global</span> core.excludesfile ~/.global_ignore
</code></pre></div></div>
<p>On Windows (if using GitHub. for Windows) the <code class="language-plaintext highlighter-rouge">.gitconfig</code> file lives in the
user’s home directory. In my case, for example ( & on Windows Vista/8), the
location of the <code class="language-plaintext highlighter-rouge">.gitconfig</code> file is <code class="language-plaintext highlighter-rouge">C:\Users\YOU\.gitconfig</code>. To set up a
global gitconfig, I use a directory <code class="language-plaintext highlighter-rouge">C:\Users\YOU\config\</code> containing a file
called <code class="language-plaintext highlighter-rouge">global_ignore</code>, and in <code class="language-plaintext highlighter-rouge">.gitconfig</code> I would add;</p>
<div class="language-ini highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nn">[user]</span>
<span class="py">name</span> <span class="p">=</span> <span class="s">King'ori Maina</span>
<span class="py">email</span> <span class="p">=</span> <span class="s">j@kingori.co</span>
<span class="nn">[core]</span>
<span class="py">excludesfile</span> <span class="p">=</span> <span class="s">C:/Users/itskingori/configs/global_ignore</span>
</code></pre></div></div>
<p>And finally in the <code class="language-plaintext highlighter-rouge">global_ignore</code> file we have something like;</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>## Editor Files ##
*.sublime-project
*.sublime-workspace
## Backup ##
*.bak
## Logs and databases ##
*.log
*.sql
*.sqlite
## Packages ##
# it's better to unpack these files and commit the raw source
# git has its own built in compression methods
*.7z
*.dmg
*.gz
*.iso
*.jar
*.rar
*.tar
*.zip
# OS generated files #
$RECYCLE.BIN/
.DS_Store
.DS_Store?
._*
.Spotlight-V100
.Trashes
Desktop.ini
Icon?
ehthumbs.db
Thumbs.db
</code></pre></div></div>
<p>Of course this is <a href="https://github.com/itskingori/configs/blob/master/gitignore/global_ignore" title="itskingori/configs/gitignore/global_ignore">my pref</a>, feel free to use whatever
suits you.</p>
<hr />
<ol>
<li><a href="https://github.com/github/gitignore">A collection of useful .gitignore
Templates</a></li>
<li><a href="https://help.github.com/articles/ignoring-files">Ignoring files</a></li>
<li><a href="http://www.lemoda.net/git/github-gitignore-windows/index.html">Setting up a global .gitignore for Github for
Windows</a></li>
<li><a href="http://augustl.com/blog/2009/global_gitignores/">Global gitignores</a></li>
</ol>
King'ori Maina
http://kingori.co/
HTTPUrlConnection hangs when attempting to getResponseCode() on Android
2013-04-11T00:00:00+00:00
kingori.co:/minutae/2013/04/httpurlconnection-getresponsecode-error/
<p>There is a small issue that causes HTTPUrlConnection to hang when trying to
retrieve the response code via <code class="language-plaintext highlighter-rouge">getResponseCode()</code> after which an Exception is
thrown.</p>
<p>In my case I was authenticating against an oAuth Server and expecting a 401
error. As per <a href="http://www.ietf.org/rfc/rfc2617.txt">RFC2617</a>:</p>
<blockquote>
<p>The 401 (Unauthorized) response message is used by an origin server to
challenge the authorization of a user agent. This response <strong>MUST</strong> include a
WWW-Authenticate header field containing at least one challenge applicable to
the requested resource.</p>
</blockquote>
<p>Which simply means the response <strong>must</strong> include the <code class="language-plaintext highlighter-rouge">WWW-Authenticate</code> header
set without which the method throws <code class="language-plaintext highlighter-rouge">java.io.IOException: No authentication
challenges found</code>.</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>header('WWW-Authenticate: OAuth realm="users"');
header('HTTP/1.1 401 Unauthorized');
</code></pre></div></div>
<p>So far, this is normal and expected.</p>
<p>On Android, the lack of “” wrapping on realm caused the app to hang at the
<code class="language-plaintext highlighter-rouge">getResponseCode()</code> attempt, therefore crashing the app … so use this
<code class="language-plaintext highlighter-rouge">realm="..."</code> instead of <code class="language-plaintext highlighter-rouge">realm=...</code> if you own the server-side API.</p>
<p>Looking at the <a href="http://tools.ietf.org/html/rfc2617#section-3.2.1">spec</a> they
seem to imply that the values should be in quotes … but its not 100% clear.</p>
<hr />
<ol>
<li><a href="http://stackoverflow.com/questions/11810447/httpurlconnection-worked-fine-in-android-2-x-but-not-in-4-1-no-authentication-c">HttpURLConnection worked fine in Android 2.x but NOT in 4.1: No …</a></li>
<li><a href="http://tools.ietf.org/html/rfc2617#section-3.2.1">The WWW-Authenticate Response Header spec</a></li>
</ol>
King'ori Maina
http://kingori.co/