Merge branch 'deploy'

This commit is contained in:
Wesley Moore 2013-01-13 12:28:03 +11:00
commit e9268cee30
53 changed files with 749 additions and 139 deletions

2
.rvmrc
View file

@ -1 +1 @@
rvm --create 1.9.2@wezm.net rvm use default

View file

@ -1,14 +1,13 @@
source :rubygems source :rubygems
gem 'rake'
gem 'mime-types' gem 'mime-types'
gem 'nanoc' gem 'nanoc'
gem 'bitly' gem 'bitly'
gem 'haml' gem 'haml'
gem 'sass'
gem 'rdiscount' gem 'rdiscount'
gem 'rubypants' gem 'rubypants'
gem 'nokogiri' gem 'nokogiri'
gem 'builder' gem 'builder'
gem 'rb-fsevent' gem 'fssm'
gem 'guard'
gem 'guard-nanoc'
gem 'growl'

View file

@ -1,51 +1,43 @@
GEM GEM
remote: http://rubygems.org/ remote: http://rubygems.org/
specs: specs:
addressable (2.2.2) bitly (0.8.0)
bitly (0.6.1)
crack (>= 0.1.4) crack (>= 0.1.4)
httparty (>= 0.5.2) httparty (>= 0.7.6)
oauth2 (>= 0.1.1) oauth2 (>= 0.5.0, < 0.9)
builder (3.0.0) builder (3.1.4)
configuration (1.2.0) colored (1.2)
crack (0.1.8) crack (0.3.1)
cri (1.0.1) cri (2.3.0)
faraday (0.5.4) colored (>= 1.2)
addressable (~> 2.2.2) faraday (0.8.4)
multipart-post (~> 1.1.0) multipart-post (~> 1.1)
rack (< 2, >= 1.1.0) fssm (0.2.9)
growl (1.0.3) haml (3.1.7)
guard (0.3.0) httparty (0.9.0)
open_gem (~> 1.4.2) multi_json (~> 1.0)
thor (~> 0.14.6) multi_xml
guard-nanoc (0.1.0) httpauth (0.2.0)
guard (>= 0.2.1) jwt (0.1.5)
nanoc (>= 3.1.5) multi_json (>= 1.0)
haml (3.0.25) mime-types (1.19)
httparty (0.7.2) multi_json (1.3.6)
crack (= 0.1.8) multi_xml (0.5.1)
launchy (0.3.7) multipart-post (1.1.5)
configuration (>= 0.0.5) nanoc (3.4.3)
rake (>= 0.8.1) cri (~> 2.2)
mime-types (1.16) nokogiri (1.5.5)
multi_json (0.0.5) oauth2 (0.8.0)
multipart-post (1.1.0) faraday (~> 0.8)
nanoc (3.1.6) httpauth (~> 0.1)
nanoc3 (>= 3.1.6) jwt (~> 0.1.4)
nanoc3 (3.1.6) multi_json (~> 1.0)
cri (>= 1.0.0) rack (~> 1.2)
nokogiri (1.4.4) rack (1.4.1)
oauth2 (0.1.1) rake (0.9.2.2)
faraday (~> 0.5.0) rdiscount (1.6.8)
multi_json (~> 0.0.4)
open_gem (1.4.2)
launchy (~> 0.3.5)
rack (1.2.1)
rake (0.8.7)
rb-fsevent (0.3.9)
rdiscount (1.6.5)
rubypants (0.2.0) rubypants (0.2.0)
thor (0.14.6) sass (3.2.1)
PLATFORMS PLATFORMS
ruby ruby
@ -53,13 +45,12 @@ PLATFORMS
DEPENDENCIES DEPENDENCIES
bitly bitly
builder builder
growl fssm
guard
guard-nanoc
haml haml
mime-types mime-types
nanoc nanoc
nokogiri nokogiri
rb-fsevent rake
rdiscount rdiscount
rubypants rubypants
sass

View file

@ -1,6 +0,0 @@
guard 'nanoc' do
watch(%r'^config.yaml')
watch(%r'^Rules')
watch(%r'^layouts\/')
watch(%r'^content\/')
end

View file

@ -12,10 +12,13 @@ This Site
--------- ---------
This site is written in [Markdown][markdown] and [SASS][sass], generated using This site is written in [Markdown][markdown] and [SASS][sass], generated using
[nanoc][nanoc], enhanced with [jQuery][jquery] and hosted on a <a [nanoc][nanoc], enhanced with [jQuery][jquery] and hosted on VPS running
href="http://manage.crucialp.com/aff.php?aff=261" class="affiliate" [Debian GNU/Linux][debian] and [nginx][nginx]. It makes use of the following
title="Affiliate link">Crucial Paradigm</a> VPS running [Debian resources made available freely by their authors:
GNU/Linux][debian] and [nginx][nginx].
* [Reset CSS][cssreset] by Eric Meyer
* [Mono icons][monoicons] by tutorial9
* [Feed icon][feedicon] by FeedIcons.com and the Mozilla Foundation
The content is split into two sections: The content is split into two sections:
[Technical](/technical/articles/) and [Personal](/personal/articles/). There is [Technical](/technical/articles/) and [Personal](/personal/articles/). There is
@ -48,3 +51,6 @@ photos. My primary camera is a Canon 400D SLR, with the following lenses:
[debian]: http://www.debian.org/ [debian]: http://www.debian.org/
[jquery]: http://jquery.com/ [jquery]: http://jquery.com/
[sass]: http://sass-lang.com/ [sass]: http://sass-lang.com/
[cssreset]: http://meyerweb.com/eric/tools/css/reset/
[monoicons]: http://www.tutorial9.net/resources/108-mono-icons-huge-set-of-minimal-icons/
[feedicon]: http://feedicons.com/

View file

@ -35,6 +35,11 @@ while(x=eval(x));}hiveware_enkoder();
//]]> //]]>
</script> </script>
App.net
-------
[https://alpha.app.net/wezm](https://alpha.app.net/wezm)
Twitter Twitter
------- -------

View file

@ -1,3 +0,0 @@
Google's web browser, Chrome, has been available as a developer preview for some time now. Recently it shifted to beta status and the polish keeps piling on. There are a lot of nice touches in the browser that have contributed to me switching away from Safari such as multi-purpose address/search bar, tab closing behaviour, performance and a supported extension mechanism. Some of these things were discussed in Rob Friesel Jr.'s <a href="http://blog.founddrama.net/2010/01/a-week-with-chrome/">a Week With Chrome</a> and Basil Safwat's obviously tab focussed, <a href="http://www.theinvisibl.com/news/2009/12/08/a-piece-with-a-lot-of-screenshots-about-the-close-tab-behaviour-in-google-chrome/">A piece with a lot of screenshots about the close tab behaviour in Google Chrome</a>.
Today, whilst reading http://orderedlist.com/our-writing/resources/html-css/single-line-css/

View file

@ -1,14 +0,0 @@
---
slug: google-chrome-for-mac
permalink: http://www.wezm.net/?p=298
kind: draft
is_hidden: true
section: personal
created_at: 0000-00-00 00:00:00
title: Google Chrome for Mac
post_id: 298
tags: []
categories:
- Miscellaneous
status: draft

View file

@ -1,3 +0,0 @@
On the topic of OS's nearing release, Haiku is set for an alpha release in Sep[1]: http://www.osnews.com/story/22001/Haiku_Schedules_First_Alpha_Release_for_September_9
If you haven't heard of <a href="http://www.haiku-os.org/">Haiku </a>its a rewrite of BeOS from scratch. The aim of the first release is compatibility with the last official release of BeOS: R5. They're a good way down that path. As far as I know many apps that were built for R5 will run on Haiku. I've been following the project for a while now. Back in uni I downloaded an installed BeOS on my PC, this was obviously before the company went out of business/was bought by Palm (I think). The bit that interests me about it is that its GUI out of the box, much like OS X and Windows. Its attributes such as compactness, GUI, open source and POSIX core makes it a great candidate for high level embedded type projects I think. Things like the digital photo frame project I've had in mind for a while. Its one drawback in my mind is that the platform's primary language is C++, which I'm not a huge fan of. However if you're into C++ it might be worth checking out. If I recall correctly large parts of the kernel are written in C++ too.

View file

@ -1,14 +0,0 @@
---
slug: haiku
permalink: http://www.wezm.net/?p=240
kind: draft
is_hidden: true
section: personal
created_at: 0000-00-00 00:00:00
title: Haiku
post_id: 240
tags:
- os
categories:
- Miscellaneous
status: draft

View file

@ -1,3 +0,0 @@
Reminders aren't aggressive enough. A single buzz when on silent is not enough and makes them very easy to miss. They should behave like a phone call and persist until acknwledged.
Lack of camera functionality: no timed photos

View file

@ -1,14 +0,0 @@
---
slug: iphone-gripes-reminders
permalink: http://www.wezm.net/?p=237
kind: draft
is_hidden: true
section: technical
created_at: 2008-07-24 14:11:35
title: "iPhone gripes: Reminders"
post_id: 237
tags: []
categories:
- iPhone
status: draft

View file

@ -4,7 +4,7 @@ permalink: http://www.wezm.net/?p=100
kind: draft kind: draft
is_hidden: true is_hidden: true
section: uncategorized section: uncategorized
created_at: 0000-00-00 00:00:00 created_at: 2012-01-01 00:00:00
title: Perl Worst Practices title: Perl Worst Practices
post_id: 100 post_id: 100
tags: [] tags: []

View file

@ -54,13 +54,17 @@ what I'm most interested in.
<figure> <figure>
<a href="/images/2010/09/_IM_9078-9080.jpg" rel="prettyPhoto[weather]"><img src="/images/2010/09/_IM_9078-9080-small.jpg" width="266" height="400" alt="The Finished Installation" /></a> <a href="/images/2010/09/_IM_9078-9080.jpg" rel="prettyPhoto[weather]"><img src="/images/2010/09/_IM_9078-9080-small.jpg" width="266" height="400" alt="The Finished Installation" /></a>
<figcaption>The Finished Installation</figcaption> <figcaption>The Finished Installation</figcaption>
<figure> </figure>
To log and upload the weather readings to [http://weather.wezm.net/][weather] To log and upload the weather readings to [http://weather.wezm.net/][weather]
I'm using the [wview][wview] weather station software. wview is running on the I'm using the [wview][wview] weather station software. wview is running on the
Mac mini connected to our TV. The site layout is pretty basic so I hope to come Mac mini connected to our TV. The site layout is pretty basic so I hope to come
up with a cleaner design in the coming weeks. up with a cleaner design in the coming weeks.
**Update:** I built a custom logging and charting solution. See the post,
[Weather Station Software][software].
[software]: /technical/2010/09/weather-station-software/
[WS2355]: http://www.lacrossetechnology.com.au/shop2/product_info.php?cPath=21&products_id=93 [WS2355]: http://www.lacrossetechnology.com.au/shop2/product_info.php?cPath=21&products_id=93
[wview]: http://www.wviewweather.com/ [wview]: http://www.wviewweather.com/
[weather]: http://weather.wezm.net/ [weather]: http://weather.wezm.net/

View file

@ -0,0 +1,39 @@
This year I've decided to have a go at publishing a photo every day
of the year. I'm not the first to do this, its also known by the name
[Project 365][project365]. I'm publishing my photos to the [2012 set on
Flickr][set]. The first week whilst I was still on Christmas holidays was
pretty easy. Although I am missing a photo for Jan 2 as the photo I took
got deleted whilst trying to restore my iPhone that got drowned in a river.
Anyway after returning to work its been harder to find things to take
pictures of but I haven't missed a day yet.
[set]: http://www.flickr.com/photos/wezm/sets/72157628659470185/
[project365]: http://content.photojojo.com/tutorials/project-365-take-a-photo-a-day/
Some of my favourites from the first 3 weeks are:
<figure>
<a href="http://www.flickr.com/photos/wezm/6657534021/"><img src="http://farm8.staticflickr.com/7012/6657534021_4f817ed181.jpg" alt="Eastern Spinebill" /></a>
<figcaption>Jan 8 &mdash; Eastern Spinebill</figcaption>
</figure>
<figure>
<a href="http://www.flickr.com/photos/wezm/6689132165/"><img src="http://farm8.staticflickr.com/7165/6689132165_a804d761de.jpg" alt="CityLink" /></a>
<figcaption>Jan 13 &mdash; CityLink</figcaption>
</figure>
<figure>
<a href="http://www.flickr.com/photos/wezm/6697126903/"><img src="http://farm8.staticflickr.com/7022/6697126903_7edb0f16f4.jpg" alt="Sulphur Crested Cockatoo" /></a>
<figcaption>Jan 15 &mdash; Sulphur Crested Cockatoo</figcaption>
</figure>
<figure>
<a href="http://www.flickr.com/photos/wezm/6719362425/"><img src="http://farm8.staticflickr.com/7160/6719362425_4ca8528510.jpg" alt="Belvedere — Intense" /></a>
<figcaption>Jan 18 &mdash; Belvedere &ndash; Intense</figcaption>
</figure>
<figure>
<a href="http://www.flickr.com/photos/wezm/6727700109/"><img src="http://farm8.staticflickr.com/7147/6727700109_2b71858bf7.jpg" alt="Macedon Primary School Plantation" /></a>
<figcaption>Jan 19 &mdash; Macedon Primary School Plantation</figcaption>
</figure>

View file

@ -0,0 +1,11 @@
---
title: A Photo a Day in 2012
extra: In 2012 I'm aiming to take and publish a photo every day.
kind: article
section: personal
created_at: 2012-01-21 17:18:00
keywords:
- photography
- "2012"
- project365
short_url: http://bit.ly/wKwmtl

View file

@ -3,21 +3,31 @@ more noteworthy projects are listed below.
[github]: http://github.com/wezm [github]: http://github.com/wezm
<!--
Monothumb Monothumb
--------- ---------
`monothumb` is the tool that generates the thumbnails on the [home page](/). It [monothumb] is the tool that generates the thumbnails on the [home page](/). It
retrieves thumbnails of my [recent uploads to Flickr][flickr], converts them to retrieves thumbnails of my [recent uploads to Flickr][flickr], converts them to
greyscale and then generates a single output image with both the colour and greyscale and then generates a single output image with both the colour and
monochrome version of the thumbnail. There are two version of the tool. The monochrome versions of the thumbnail. There are two version of the tool. The
original one, written in Objective-C that uses CoreImage and a second version original one, written in Objective-C that uses CoreImage and a second version
written in Lua. The Lua one is the one currently in use. written in Lua. The Lua one uses my [lua-imlib](#lua-imlib) fork.
[flickr]: http://www.flickr.com/photos/wezm/ [flickr]: http://www.flickr.com/photos/wezm/
[monothumb]: https://github.com/wezm/monothumb
--> <a name="lua-imlib"></a>
lua-imlib2
----------
[lua-imlib2] is a fork of the published lua-imlib library with additional
functionality. This library allows image processing in Lua. Specifically I
added:
* Support for filters
* Image blending
[lua-imlib2]: https://github.com/wezm/lua-imlib2
node-genx node-genx
--------- ---------

View file

@ -282,7 +282,7 @@ a
height: 75px height: 75px
width: 75px width: 75px
border: 1px solid #ccc border: 1px solid #ccc
background: url(/images/photos.jpg) no-repeat 0 -75px background: url(/images/photos.jpg?20120121) no-repeat 0 -75px
&:first-child &:first-child
margin-left: 2em margin-left: 2em

View file

@ -1,4 +1,5 @@
Here's tip for something I worked out today. WordPress blogs generally have an RSS feed available for the comments on a post. This is handy for when you want to see other comments posted without having to remember to check back. The problem is many <acronym title="WordPress">WP</acronym> themes don't provide a link to the feed. The solution is to add `/feed` to the URL of the post, so for this post the comment feed is at: Here's tip for something I worked out today. WordPress blogs generally have an RSS feed available for the comments on a post. This is handy for when you want to see other comments posted without having to remember to check back. The problem is many <acronym title="WordPress">WP</acronym> themes don't provide a link to the feed. The solution is to add `/feed` to the URL of the post, so for this post the comment feed is at:
<a href="http://www.wezm.net/2008/07/02/comment-feeds-in-wordpress/feed">http://www.wezm.net/2008/07/02/comment-feeds-in-wordpress/feed</a>.
<u>http://www.wezm.net/2008/07/02/comment-feeds-in-wordpress/feed</u>
**Update 25 Mar 2010:** The example given will no longer work because I've moved this site off WordPress. **Update 25 Mar 2010:** The example given will no longer work because I've moved this site off WordPress.

View file

@ -16,7 +16,7 @@ functions for communicating with a LaCrosse WS-23xx weather station and a set
of tools. wview logged its observations to an SQLite database, which seemed of tools. wview logged its observations to an SQLite database, which seemed
appropriate for this application. There were tools in Open2300 to log current appropriate for this application. There were tools in Open2300 to log current
conditions to MySQL and PostgreSQL databases but not SQLite. So last weekend conditions to MySQL and PostgreSQL databases but not SQLite. So last weekend
I spend some of the afternoon learning enough of the SQLite C API to add I spent some of the afternoon learning enough of the SQLite C API to add
such a tool. The result is in my such a tool. The result is in my
[git mirror of the Open2300 SVN repo][open2300git]. Once the SQLite tool is [git mirror of the Open2300 SVN repo][open2300git]. Once the SQLite tool is
tidied up a bit more I'll submit it upstream. tidied up a bit more I'll submit it upstream.
@ -29,9 +29,10 @@ that wview was previously generated. To do this I wrote a small
[Lua tool][weather-tools] [Lua tool][weather-tools]
to query the database and output the results to a [JSON][json] file. The to query the database and output the results to a [JSON][json] file. The
JSON is used on the new [weather page][weather], which is largely populated JSON is used on the new [weather page][weather], which is largely populated
by Javascript and uses the [flot charting library][flot] to graph the by Javascript and uses the [flot][flot] and [dygraphs][dygraphs] libraries
temperature history. visualise the weather data.
[json]: http://www.json.org/ [json]: http://www.json.org/
[flot]: http://code.google.com/p/flot/ [flot]: http://code.google.com/p/flot/
[dygraphs]: http://dygraphs.com/
[weather-tools]: http://github.com/wezm/weather-tools [weather-tools]: http://github.com/wezm/weather-tools

View file

@ -0,0 +1,49 @@
Ever since this version of my site went live I've been meaning to
post about the generation of the monochrome thumbnails on the [front page](/).
When I was building the site I wanted to include recent items
from my Flickr photostream. However with the predominantly monochrome
design I didn't like the look of all the colour they added. So I looked into
having monochrome versions of the thumbnails shown.
The first thing I investigated was Javascript image processing libraries. The
only main contender in that space was [Pixastic]. It worked but its cross browser
support wasn't great at the time. So I moved on to writing a tool that I
could run locally.
[Pixastic]: http://pixastic.com/
I decided the tool should generate a single image with
both the colour and monochrome versions in it (a technique known as spriting).
Using a single image means only one HTTP request instead of forty. Being a
programmer with an interest in Cocoa programming I created a small command line
tool that used the Flickr API to get the details of the last twenty images in
my photostream, fetch them and then use Core Image to convert them to
monochrome, add both the colour and monochrome versions to the output image and
finally save the result.
This worked great, however when I stopped hosting my site on my Mac I thought I
would need to run the process periodically on my Linux server, which ruled out
Core Image. I took this as another opportunity to learn something new and
rewrote it in Lua using imlib2 bindings. I had to make some additions to the
imlib bindings, which are [published on GitHub][luaimlib].
[luaimlib]: https://github.com/wezm/lua-imlib2
I used the Lua version for some time but never bothered to set it up
on the server. I wasn't uploading photos all that frequently and it
was simple enough to run locally and rsync the result. I've recently
switched back to the Mac version as it was simpler to get up and running
on my new laptop.
The [code is on GitHub][code] if anyone wants to do something similar. The
Cocoa version is on the master branch, the Lua version is on the
[lua branch][lua-branch].
[code]: https://github.com/wezm/monothumb
[lua-branch]: https://github.com/wezm/monothumb/tree/lua
The current version of the processed thumbnails is shown below.
<div style="overflow-x: auto; overflow-y: hidden;">
<img src="/images/photos.jpg" />
</div>

View file

@ -0,0 +1,13 @@
---
title: Monochrome Thumbnails
extra: Generating monochrome thumbnails with a color rollover from my Flickr feed
kind: article
section: technical
created_at: 2011-08-27 18:54:00
keywords:
- image
- processing
- lua
- core
- monochrome
short_url: http://bit.ly/omIs0U

View file

@ -0,0 +1,29 @@
Xcode has a bad habit of adding trailing whitespace to code, which is a pet
peeve of mine. It introduces irrelevant changes into diffs and is particularly
glaring when commiting code with [GitX], which highlights it in red. In [TextMate]
and now [Vico] I have bound the strip trailing whitespace in current document
action to ⌃⌥⌘S (control-option-command-s). This makes it quick and easy.
Xcode makes adding these types of actions a bit harder but I came up with a
solution that uses the Behaviours functionality in Xcode 4. This is how I did
it:
[GitX]: http://gitx.frim.nl/
[Vico]: http://www.vicoapp.com/
[TextMate]: http://macromates.com/
Create a shell script that invokes `sed` on each git tracked file that is
modified. Since Xcode doesn't tell the script what the current file was and
I didn't want to run sed over every file every time, processing tracked files
with modifications was the best solution I could come up with. Note that the
script also only prcocesses `.m` and `.h` files. I have my copy of the script
in `~/Documents/strip.sh`, be sure to give it the execute permission.
<script src="https://gist.github.com/1175182.js?file=strip.sh"></script>
Next you need to add a behaviour to Xcode. Go to the Xcode preferences and
click the Behaviours section, then click the + button. Name the behaviour and
give it a keyboard shortcut. In the right pane check Run and choose the script
you saved above. That's it. Now you can kill off that nasty whitespace with
ease.
<a href="/images/2011/08/xcode-behaviours-preferences.png" rel="prettyPhoto[xcode]"><img src="/images/2011/08/xcode-behaviours-preferences-small.png" width="600" height="423" alt="Xcode 4 Behaviours Preferences" /></a>

View file

@ -0,0 +1,16 @@
---
title: Strip Trailing Whitespace in Xcode 4
extra: How to create a behaviour in Xcode 4 to strip trailing whitespace from all git tracked files with changes.
kind: article
section: technical
created_at: 2011-08-27 19:36:00
keywords:
- xcode
- strip
- trailing
- whitespace
- text
- editing
- programming
- apple
short_url: http://bit.ly/nGeJrK

View file

@ -0,0 +1,54 @@
In my ongoing efforts to distance myself from Google I started using
[DuckDuckGo][duck] as my default search engine. I tried the DDG Safari
extension but didn't really like it, especially
since it needed to add an entire new toolbar to the browser. Other
suggestions for adding DDG to Safari involved [hacking the binary][hack]
or other extensions, which I wasn't interested in.
[duck]: http://duckduckgo.com/
[hack]: http://hints.macworld.com/article.php?story=20030514035516436
**Update:** There an easier way to achive what I describe below: Just
add a hosts file entry for search.yahoo.com that points at DuckDuckGo's
IP address and set you search engine to Yahoo! in Safari. [See DuckDuckGo
for the full instructions][hosts].
[hosts]: http://help.duckduckgo.com/customer/portal/articles/255650
My solution to the problem was to hijack the Bing option in the default
search box for use with DDG. **Note:** This solution assumes you will
never want to go to the `www.bing.com` domain, not a problem for me. The
steps to implement it are:
Add an entry for `www.bing.com` to `/etc/hosts` that points the domain to
your local machine:
127.0.0.1 www.bing.com
Next configure an Apache virtual machine to respond to the `www.bing.com`
domain and redirect the request to Duck Duck Go (or your search engine
of choice). This works because DDG accepts the search query in the same
query string parameter, `q`, as Bing and ignores the other Bing related
params.
`/etc/apache2/extra/httpd-vhosts.conf`:
<VirtualHost *:80>
ServerName www.bing.com
RewriteEngine On
RewriteRule ^/search(.*)$ http://duckduckgo.com/$1 [redirect,last]
</VirtualHost>
For this to work you will need to have "Web Sharing" enabled in the Sharing
preferences pane and have the the following line included in
`/etc/apache2/httpd.conf`:
Include /private/etc/apache2/extra/httpd-vhosts.conf
Restart Apache (`sudo apachectl graceful`) and set your search engine
to Bing in Safari. Do a search and you should end up at the DDG
results. One of the neat features of DDG is its [!bang syntax][bang],
which allows you to search to 100s of sites directly. One of which is
`!g` for those times when you need to fall back on Google.
[bang]: http://duckduckgo.com/bang.html

View file

@ -0,0 +1,15 @@
---
title: Add a Custom Search Engine to Safari
extra: How to add a custom search engine to Safari without nasty hacks or input managers.
kind: article
section: technical
created_at: 2011-09-24 15:34:00
keywords:
- safari
- custom
- search
- engine
- duckduckgo
- google
- apache
short_url: http://bit.ly/rj1slK

View file

@ -0,0 +1,162 @@
## Summary
Here's the tl;dr version: I sold my Mac Pro to fund building a home
NAS. The result is a HP MicroServer with 4Gb RAM and 3 &times; 2Tb hard
drives running FreeBSD from the system drive and a ZFS pool across the
three 2Tb drives. Total cost: AU$731.67.
## Rationale
Recently the Time Machine drive in my Mac Pro started to randomly
disappear and Mac OS X would say that I had removed it improperly,
which was not true given it was an internal drive still inside the
machine.
I've seen this behaviour before and in that case it resulted in the drive
being replaced due to its inability to complete a short S.M.A.R.T.
scan. This drive (also a Samsung) was suffering a similar problem except
that initiating the S.M.A.R.T. scan would actually cause it to disappear
from the SATA bus. A check on the Samsung site showed that the drive was
out of warranty so I was up for a replacement.
The Mac Pro wasn't getting used for much since I got a i7 powered Mac
Book Pro. Its main duties involved storing my iTunes library, Aperture
library and running my weather logger. It wasn't exactly a very energy
efficient machine to run all the time. It would in fact keep the study
warm overnight when the door was closed during winter.
There was also a problem with replacing the failing drive: I couldn't afford
to do so. So I decided to move the weather logging to my [ALIX board][alix]
and sell the Mac Pro to fund building a home NAS. I was able to sell the
Mac Pro very quickly on eBay for $1500 but gave myself a budget of $1000 for
the NAS. I wanted the NAS to have reliable, redundant storage, which for me
meant [ZFS]. This implied the new machine would need to run one of [Solaris],
[illumos], [FreeBSD], [FreeNAS] or [SmartOS]. The requirement to run one of
these OS's ruled out an off the shelf NAS appliance.
[ZFS]: http://www.opensolaris.org/os/community/zfs/
[alix]: /technical/2011/12/openwrt-on-alix/
[Solaris]: http://oracle.com/solaris
[illumos]: https://www.illumos.org/
[FreeBSD]: http://www.FreeBSD.org/
[SmartOS]: http://smartos.org/
[FreeNAS]: https://www.illumos.org/
I did a lot of research into different ways to build the machine and
tried out all the OS options in virtual machines. I considered using
basic PC hardware, MiniITX, HP MicroServer, etc. Each had its own
pros and cons. The basic PC approach was possibly the cheapest but it
was the largest. MiniITX was more expensive and choice of multi hard
drive bay cases were limited. I ended up settling on the [HP Proliant
MicroServer][microserver] running FreeBSD.
[microserver]: http://h10010.www1.hp.com/wwpc/hk/en/sm/WF06b/15351-15351-4237916-4237917-4237917-4248009-5163345.html
<script type="text/javascript" charset="utf-8">
$(function () {
var alt = $(document.createElement('img')).attr('src', '/images/2012/01/_MG_0581.jpg');
$('#inside-outside-view').toggle(function() {
$(this).attr('src', alt.attr('src'))
}, function() {
$(this).attr('src', '/images/2012/01/_MG_0582.jpg')
});
});
</script>
<figure>
<img id="inside-outside-view" src="/images/2012/01/_MG_0582.jpg" width="600" height="600" alt="Inside/outside view of HP MicroServer" />
<figcaption>The end result. Click/tap to toggle inside view.</figcaption>
</figure>
<figure>
<img src="/images/2012/01/_MG_0583.jpg" width="600" height="600" alt="Fron of MicroServer with CD for size comparison" />
<figcaption>CD for size comparison.</figcaption>
</figure>
<figure>
<img src="/images/2012/01/_MG_0584.jpg" width="600" height="600" alt="Oblique view of HP MicroServer" />
<figcaption>Oblique view (excuse the finger prints).</figcaption>
</figure>
## The Build
The MicroServer is a neat little unit. It uses a low power dual core AMD
Turion II CPU and comes with 2Gb ECC RAM and a 250Gb HD. I has 4 non-hot
swappable hard drive bays all packaged up in a squat little box. I ordered
mine with an extra 2Gb or RAM as ZFS likes to have plenty of RAM available
to run well.
During my research hard drive prices sky rocketed due to floods
in Thailand, however I was able to get some at pre-flood prices from
[ht.com.au][ht]. They have since put the price up ~$40 and placed order
limits on them.
For the drives I chose 2Tb Seagate Barracuda Green's. They feature SATA 3
and a 64Mb cache and run at an atypical 5900RPM. These drives seemed to be
a good balance across energy efficiency, noise, performance and price.
[ht]: http://ht.com.au/
The final parts list ended up being rather diminutive:
* 1 &times; [HP MicroServer][microserver] (658553-371) + 2Gb extra RAM $336.82
* 3 &times; [2Tb Seagate Barracuda Green Hard Drives][hard-drives] $394.85
[hard-drives]: http://www.ht.com.au/cart/1/part/V0531-Seagate-Barracuda-Green-ST2000DL003-hard-drive-2-TB-SATA-600/detail.hts
The total cost ended up being $731.67, healthily under budget.
<figure>
<img src="/images/2012/01/IMG_0097.jpg" width="600" height="600" alt="Installing RAM into HP MicroServer" />
<figcaption>Installing the extra RAM.</figcaption>
</figure>
<figure>
<img src="/images/2012/01/IMG_0098.jpg" width="600" height="600" alt="Installing hard drives into HP MicroServer" />
<figcaption>Installing the hard drives.</figcaption>
</figure>
## Software
Installing FreeBSD and setting up the ZFS pool was very
straightforward. I'm running the drives in a RAIDZ configuration,
giving 3.6Tb of usable storage. I currently have two ZFS file systems
on that. One in a normal configuration and the other for photos with
`copies=2` set.
The system all ran well for a few days however on the forth day one of
the brand new drives failed and started making a terrible clicking, beeping
noise. Fortunately HT replaced it very promptly and the replacement has
been running fine since. During the time the failed drive was out for
replacement the ZFS pool continued to run fine in its degraded state, with
no data loss. Once the new drive was installed it was a simple matter of
issuing `zfs replace ada1` and it began the process of resilvering the data
onto the new drive and it has been running incident free since.
$ zpool status
pool: storage
state: ONLINE
scan: resilvered 1.07T in 9h32m with 0 errors on Tue Nov 29 07:13:29 2011
config:
NAME STATE READ WRITE CKSUM
storage ONLINE 0 0 0
raidz1-0 ONLINE 0 0 0
ada1 ONLINE 0 0 0
ada2 ONLINE 0 0 0
ada3 ONLINE 0 0 0
errors: No known data errors
After setting up the OS and file systems the only other thing I
needed to so was make the storage available to other machines on the
network. Since my house is all Macs I built [netatalk] via the FreeBSD
ports collection to make the storage available via <abbr title="Apple
Filing Protocol">AFP</abbr>.
[netatalk]: http://netatalk.sourceforge.net/
With that done it's the sever shows up in the Finder via Bonjour and
copying/accessing data is dead simple.

View file

@ -0,0 +1,14 @@
---
title: Home NAS Powered by FreeBSD and ZFS
extra: Building a home NAS with a HP MicroServer running FreeBSD and ZFS.
kind: article
section: technical
created_at: 2012-01-21 17:08:00
keywords:
- zfs
- freebsd
- hp
- proliant
- microserver
- nas
short_url: http://bit.ly/xz4hnt

View file

@ -0,0 +1,46 @@
When it comes time to present errors or other messages in iOS with
[UIAlertView] it is immediately obvious that a more convenient interface
would involve the use of blocks. A [search on GitHub][github-search]
shows just about every iOS developer has had the same thought and had a crack at it.
[UIAlertView]: http://developer.apple.com/library/ios/#documentation/uikit/reference/UIAlertView_Class/UIAlertView/UIAlertView.html
[github-search]: https://github.com/search?type=Repositories&language=&q=uialertview&repo=&langOverride=&x=14&y=17&start_value=1
After reviewing the better options (I.e. those that actually had a
README with more than a few lines of content) on GitHub it appeared
that one of the challenges was how to handle memory. This stems from
the wrapper becoming the delegate for the UIAlertView but not having a
strong reference from the caller. I saw various solutions to this, most
involving adding a extra retain call to keep everything around until the
delegate methods were called.
Since my project is using ARC I looked for a solution that
didn't involve marking the wrapper file as non-ARC and
invoking `retain`. The solution I came up with was to use
[`objc_setAssociatedObject`][set-object]. This Objective-C runtime
function allows one object to be associated with another using various
memory management strategies. I used this to associate the UIAlertView
blocks based wrapper with the UIAlertView.
[set-object]: http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocAssociativeReferences.html
In the `init` method the wrapper instance is associated with its UIAlertView:
objc_setAssociatedObject(alertView, _cmd, self, OBJC_ASSOCIATION_RETAIN);
Note that I'm using the implicit second argument to the method, its
selector, `_cmd` as the key for the associated object. This was
suggested in a [tweet by Bill Bumgarner][bbum].
[bbum]: http://twitter.com/bbum/status/3609098005
Then in `alertView:didDismissWithButtonIndex:`, the association
is removed, `dealloc` of the wrapper called as a result and the
`UIAlertView` also released.
SEL key = @selector(initWithTitle:message:);
objc_setAssociatedObject(self.alertView, key, nil, OBJC_ASSOCIATION_RETAIN);
The full [MIT licensed code][gist] is available as a [gist on GitHub][gist].
[gist]: https://gist.github.com/1392611

View file

@ -0,0 +1,14 @@
---
title: Fun With objc_setAssociatedObject and UIAlertView
extra: Using objc_setAssociatedObject in a blocks based UIAlertView wrapper.
kind: article
section: technical
created_at: 2011-12-11 17:26:00
keywords:
- ios
- uialertview
- blocks
- objc_setAssociatedObject
- arc
- objective-c
short_url: http://bit.ly/u9Ys9v

View file

@ -0,0 +1,61 @@
At work we're currently having an iOS app that I'm working on styled
by a designer. The second screen we were supplied was a pretty splash
screen with a big logo on it. We responded saying that we didn't want
to use the launch image like that. Our designer responded saying that
was fine but the majority of the clients nowadays require heavy emphases
on corporate branding therefore it was a standard practice to cater to
those requirements. It's a shame that this is what people are are asking
for since its is not the intended use of the launch image.
Justin Williams recently had the following clear-cut words to say on the
topic of splash screens in his [On Magazines and the iPad][carpeaqua]
article (emphasis from the article):
> Remember, kids. The first rule of mobile development is that *no one
> gives a fuck about your brand*. A splash screen with a giant logo
> is something that makes editors and marketing directors feel good,
> but to a user it just feels like a meaningless delay. You know that
> feeling of frustration you get each time theres a 15-second preroll
> before a video on the web? Thats what a splash screen with logos and
> advertisements is.
[carpeaqua]: http://carpeaqua.com/2011/12/04/on-magazines-and-the-ipad/
The Apple [iOS Human Interface Guidelines][MobileHIG] include the
following suggestions:
> Avoid taking space away from the content people care about. For
> example, displaying a second, persistent bar at the top of the screen
> that does nothing but display branding assets means that theres less
> room for content. Consider other, less intrusive ways to display
> pervasive branding, such as subtly customizing the background of a
> screen.
> Display a launch image that closely resembles the first screen of the
> application. This practice decreases the perceived launch time of your
> application.
> Avoid displaying an About window or a splash screen. In general, try
> to avoid providing any type of startup experience that prevents people
> from using your application immediately.
> Supply a launch image to improve user experience.
>
> Avoid using your launch image as an opportunity to provide:
>
> * An "application entry experience," such as a splash screen
> * An About window
> * Branding elements, unless they are a static part of your
> applications first screen
>
> Because users are likely to switch among applications frequently, you
> should make every effort to cut launch time to a minimum, and you
> should design a launch image that downplays the experience rather than
> drawing attention to it.
[MobileHIG]: http://developer.apple.com/library/ios/documentation/UserExperience/Conceptual/MobileHIG/MobileHIG.pdf
The launch image is designed to make the perceived launch time of you app
feel faster by showing something resembling the interface that will be loaded
as quickly as possible. Displaying a logo does nothing but draw attention
to how quickly your app loads and adds nothing to the user's experience.

View file

@ -0,0 +1,15 @@
---
title: The iOS Launch Image is Not a Splash Screen
extra: Reasons why the launch image in iOS apps is not intended to be a splash screen with your pretty logo on it.
kind: article
section: technical
created_at: 2011-12-08 07:29:00
keywords:
- ios
- iphone
- ipad
- splash
- screen
- launch
- image
short_url: http://bit.ly/uRHJqI

View file

@ -0,0 +1,85 @@
After ongoing issues with maintaining a reliable Internet connection at
home I decided to add a router box to the network in charge of assigning
IP addresses and sharing our Internet connection with the rest of the
network. I wanted something with at least two Ethernet ports so that
all Internet traffic would flow through the device and allow bandwidth
hogs to be identified at times when the connection appeared flooded.
After a bunch of research into appropriate hardware and software I
decided on a [PC Engines ALIX][alix] single board computer (alix2d13). The
ALIX is a small board about the size of a CD case with the following
features:
* 500Mhz AMD Geode (x86 compatible) CPU
* 256Mb RAM
* 2 &times; USB ports
* 3 &times; 10/100 Ethernet ports
* Mini-PCI socket (for WiFi if desired)
* RS-232 serial port
* CompactFlash socket
Along with the board I ordered one of [PC Engines cases][case]
(case1s2u) to go with it.
[alix]: http://www.pcengines.ch/alix2d13.htm
[case]: http://www.pcengines.ch/case1d2u.htm
For the software I settled on [OpenWRT][openwrt]. I chose it for a number of
reasons:
* Good support for ALIX boards.
* Designed to run from Flash and read only file systems.
* Great binary package manager that allows additional software to be
installed.
* Lightweight [Lua] based Web UI available ([LuCI][luci]).
[openwrt]: https://openwrt.org/
[luci]: http://luci.subsignal.org/
[Lua]: http://www.lua.org/
After learning to use the excellent OpenWRT build system I was able to
build a custom CompactFlash image for the board to run. I also created a
package for my [weather logging software][weather-software] so that the
ALIX can do all my [weather station][weather] logging.
[weather]: /personal/2010/09/weather-station/
[weather-software]: /technical/2010/09/weather-station-software/
This setup has been extremely reliable. I've pushed all services on to
it that my ADSL modem and AirPort base station used to be responsible
for. Including maintaining the PPPoE connection to my ISP. I'd certainly
recommend a set up like this to anyone who is looking for a small
dedicated home router.
If you don't like the prospect of building your own custom OS image I'd
also highly recommend <tt>[m0n0wall]</tt>, which is a [FreeBSD] derived
router system. I ran this on the ALIX initially and it was very easy
to get up an running (write image to CF card, boot from card - default
settings worked fine but can be changed via a web UI) and very reliable.
[m0n0wall]: http://m0n0.ch/wall/
[FreeBSD]: http://www.freebsd.org/
<figure>
<img src="/images/2012/01/_MG_0562.jpg" width="600" height="258" alt="Front view" />
<figcaption>Front with three LEDs. The behaviour of the LEDs can
be customised in OpenWRT. I have the left one indication power and
the middle one indicating activity on the WAN port. The other one is
currently unused.</figcaption>
</figure>
<figure>
<img src="/images/2012/01/_MG_0569.jpg" width="600" height="600" alt="Top view with CD for size comparison" />
<figcaption>Top of case, showing size in comparison to a CD case.</figcaption>
</figure>
<figure>
<img src="/images/2012/01/_MG_0567.jpg" width="600" height="600" alt="alix2d13 board" />
<figcaption>The ALIX board itself with the following connected: WAN
and LAN Ethernet, 8Gb [MosKeyto USB flash drive][moskeyto],
weather station USB cable and 32Mb CF card that the system runs
off.</figcaption>
</figure>
[moskeyto]: http://www.lacie.com/au/products/product.htm?id=10425

View file

@ -0,0 +1,16 @@
---
title: Little Linux Router Box
extra: Solving my Internet connection issues with a PC Engines ALIX single board computer and OpenWRT.
kind: article
section: technical
created_at: 2012-01-21 15:33:00
keywords:
- alix
- embedded
- linux
- openwrt
- server
- appliance
- freebsd
- m0n0wall
short_url: http://bit.ly/y9ZEKZ

View file

@ -26,7 +26,7 @@
<div class="rainfall week chart"></div> <div class="rainfall week chart"></div>
</section> </section>
<small>Forecast icons by <a href="http://lavana.deviantart.com/art/Flat-Weather-Icons-32021664">LavAna</a></small> <small>Forecast icons by <a href="http://lavana.deviantart.com/art/Flat-Weather-Icons-32021664">LavAna</a>. Data from my <a href="/personal/2010/09/weather-station/">weather station</a>.</small>
<script id="current-template" type="text/x-handlebars-template"> <script id="current-template" type="text/x-handlebars-template">
<div id="current"> <div id="current">
<figure class="forecast"> <figure class="forecast">

View file

@ -1,6 +1,6 @@
<meta charset="utf-8" /> <meta charset="utf-8" />
<meta name="viewport" content="width=device-width" /> <meta name="viewport" content="width=device-width" />
<title><%=h [@item[:title], 'WezM.net'].compact.join(' - ') %></title> <title><%=h [@item[:title], 'WezM.net by Wesley Moore'].compact.join(' - ') %></title>
<% if @item[:extra] %><meta name="description" content="<%=h @item[:extra] %>"><% end %> <% if @item[:extra] %><meta name="description" content="<%=h @item[:extra] %>"><% end %>
<% if @item[:keywords] %><meta name="keywords" content="<%=h @item[:keywords].join(',') %>"><% end %> <% if @item[:keywords] %><meta name="keywords" content="<%=h @item[:keywords].join(',') %>"><% end %>
<!--[if lt IE 9]> <!--[if lt IE 9]>

View file

@ -1,4 +1,5 @@
<% post_date = WezM::Helpers.parse_post_date(@item) %> <% post_date = WezM::Helpers.parse_post_date(@item) %>
<% short = @item[:short_url] %>
<div class="published"> <div class="published">
Published on Published on
<abbr class="calender date" title="<%= post_date.iso8601 %>"> <abbr class="calender date" title="<%= post_date.iso8601 %>">
@ -11,7 +12,8 @@
<%= yield %> <%= yield %>
<div id="respond"> <div id="respond">
<h2>Something to Add?</h2> <h2>Something to Add?</h2>
<p>Contact me by email or Twitter if you have a comment, correction or just want to get in touch.</p> <p>Contact me by email, App.net or Twitter if you have a comment, correction
or just want to get in touch.</p>
<ul class="inline"> <ul class="inline">
<li> <li>
<script type="text/javascript"> <script type="text/javascript">
@ -51,7 +53,9 @@
</script> </script>
</li> </li>
<li> <li>
<% short = @item[:short_url] %> <a href="https://alpha.app.net/intent/post?text=<%= URI.encode("#{@item[:title]} - #{short} @wezm") %>" target="_blank">Post on App.net</a>
</li>
<li>
<a href="http://twitter.com/home?status=<%= URI.encode("#{@item[:title]} - #{short} @wezm") %>" target="_blank">Tweet</a> <a href="http://twitter.com/home?status=<%= URI.encode("#{@item[:title]} - #{short} @wezm") %>" target="_blank">Tweet</a>
</li> </li>
<li class="short">Short URL: <a href="<%= short %>"><%= short %></a></li> <li class="short">Short URL: <a href="<%= short %>"><%= short %></a></li>

View file

@ -4,7 +4,7 @@ module WezM
module Helpers module Helpers
def self.parse_post_date(article) def self.parse_post_date(article)
Time.parse(article[:created_at]) article[:created_at]
end end
end end

Binary file not shown.

After

Width:  |  Height:  |  Size: 145 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 177 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 138 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 80 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

After

Width:  |  Height:  |  Size: 131 KiB

View file

@ -8,7 +8,7 @@ jQuery(function () {
var photo = $(obj); var photo = $(obj);
var image = { var image = {
href: photo.attr('url_z'), href: photo.attr('url_z'),
src: '/images/photos.jpg', src: '/images/photos.jpg?20120121',
alt: photo.attr('title') alt: photo.attr('title')
}; };
var li = $(image_template(image)); var li = $(image_template(image));
@ -20,5 +20,5 @@ jQuery(function () {
}; };
// Populate Flickr // Populate Flickr
jQuery.get("/photos.xml", {}, populate_flickr); jQuery.get("/photos.xml?20111208", {}, populate_flickr);
}); });

View file

@ -39,8 +39,9 @@
].join('') ].join('')
} }
function datetimeString(date) {
var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']; var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'];
function datetimeString(date) {
if (!date) return '';
return [ return [
date.getDate(), date.getDate(),
months[date.getMonth()], months[date.getMonth()],
@ -49,6 +50,7 @@
} }
function timeString(date) { function timeString(date) {
if (!date) return '';
return [ return [
padNumber(date.getHours()), padNumber(date.getHours()),
padNumber(date.getMinutes()) padNumber(date.getMinutes())
@ -100,8 +102,13 @@
forecast: data.current.forecast forecast: data.current.forecast
}; };
if (current.temperature === undefined) {
$('.loading').replaceWith($('<p>Unavailable</p>'));
}
else {
var current_div = currentTemplate(current); var current_div = currentTemplate(current);
$('.loading').replaceWith(current_div) $('.loading').replaceWith(current_div)
}
// Populate the extremes // Populate the extremes
var extremes = []; var extremes = [];

File diff suppressed because one or more lines are too long