Everything is Gray

A place to put stuff.

Determining Guest Login Status

| Comments

The other day I was presented with the challenge of determining whether Guest login was enabled on 150+ Macs. Fortunately, my client was using the Casper Suite, so I was able to whip up an Extension Attribute rather quickly. Here’s what I came up with to get the status:

cURL Speed Test

| Comments

Have you ever needed to run a quick download speed test, but were too lazy to open up a new browser window and use one of the Web-based tools? Or perhaps you just prefer to use the command-line like me. Never fear, because appending this line to your ~/.bash_profile will allow you test your download speed from within your login shell by simply typing speedtest.

On Migrating from WordPress to Octopress

| Comments

Having recently made the decision to migrate my blog from WordPress to Octopress I decided I would share my findings in hopes that someone else will benefit from them, and so I can refer back to this post should I need to do something similar in the future.

The primary reason I decided to move to a statically generated site is because I found myself spending more time worrying about whether my site was running and was secure than I did writing. My site was hacked last year because I was running an outdated version of WordPress, and since moving to a new host, (Amazon EC2), I have frequently had to restart MySQL and Apache just to keep the site up. This could be partially due to the fact that I was running the site on a micro instance, but now that my blog is static I don’t have to worry about that any longer. Another reason why I chose Octopress for my blogging platform is that I like to tinker, and being able to use tools that I’m already familiar with and use every day was a huge plus, (Vim, Git, and Markdown, specifically).

So, without further ado1, here are the steps I took to mirgrate from WordPress running on an Amazon EC2 instance to Octopress running on Heroku.

Prepping Your Environment

I performed the migration using a fairly stock OS X 10.8 machine. If you’re using a Mac, you should probably be using Homebrew to manage packages.

1
2
3
brew update
brew doctor
brew install rbenv

The next thing you should do is add the following to your ~/.bash_profile.

1
2
3
4
5
# To use Homebrew's directories rather than ~/.rbenv add to your profile:
export RBENV_ROOT=/usr/local/var/rbenv

# To enable shims and autocompletion add to your profile:
if which rbenv > /dev/null; then eval "$(rbenv init -)"; fi

Then source ~/.bash_profile.

Now install Ruby 1.9.3 with rbenv.

1
2
3
4
5
6
7
8
brew install ruby-build
brew update
brew tap homebrew/dupes
brew install automake apple-gcc42
rbenv install 1.9.3-p194
rbenv rehash
rbenv global 1.9.3-p194
ruby --version # Should now return 1.9.3

Setting Up Your Local ~/Sites Directory and Installing Octopress

On OS X 10.8 the ~/Sites folder no longer exists in the home directory by default. No problem though, because we can create it, and we’ll even get the correct permissions and pretty icon when we do so.

I also recommend checking out Anvil for Mac. This will allow you to easily manage your local site and give you a .dev domain for testing. Best of all, it’s free.

1
2
3
4
5
6
7
8
mkdir ~/Sites
cd ~/Sites
git clone git://github.com/imathis/octopress.git <sitename>
cd <sitename>
gem install bundler
rbenv rehash
bundle install
rake install

If you took my advice and installed Anvil for Mac, do the following to create a symlink to your site in the ~/.pow directory.

1
2
3
4
cd ~/.pow
ln -s ~/Sites/<sitename> <sitename>
cd -
rake generate && rake watch

Use rack-rewrite for Redirects

This is useful for redirecting old URLs to your new Octopress site, especially if you used date-based permalinks for archives on WordPress, (something like example.com/2012/02/22), and you want those to redirect to /archives on your new site.

Add this to the end of your Gemfile.

Gemfile
1
gem 'rack-rewrite'

Add this to config.ru.

config.ru
1
require 'rack-rewrite'

Under $root = ::File.dirname(__FILE__) in config.ru add your redirects, (these are just some examples). Of particular interest are the regular expressions that redirect dates in yyyy-mm-dd format to /archives.

config.ru
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
use Rack::Rewrite do
    r301 /.*/,  Proc.new {|path, rack_env| "http://#{rack_env['SERVER_NAME'].     gsub(/www\./i, '') }#{path}" },
      :if => Proc.new {|rack_env| rack_env['SERVER_NAME'] =~ /www\./i}
    r301 %r{^/tag/art/?$}, '/category/art/'
    r301 %r{^/tag/design/?$}, '/category/design/'
    r301 %r{^/tag/os-x/?$}, '/category/os-x/'
    r301 %r{^/tag/science/?$}, '/category/science/'
    r301 %r{^/tag/technology/?$}, '/category/technology/'
    r301 %r{^/tag/uncategorized/?$}, '/category/uncategorized/'
    r301 %r{^/tag/web-design/?$}, '/category/web-design/'
    r301 %r{^/tag/web-development/?$}, '/category/web-development/'
    r301 %r{^/tag/wordpress/?$}, '/category/wordpress/'
    r301 %r{^/[0-9]{4}/(1[0-2]|0[1-9])/(3[01]|[12][0-9]|0[1-9])/?$}, '/archives/'
    r301 %r{^/[0-9]{4}/(1[0-2]|0[1-9])/?$}, '/archives/'
    r301 %r{^/[0-9]{4}/?$}, '/archives/'
end

Install rack-rewrite.

1
2
3
4
bundle install
bundle
bundle show rack-rewrite
rake generate && rake watch

Now restart your local server, (turn the slider on and off with Anvil).

Create _heroku Directory for Deployment

I opted to keep the generated Heroku site in a separate repository so I can keep public in my .gitignore. This will help keep your commit history clean, as not (nearly) every file that Git is tracking will change every time you re-generate your site.

1
2
3
4
5
6
cd ~/Sites/<sitename>
mkdir _heroku
cp config.ru _heroku/
cp Gemfile _heroku/
cd _heroku
mkdir public

Create an HTML file in _heroku/public so you can deploy to Heroku.

1
2
touch ~/Sites/<sitename>/_heroku/public/index.html
echo '<html><p>Hello world.</p></html>' > ~/Sites/<sitename>/_heroku/public/index.html

Make the Gemfile in _heroku only include these lines.

1
2
3
4
source "http://rubygems.org"

gem 'sinatra', '~> 1.4.2'
gem 'rack-rewrite'

Add this task to your Rakefile. This will result in your site being deployed to Heroku when you type rake deploy. Don’t run rake deploy at this time, though, because you haven’t set up Heroku yet.

Rakefile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
desc "Deploy a basic rack app to heroku"
multitask :heroku do
puts "## Deploying to Heroku"
    (Dir["#{deploy_dir}/public/*"]).each { |f| rm_rf(f) }
    system "cp config.ru #{deploy_dir}/"
    system "cp -R #{public_dir}/* #{deploy_dir}/public"
    puts "\n## Copying #{public_dir} to #{deploy_dir}/public"
    cd "#{deploy_dir}" do
        system "git add ."
        system "git add -u"
        puts "\n## Committing: Site updated at #{Time.now.utc}"
        message = "Site updated at #{Time.now.utc}"
        system "git commit -m '#{message}'"
        puts "\n## Pushing generated #{deploy_dir} website"
        system "git push heroku #{deploy_branch}"
        puts "\n## Heroku deploy complete"
    end
end

…then update these variables, (in your Rakefile).

1
2
3
deploy_default = "heroku"
deploy_branch = "master"
deploy_dir = "_heroku"

Signing up for and Configuring Heroku

Now it’s time to sign up for a free Heroku account. The Octopress documentation recommends installing the heroku gem, but that’s deprecated so download and install the Heroku Toolbelt instead.

1
2
3
4
ssh-keygen # Generate a public/private key pair
heroku create # Enter your Heroku credentials
<number_for_public_key> <ENTER>` # Use the public key that was created when you ran `ssh-keygen`
heroku rename <sitename> # Also make sure that `url:` in _config.yml matches http://<sitename>.herokuapp.com

Now you can do your first deploy to Heroku!

1
2
3
4
5
6
7
cd ~/Sites/<sitename>/_heroku
git init .
git add .
git config branch.master.remote heroku
git commit -am "Initial commit."
rake generate && rake watch
rake deploy

Exporting your WordPress Posts and Comments

Log on to your WordPress Admin and export your content in XML format. You can find this under Tools > Export. Keep this data handy because we’ll be using it in the next step.

The next steps I took were to sign up for a free Disqus account, install the (Disqus) WordPress plugin, and export my comments to Disqus from the plugin options. This will ensure that your comments are preserved after migrating to Octopress, (as long as your permalinks don’t change). Also be sure to add your Disqus shortname to _config.yml.

Importing your WordPress data into your Octopress Site

There are a number of tools available for importing your WordPress posts into Octopress as Markdown files, but the one I ended up using was exitwp. You can follow these steps to import your WordPress site with exitwp.

1
2
3
4
5
6
7
8
9
10
11
12
13
brew install python
printf '\nexport PATH=/usr/local/share/python:$PATH' >> ~/.bash_profile
source ~/.bash_profile
pip install virtualenv
pip install virtualenvwrapper
source /usr/local/share/python/virtualenvwrapper.sh
mkvirtualenv --no-site-packages octopress # Don't symlink site packages so your environment is more isolated
brew install libyaml
pip install pyyaml
pip install BeautifulSoup4
pip install html2text
cd ~/Documents
git clone https://github.com/thomasf/exitwp

Now, copy your WordPress XML files to ~/Documents/exitwp/wordpress-xml, then run xmllint on your export file and address any errors you encounter. You should also customize what you want exported in ~/Documents/exitwp/config.yaml, (e.g., whether or not you want images to be downloaded and included in your build directory). To run the tool type python exitwp.py in the terminal from within the ~/Documents/exitwp directory.

You should now see your converted site in ~/Documents/exitwp/build, which you can copy to your source directory.

Remove /blog/ from Octopress URL

Follow these steps if you don’t want /blog/ to appear in your Octopress URL.

Update the permalink setting in _config.yml.

_config.yml
1
permalink: /:year/:month/:day/:title/

Move the contents of the blog directory.

1
2
3
mv ~/Sites/<sitename>/source/blog/archives ~/Sites/<sitename>/source/archives
mv ~/Sites/<sitename>/source/blog/articles/index.html ~/Sites/<sitename>/source/articles/index.html
rm -rf ~/Sites/<sitename/source/blog

Update the navigation in source/_includes/custom/navigation.hmtl.

1
2
3
4
5
6
7
8
# Change this
<li><a href="/blog/archives">Archives</a></li>
# to this
<li><a href="/archives">Archives</a></li>
# ...and this:
<li><a href="/">Blog</a></li>
# to this:
<li><a href="/">Home</a></li>

Update the Archives link in source/index.html.

1
2
3
4
# Change this:
<a href="/blog/archives">Blog Archives</a>
# to this:
<a href="/archives">Archives</a>

Update the category base URL in _config.yml.

1
2
3
4
5
6
7
8
# Change this:
category_dir: blog/categories
# to this:
category_dir: category
# ...and this:
pagination_dir: blog
# to this:
pagination_dir:

Update the Archives page title in source/archives/index.html.

1
2
3
4
# Change this:
title: Blog Archive
# to this:
title: Archives

Change Author Name After Importing from WordPress

Another thing that bothered me for a while about my WordPress blog was that the author metadata for posts and pages reflected the ‘admin’ shortname. This is because I left the default username when initally setting up WordPress years ago. I’m sure there’s an easy way to change this, but now that my blog consists of plain text files I have the freedom to use whatever tools I choose to make changes. Here’s a perfect example of that using find and sed.

1
cd ~/Sites/<sitename>/source && find . -name "*.markdown" -print0 | xargs -0 sed -i '' -e 's/author:\ admin/author:\ Forename\ Surname/g'

Using Google Fonts

If you love Google Fonts add this to the top of source/_includes/custom/head.html, (just be sure to use your own favorite fonts!).

1
<link href='http://fonts.googleapis.com/css?family=Archivo+Narrow:400,700' rel='stylesheet'  type='text/css'>

Prevent Comment Text from Wrapping on Small Screens

One of the first things I noticed with the default Octopress theme is that the Disqus comments text that appears above posts was wrapping on smaller screens, which caused it to overlap with the post title. To fix this, I added the following to sass/custom/_styles.scss.

_styles.scss
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
article {
    header {
        p {
            &.meta {
                font-size: .7em;
            }
        }
    }
}

@media only screen and (min-width: 480px) {
    article {
        header {
            p {
                &.meta {
                    font-size: .9em;
                }
            }
        }
    }
}

404

You might also want a custom 404 page. Fortunately, that’s pretty easy too.

1
2
3
4
5
6
cd ~/Sites/<sitename> && rake new_page[404]
cd source/404
mv index.markdown 404.markdown
mv 404.markdown ../
cd ../
rm -rf 404

Then update the yaml front matter in 404.markdown.

Fancybox

I followed a post on Ewal.net to get Fancybox working with Octopress. The only difference is that I didn’t add a reference to jQuery in the head because it’s already present in the default installation of Octopress.

To add Fancybox support to an image simply add this to your post.

1
<img class="fancybox" src="/dir/foo.jpg" title="Title" >
source/javascripts/anchor.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$(function() {
    $('.entry-content').each(function(i){
        var _i = i;
            $(this).find('img.fancybox').each(function(){
            var img = $(this);
            var title = img.attr("title");
            var classes = img.attr("class");
            img.removeAttr("class");
            img.wrap('<a href="'+this.src+'" class="' + classes + '" rel="gallery'+_i+'" /   >');
            if (title != "")
            {
                img.parent().attr("title", title);
            }
        });
    });
    $('.fancybox').fancybox();
});

Open Vim when running rake new_post and make new posts un-published by default

Add the following to your Rakefile if you want rake new_post to open in your editor and new posts to be un-published by default. Replace Vim with your favorite editor if you dare. :)

Rakefile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
desc "Begin a new post in #{source_dir}/#{posts_dir}"
task :new_post, :title do |t, args|
    if args.title
        title = args.title
    else
        title = get_stdin("Enter a title for your post: ")
    end
    raise "### You haven't set anything up yet. First run `rake install` to set up an    Octopress theme. "
    unless File.directory?(source_dir)
    mkdir_p "#{source_dir}/#{posts_dir}"
    filename = "#{source_dir}/#{posts_dir}/#{Time.now.strftime('%Y-%m-%d')}-#{title.     to_url}. #{new_post_ext}"
    if File.exist?(filename)
        abort("rake aborted!") if ask("#{filename} already exists. Do you want to        overwrite?", ['y', 'n']) == 'n'
    end
    puts "Creating new post: #{filename}"
    open(filename, 'w') do |post|
        post.puts "---"
        post.puts "layout: post"
        post.puts "title: \"#{title.gsub(/&/,'&amp;')}\""
        post.puts "date: #{Time.now.strftime('%Y-%m-%d %H:%M')}"
        post.puts "published: false"
        post.puts "comments: true"
        post.puts "categories: "
        post.puts "---"
    end
    system "vim \"#{filename}\""
end

Finalize DNS

The last step for me was to transfer my DNS records from Amazon Route 53 to Hover, (my registrar). Heroku has a farily detailed article on using custom domains, so I recommend reading that.

Here are the relevant Heroku commands. Don’t forget to update the url: in _config.yml one last time, (e.g., remove herokuapp from URL).

1
2
cd ~/Sites/<sitename>/_heroku && heroku domains:add <sitename>.com
heroku domains:add www.<sitename>.com

  1. Yes, I spelled that correctly. Google it.

Automatically Post Images to Tumblr with Automator

| Comments

For the past few months I have been drawing every day on 2.5 x 3.5 inch pieces of Bristol board as part of my most recent ‘kooBtrA’ project. kooBtrA = ArtBook in reverse, as I plan to self publish a full-color book containing all the images sometime after one year passes.

As you might imagine, finding the time to draw every day can be challenging. Not to mention the fact that I’ve also been posting these images to my Tumbleog; which includes scanning, resizing, and logging into Tumblr to post the image along with a description and tag. This became mundane after the first few days of posting, so I decided to set time aside to automate this process, as doing so would surely save me time in the long run.

I did a bit of research and discovered that Tumblr offers the ability to send posts via email. This immediately gave me the idea of using Automator) to streamline this process, as Automator offers a very straightforward ‘New Mail Message’ Action. This would allow me to create an Image Capture Plugin that grabs the image that was scanned and include it in the email message, right? Well, yes, but with one caveat. With Snow Leopard’s introduction came a few changes, one of which removes the ability to scan to a specified folder while using an Image Capture Plugin, (the image is saved to the ~/Pictures folder, then the Workflow runs). The workaround in my case was to use a Folder Action, which would result in the Workflow running any time a new file is added to the specified folder.

What I had been doing until this point was scanning the image to a subfolder of my ~/Documents folder; scaling the image to 300px max on either side depending on orientation; then uploading the image to Tumblr.com along with a description and tag. The Folder Action Workflow I ended up producing cuts the time this took in half.

The first thing I did was create two variables. One for the name of the post and one for the number of the post. You can achieve this by right or control clicking in the variables window at the bottom of the application window and choosing ‘New variable.’ I left the value blank, as this will vary with each post. The next step was to start dragging actions over to the right of the application window. The first is an ‘Ask for Text’ Action, which asks for the name of the post, then sets the value of the variable. The same goes for the number of post. The Workflow then asks for the Finder items to act on, then copies them to a new location and scales them to 300px. Finally, the ‘New Mail Message’ Action is added, which utilizes the name and number variables that were set previously, as well as receives the resized image from the previous Action. The last Action that was added was ‘Send Outgoing Messages,’ which is fairly self explanatory.

Below is the printed Workflow for your reference should you wish to accomplish something similar. If you have any suggestions as to improving this Automator Workflow please leave a comment. For more information regarding Tumblr’s post via email option please visit http://www.tumblr.com/docs/en/email_publishing.

Restore MySQL Database from ibdata and .frm Files

| Comments

Last week I was presented with a problem that involved restoring a MySQL database for a client using only the /data folder from an original MySQL installation. The solution turned out to be rather simple, but that didn’t stop me from racking my brain for a few hours. Thus, I thought I’d share my experience in hopes of helping others that may run into this.

NOTE The MySQL database I was tasked with restoring was associated with a WordPress installation. My guess is that this is irrelevant, though.

ALSO NOTE This article assumes you are comfortable with software solutions such as MAMP and/or XAMPP, as well as phpMyAdmin.

I made the decision early on to solve this problem locally, (I find that working directly from a web server usually just gets me into trouble).  I use MAMP on a regular basis and as such have quite a few MySQL databases associated with that installation. Rather than fooling with this at all I opted to use XAMPP on a Windows XP SP2 machine. Either one of these solutions will work, as they essentially provide the same services. I chose to avoid using MAMP on my machine because of everything I have invested into that application, but that doesn’t mean you have to.

The first thing you’ll want to do is install a fresh copy of either MAMP, (Mac only), or XAMPP. Then create an empty database using phpMyAdmin with the same name as your original database, (the one you’re trying to restore). For example, if your previous database was called ‘wordpress,’ in phpMyAdmin, (under the ‘Create new database’ text field), you would enter ‘wordpress.’ This will create a folder named wordpress in /Applications/MAMP/db/mysql if you’re using MAMP, or C:\xampp\mysql if you’re using XAMPP. At this point you’ll want to turn off the MySQL service. Now, copy the contents of, (not the entire folder), your mysql database folder that contains the .frm files to the new location. The next step is to copy the ibdata1 file to the MySQL folder in either XAMPP or MAMP, then start the MySQL service again. Now you should be able to locate your database tables in phpMyAdmin.

At this point, (assuming you don’t want to keep the data locally on your machine), you’ll want to export the database using phpMyAdmin. Be sure to check Add DROP TABLE, choose SQL as the export type, and check the ‘Save as file’ checkbox. The .sql file that will be generated can easily be imported into another instance of phpMyAdmin. The new database doesn’t need to have the same name as the previous database, either. I was unable to use my previous database name because the site I was working on had been moved to a shared hosting server, (where someone had already chosen the name of my previous database), and everything worked fine.

Also keep in mind that this can be accomplished whether or not your server is running phpMyAdmin. There are plenty of alternatives available that will allow you to accomplish the same tasks, and there’s always the command line. The most important step is to simply copy the contents of the /data folder and the ibdata1 file. Hope this helps!

Leave a comment if you have any questions!

In-Store Signing at Pages Bookstore

| Comments

The kind folks at Pages Bookstore have invited me to do a book signing and give a short talk on comics production on May 8, 2010. The event will be taking place from 1-3 pm in downtown Flint, MI. If you’re in the area stop by to pick up one of my short comics and chat with me for a bit. The promotional poster I did for the event can be found in the portfolio section of this site.

MSU Comics Forum

| Comments

Thanks to my mentor and friend Ryan Claytor I’ll be tabling at the MSU Comics Forum on March 27, 2010. The event is held annually at, you guessed it, Michigan State University. There I’ll be showcasing my latest comic, “Here For Now,” (which I’ll soon have examples of in the portfolio section of this site), as well as my first comic, “Stars Beneath Stars.” For more info please visit http://www.comicsforum.msu.edu/.

Configure Archive Utility in Mac OS X

| Comments

Having recently purchased a new MacBook Pro and electing to skip the option of running Migration Assistant) to transfer my data and settings, I noticed that a few applications were behaving differently. Over the years I’ve configured quite a few things on my Mac, and eventually I became accustomed to said customizations. One of the first things I noticed was that when I would unarchive a zip file, the compressed file would stay put. I remembered that a few years ago I learned of a cool way to configure Mac OS X’s built-in Archive Utility, (using a System Preference pane), so I immediately went digging. To do this, simply navigate to /System/Library/CoreServices. From there right or control click on Archive Utility.app, and select “Show Package Contents.” A new window will open containing a folder named Contents, within which you’ll find Resources, and finally Archives.prefPane. Opening this preference pane will result in System Preferences.app asking if you’d like to install for all users or for this user only. Voila! Now you can tell Archive Utility to delete the archive after expanding it.

10 Inspiring Websites

| Comments

Lately I’ve been spending quite a bit of time designing websites, whether it’s WordPress theme development or Joomla! template design. A huge part of this process, (for me), is finding inspiration. Below are 10 carefully crafted examples of good web design that I’ve been inspired by as of late.

31THREE

Kyle Florence

A List Apart

Buffalo

Design by Silnt

FullAhead

Viget

thinkdesign

Ed Merritt

ThemeShaper

Webcomics

| Comments

I have a confession to make: I love webcomics. I’m quite the comics nerd in general, to be honest. It’s possible that recently completing the first sequential drawing class offered at my university rekindled this fascination, but who’s keeping track? If you’re interested in finding out who’s responsible for teaching me everything I know about the production of comics, visit my professor’s site elephanteater.com. I’ll have a few more samples from my comic posted in the portfolio section here shortly. Now back to webcomics, here are a few of my favorites:

xkcd
American Elf
Least I Could Do
Looking For Group
Toothpaste for Dinner
NatalieDee
Questionable Content
AppleGeeks