I use this Capistrano recipe at work to send a broadcast to the office when I deploy an update. We use Jabber, and have a broadcast user that forwards messages to every user.

Copy jabber.yml to config/jabber.yml. Edit the details in it:

username: The Jabber account that will be **SENDING** alerts
          to the broadcast account

password: The password for the above Jabber account

broadcast: The Jabber broadcast account configured to forward
           messages to all users

Drop jabber.rb to config/deploy/jabber.rb. Add load "config/deploy/jabber.rb" to config/deploy.rb.

When you deploy and Capistrano hits the web:disable and web:enable tasks, a message will be sent to your users indicating the system is down. You can customize this message like so:

JABBER_REASON='a database migration' JABBER_DOWNTIME='10 minutes' cap deploy
JABBER_REASON='everything is broken' JABBER_DOWNTIME='a long time' cap deploy:web:disable

I extracted a few pieces of code into Rails Plugins.

  • Cars: Helpers for populating dropdowns with automobile makes and models
  • Host Router: Allows creation of routes based on hostname or port
  • Multisite: Provides site-specific view paths
  • Remote Database: Helpers for working with databases on multiple hosts
  • Fraud Guardian: Helpers for generating fraud reports via FraudGuardian

Nothing spectacular, but maybe they’ll help someone else.

I needed HTTP basic authentication for a Sinatra app running as a Rails Metal. I have two apps, one running Clearance and another running Authlogic.

Using the info from my previous post, I wrote a small Sinatra plugin that works with both Clearance and Authlogic.

Throw the file above in lib/sinatra_authentication.rb. Then, your metal, app/metals/api.rb would look something like this:

Authlogic doesn’t have an authenticate method, so I added this to app/models/user.rb:

Hope it helps someone else.

Recently, I needed to write an API to work with an iPhone application. I used Clearance for authentication. Unfortunately, it doesn’t support HTTP Basic Authentication out of the box, which made it difficult to use in an API.

I found this issue with a patch that worked. However, the Thoughtbot guys said that Rack::Auth::Basic should be used instead. No examples were provided.

I tried for a few days to get things to work with Rack and ended up using that patch.

Today I decided to take another look at this. I found a cached slideshow on Google that had the info I needed to make an API using a Sinatra app as a Rails Metal.

This is basically how I got HTTP Basic Auth working with Clearance:

Hope it helps someone else having this problem.

I missed Ruby’s Array.first and Array.last methods coding in Javascript tonight, so I wrote them myself:

If you’re using Jekyll and pagination (see Template data), make sure you’re using index.html and NOT index.markdown or index.md.

If you don’t use a .html extension, pagination will not work.

I recently wrote a git alias to open a repo in your web browser.

Why not just install hub and use hub browse I hear you ask? Well, because browse is the only feature of hub I actually used, and it only works on GitHub repos. This one doesn’t wrap the git executable, and works outside of GitHub.

This assumes that the URLs for both git and web are the same (except for the git parts). Eg:

Git: git@github.com:itspriddle/dotfiles.git
Web: http://github.com/itspriddle/dotfiles

Git: git://example.com/scripts/hacks.git
Web: http://example.com/scripts/hacks

Git: http://example.com/private/ninja-training.git
Web: http://example.com/private/ninja-training

Add the following to ~/.gitconfig under the [alias] section (or create it if you haven’t created any aliases):

browse  = !open $( \
  echo \"`git config remote.origin.url`\" | \
  ruby -e \"url = ARGF.read\" \
       -e \"url.sub!(/^(git\\:\\/\\/|git@|http\\:\\/\\/|https\\:\\/\\/)/, '')\" \
       -e \"url.sub!(':', '/')\" \
       -e \"url.sub!(/\\.git\\$/, '')\" \
       -e \"print 'http://' + url\" \
)

Run git browse from your repo and watch in awe as it opens in your web browser.

It’s admittedly a bit fragile, but has worked on all of the repositories that I work with regularly. Feel free to fork it if you have improvements.

This will only work for OS X, but you should be able to get it working on Linux with something like gnome-open.

I’ve been using TextMate nearly every day for 2 years. Over that time I’ve customized it exactly to my liking with a bunch of extra bundles, plugins, and theme tweaks. I’ve tried a few different things to try to manage my ~/Library/Application Support/TextMate directory.

I got bored one day and decided I’d try managing them with git submodules. It was more of an exercise in learning the git submodule command, but it turns out it’s also a great way to maintain my TextMate config.

Read up on submodules yourself, but the important thing to note here is that a submodule acts as a git “symlink” to a specific commit on a repo. Instead of keeping the entire Bundles directory (and subfiles) in your repo, a .gitmodules file keeps track of the clone url and the local file path. Take a look at my Bundles directory on GitHub for a visual representation of what I’m talking about.

If you don’t care about the specifics, just check out my TextMate Config. If you do… keep reading.

The steps boil down to this

  1. Create repo in ~/Library/Application Support/TextMate
  2. Add submodules in ~/Library/Application Support/TextMate/Bundles
  3. Initialize submodules
  4. Maintain submodules

Create repo

This is best done from a blank support directory, so backup ~/Library/Application Support/TextMate and then empty it. Then run cd ~/Library/Application Support/TextMate && git init to create the repository. Create your bundles directory with mkdir Bundles.

Add submodules

Add submodules using git submodule add [repo url] [file path]. Using the repo you created before, you might add Dr. Nic’s Ruby On Rails bundle with the following command:

git submodule add git://github.com/drnic/ruby-on-rails-tmbundle.git "Bundles/Ruby on Rails.tmbundle"

This command, tells git to add a submodule for Dr. Nic’s repo on GitHub to Bundles/Ruby on Rails.tmbundle. Repeat this process for any other bundles you have.

Initialize submodules

You probably jumped ahead already and noticed that your Bundles/ directory is essentially empty. In order to actually download submodules, you need to initialize them with git submodule init, then update them with git submodule update. You’ll see git download each submodule and print the sha1 hash of the commit it used. Reload TextMate, and you’re ready to rock.

Maintain submodules

It’s likely you’re going to need to update your bundles at some point - either a new version is released, or you’ve decided you no longer need a bundle.

To add a new submodule you’d simply run git submodule add again, as before.

Updating submodules is slightly different, and admittedly, a little cumbersome. Let’s say Dr. Nic updated the Rails bundle. Here are the steps I’d take to pull those changes:

cd Bundles/Ruby\ on\ Rails.tmbundle
git pull origin master
cd ../..
git add Bundles/Ruby\ on\ Rails.tmbundle
git commit -m "Updating Ruby on Rails bundle"

Deleting submodules is a bit of a pain, and requires Google every time I need to do it. First, you need to manually edit both .gitmodules and .git/config, and remove the offending submodule. The not-so-obvious step, is removing the module from git itself. Do do this, you’d run git rm --cached Bundles/Bundle to delete.tmbundle. Commit those 3 changes and you’ve successfully removed the bundle from your repo.

Notes on committing

When you run git submodule add, git will automatically update and stage your .gitmodules file for you. To commit the bundle too, run git add Bundles/MY Bundle.tmbundle. Again, this is committing a pointer to the submodule, not the entire bundle’s contents.

Sharing/Installation on a new Mac

If you need to help a friend clone your setup, or install TextMate on a new Mac, you’ll be very happy you took the time to do this. Just run (replacing your repo URL):

git clone git://github.com/itspriddle/textmate-config.git ~/Library/Application\ Support/TextMate
cd ~/Library/Application\ Support/TextMate
git submodule init
git submodule update

Boom - good to hack.

I’ll also note that this same method can easily be applied for vim configs.

I found this git hook that lets you deploy a project with a git push rather than having to use a full deployment library such as Capistrano. I use this on a bunch of PHP projects that don’t need all the features Capistrano provides.

On the remote server, we’re going to assume you’re keeping your project in /var/www/example.com from a repository called example.com

mkdir /var/www/example.com
cd /var/www/example.com
git init
git config receive.denyCurrentBranch ignore
cd .git/hooks
curl -O http://gist.github.com/raw/398175/b0a281817b307ca21dd7c21b34cadbd91170ead8/post-update
chmod +x post-update

On your local development machine:

cd /path/to/example.com
git remote add production user@myserver.com:/var/www/example.com/.git
git push production master

Any time you need to update in the future, just use git push production [branch] and it’ll be updated on your remote server.

I work on a few apps that deal with phone numbers. I usually store these as bigint(11) in MySQL. My migrations always seemed to ignore this.

t.integer :phone_number, :limit => 11

Tonight, I found the following method in ActiveRecord that explains this weirdness:

# Maps logical Rails types to MySQL-specific data types.
def type_to_sql(type, limit = nil, precision = nil, scale = nil)
  return super unless type.to_s == 'integer'

  case limit
  when 1; 'tinyint'
  when 2; 'smallint'
  when 3; 'mediumint'
  when nil, 4, 11; 'int(11)'  # compatibility with MySQL default
  when 5..8; 'bigint'
  else raise(ActiveRecordError, "No integer type has byte size #{limit}")
  end
end

To fix this, try t.integer :phone_number, :limit => 5 instead.

It seems that (at least with the MySQL adapter), limit actually specifies the number of bytes that are using in the column, rather than the display limit.

Hope that helps someone else.

I threw together a simple script to create a new post in _posts/ for a Jekyll based blog.

Save it to _script and then run

POST_TITLE="My new post" ./_script/generate post

I’ve used CodeIgniter in several PHP projects, and I love it (if I have to write PHP). I’m a big fan of the included Database Library.

I write a lot of server side scripts in PHP for work (crons, etc). I really hate ADODB’s syntax, so I set out to extract CodeIgniter’s database library.

CodeIgniter Database Library is the result of my hacking. I haven’t tested this very thoroughly, but I plan to with any PHP scripts I write in the future.

If you’ve ever used the MySQL module with Asterisk, you’ve probably had loads of fun formatting queries.

This query:

SELECT * FROM accounts WHERE extension = '${EXTEN}'
AND enabled = 'Y' AND balance > 0.00 LIMIT 1;

Becomes:

SELECT\ *\ FROM\ accounts\ WHERE\ extension\ =\ \'${EXTEN}\'\
AND\ enabled\ =\ \'Y\'\ AND\ balance\ >\ 0.00\ LIMIT\ 1;

That probably doesn’t seem too difficult, but if you have huge queries, it’s really easy to miss a character that needs to be escaped. Needless to say, if you put code like that into production, your PBX is going to die when the dialplan hits that code.

I finally threw together a script to do this automatically.

Now, I can run:

asterisk-format-query <<'QUERY'
SELECT * FROM accounts WHERE extension = '${EXTEN}'
AND enabled = 'Y' AND balance > 0.00 LIMIT 1;
QUERY

NOTE: Above, I used a quoted heredoc. This prevents your shell from trying to interpolate things like ${EXTEN}.

It took me a while to find a clearly documented way to manage gems without having to use sudo. Just drop these lines into your ~/.zshrc or ~/.bashrc file.

Easy.

Redmine has an awesome feature built in that lets you check an email account to import new tickets into your project.

Unfortunately, I didn’t see a clear way to do this without exposing your IMAP username/password to your cron.logs. I wrote a small script that reads the username/password/host from your config/email.yml file.

NOTE If you are using a different email account than the one in config/email.yml then you should create config/imap.yml and include that in this script. ** DO NOT ** add extra fields to config/email.yml or you’ll break things.

For my own reference really, here are the steps I took to setup an Apache vhost to redirect all non-SSL requests to https:

After migrating my blog from Wordpress to Jekyll, one thing I was missing was a functional search box. I threw one together last night.

The first problem is getting a “database” of blog posts that can be searched with jQuery. Luckily Jekyll parses anything with YAML Front Matter, so I was able to whip up a posts.json file that’s dynamically created.

Next, I tried using Ziadin Givan’s jQuery autocomplete plugin but it didn’t quite work the way I needed it to. I ended up using it as a starting point to roll my own.

A sample gist is up to get you going, or see the full source.

I’ve had to do this a few times when I wasn’t able to just drop the entire database, so I threw together a small PHP script that will do it for you.

Just add your username, password, and database name and save it as drop_wp_tables.php. If you have shell access you can run php drop_wp_tables.php. Otherwise upload it to your site and pull up http://yoursite.com/wp_delete.php. Make sure you delete this file if you upload it to your site!

Note: If you used something other than wp_ as your table prefix, make sure to edit the script accordingly.

I wrote these as helpers for a project I’m making with CodeIgniter, but you can use them in any application.

So I learned yet another awesome feature in vim today - code folding.

For those of you who don’t know what I’m talking about, code folding lets you shrink the contents of multiple lines of code into 1 line. A lot of the better code editors out there do it, like Dreamweaver and ZendStudio. It’s a handy feature when you have scripts with hundreds of lines of code.

There are several ways you can fold a portion of code in vim. You could type 10:fold for instance, and the 10 lines under the cursor would be folded. You could also specify the start and end lines manually with :[start line],[end line]fold

An easy way I saw to do this, is to use Shift+V in command mode. This will let you highlight lines of code. So it’s as simple as pressing Shift+V then the down arrow until you’ve highlighted a section of code. Then you can press zf to fold (or type in :fold).

Cool right? There’s one more thing I did to keep these folds from session to session - normally folds will disappear after you close vim unless you create what is called a view. I found a page on vim.org that explains how to do this automatically. Just add these lines into your ~/.vimrc file:

autocmd BufWinLeave *.* mkview
autocmd BufWinEnter *.* silent loadview

This will save your folds when you exit a document and load them when you open it.

Happy folding!

I did this about 8 months ago and never wrote down my steps. I just had to figure it out again for another server, and thought I’d write it down here to save myself (and possibly someone else) time.

First, this requires you have SSH access to your host. If you don’t, this post wasn’t meant for you. Then again… you probably wouldn’t need vim7 if you didn’t. Anyway, open a shell and enter these commands:

$ mkdir -p ~/local/src
$ cd ~/local/src
$ wget ftp://ftp.vim.org/pub/vim/unix/vim-7.1.tar.bz2
$ tar -vjxf vim-7.1.tar.bz2
$ cd vim71
$ ./configure --prefix=$HOME/local
$ make
$ make install

Vim is now installed in $HOME/local/bin/vim. To use that instead of /usr/bin/vim (your webhost’s OLD vim), open ~/.bash_profile (create it if it doesn’t exist) and add $HOME/local/bin to the front of your path. My path looks like this:

export PATH=$HOME/local/bin:$PATH

That will look for any programs in $HOME/local/bin first. If they’re not there, move on the the system defined path to look.

Note: When I did this, vim wasn’t importing /etc/vimrc, so I had to copy it to my home dir.

$ cp /etc/vimrc ~/.vimrc

You’ll likely need to make some edits so everything works/looks how you want.