Welcome

Snippets is a public source code repository. Easily build up your personal collection of code snippets, categorize them with tags / keywords, and share them with the world (or not, you can keep them private!)

What next?
1. Bookmark us with del.icio.us or Digg Us!
2. Subscribe to this site's RSS feed
3. Browse the site.
4. Post your own code snippets to the site!

Limit Google searches by date

See: Easy Way to Find Recent Web Pages

date='d15'
date='m3'
date='y'
words='unix linux shell bash'
site='codesnippets.joyent.com'

open -a Safari "http://www.google.com/search?q=${words// /+}&as_qdr=${date}"

open -a Safari "http://www.google.com/search?q=site%3A${site}%20${words// /+}&as_qdr=${date}"


# sbd - search by date
# cf. also http://codesnippets.joyent.com/posts/show/1700

function sbd() {
   declare date site words
   date="${1}"
   words="${2}"
   site="${3}"
   if [[ $# -eq 2 ]]; then
      /usr/bin/open -a Safari "http://www.google.com/search?q=${words// /+}&as_qdr=${date}"
   elif [[ $# -eq 3 ]]; then
      /usr/bin/open -a Safari "http://www.google.com/search?q=site%3A${site}%20${words// /+}&as_qdr=${date}"
   else
      return 1
   fi
   return 0
}


sbd d 'unix linux shell bash'
sbd m5 'unix linux shell bash'
sbd y3 'unix linux shell bash' codesnippets.joyent.com

Copying JUST mp3 files, flattening directory structure

// This is a simple find command that copies only mp3 files
// from an iTunes directory; it only copies the files into
// a directory called "mp3_flat"

find /[[yourpath]]/iTunes\ Music -iname "*.mp3" -exec cp {} /[[yourbackuppath]]/mp3_flat/ \;

My capistrano recipe for deploying on shared accelerator from a git repo

// deploy.rb - note that the git repo is also hosted on the shared accelerator

before("deploy:restart") { set :use_sudo, false } 
after "deploy:start", :restart_web_server
set :user, "my_user_name"
set :application, "myapp.com"
set :domain, "myapp.com"
set :joyent_primary_domain, "prospect.joyent.us"
set :repository, "ssh://my_user_name@prospect.joyent.us/users/home/my_user_name/git/myapp.git"
set :scm, :git
set :deploy_to, "/users/home/#{user}/domains/#{domain}/web"

set :use_sudo, false
role :app, "#{joyent_primary_domain}"
role :web, "#{joyent_primary_domain}"
role :db,  "#{joyent_primary_domain}", :primary => true

default_run_options[:pty] = true
namespace :deploy do
  desc "Restart Mongrel by killing" 
  task :restart, :roles => :app do
    run "pkill mongrel"
  end
end

Watch YouTube videos with QuickTime

Requires SIMBL and GreaseKit. Tested on Safari.
# YouTube in MP4 via QuickTime Plugin!
# http://www.joeyhagedorn.com/2008/04/16/youtube-in-mp4-via-quicktime-plugin

open -a Safari http://www.joeyhagedorn.com/media/downloads/youtubeQT.user.js


# Download YouTube Videos as MP4 Files
# http://googlesystem.blogspot.com/2008/04/download-youtube-videos-as-mp4-files.html

open -a Safari http://members.optusnet.com.au/lbramsay/youtube_mp4.user.js


1. Youtube QT (http://www.joeyhagedorn.com/media/downloads/youtubeQT.user.js)
// ==UserScript==
// @name           Youtube QT
// @namespace      userscripts.org
// @description    Plays the high-resolution YouTube video in an embedded Quicktime player 
// @version        0.1
// @include        http://youtube.com/watch?*
// @include        http://www.youtube.com/watch?*
// @include        http://*.youtube.com/watch?*
// ==/UserScript==
	
var video_id = null;
var video_hash = null;
var video_player = document.getElementById('movie_player');

if (video_player) {var flash_variables=video_player.attributes.getNamedItem('flashvars');
	if (flash_variables) {var flash_values=flash_variables.value;
		if (flash_values) {var video_id_match=flash_values.match(/video_id=([^(\&|$)]*)/);
			if (video_id_match!=null) video_id=video_id_match[1];
				var video_hash_match=flash_values.match(/t=([^(\&|$)]*)/);
				if (video_hash_match!=null) video_hash=video_hash_match[1];
		}
	}
}

if (video_id==null || video_hash==null) {var args=unsafeWindow.swfArgs;
	if (args) {video_id=args['video_id'];
		video_hash=args['t'];
	}
}

if (video_id==null || video_hash==null) return;

var yt_mp4_path = 'http://www.youtube.com/get_video?fmt=18&video_id='+video_id+'&t='+video_hash;
var div_embed=document.getElementById('watch-player-div');

if (div_embed) {div_embed.innerHTML='<embed src=\''+yt_mp4_path+'\' type="video/mp4" width=480 height=400 scale=\'aspect\'></embed>';
};


2. Download YouTube Videos as MP4 (http://members.optusnet.com.au/lbramsay/youtube_mp4.user.js)
// ==UserScript==
// @name           Download YouTube Videos as MP4
// @description    Adds an option to download YouTube videos.
// @namespace      http://googlesystem.blogspot.com
// @include        http://*.youtube.com/watch?*
// @include        http://youtube.com/watch?*
// @version        0.4
// ==/UserScript==

if ( navigator.userAgent.indexOf("AppleWebKit") != -1 ) {
      if (document.getElementById('download-youtube-video')) return;
    
      var video_id = null;
      var video_hash = null;
      var video_player = document.getElementById('movie_player');
      
      if (video_player) {
        var flash_variables = video_player.attributes.getNamedItem('flashvars');  
        if (flash_variables) {
          var flash_values = flash_variables.value;
          if (flash_values) {
            var video_id_match = flash_values.match(/video_id=([^(\&|$)]*)/);
            if (video_id_match!=null) video_id = video_id_match[1];
            var video_hash_match = flash_values.match(/t=([^(\&|$)]*)/);
            if (video_hash_match!=null) video_hash = video_hash_match[1];        
          }
        }
      }
      
      if (video_id==null || video_hash==null) {
        var args = window.swfArgs;
        if (args) {
          video_id = args['video_id'];
          video_hash = args['t'];  
        }
      }
      
      if (video_id==null || video_hash==null) return;
     
       var yt_mp4_path ='http://www.youtube.com/get_video?fmt=18&amp;video_id='+video_id+'&amp;t='+video_hash; 
       var div_embed = document.getElementById('watch-embed-div');
       if (div_embed) {
          div_embed.innerHTML = div_embed.innerHTML + '<br /> <span id=\'download-youtube-video\'> <a href=\''+yt_mp4_path+'\'>Download as MP4</a> '+ ((navigator.userAgent.indexOf('Safari')!=-1)?'(control-click and select <i>Download linked file as</i>)' : ('(right-click and select <i>Save '+ (navigator.appName=='Microsoft Internet Explorer'?'target':'link') +' as</i>)')) + '</span>';
      }

} else {
    (function () {
    
      if (document.getElementById('download-youtube-video')) return;
    
      var video_id = null;
      var video_hash = null;
      var video_player = document.getElementById('movie_player');
      
      if (video_player) {
        var flash_variables = video_player.attributes.getNamedItem('flashvars');  
        if (flash_variables) {
          var flash_values = flash_variables.value;
          if (flash_values) {
            var video_id_match = flash_values.match(/video_id=([^(\&|$)]*)/);
            if (video_id_match!=null) video_id = video_id_match[1];
            var video_hash_match = flash_values.match(/t=([^(\&|$)]*)/);
            if (video_hash_match!=null) video_hash = video_hash_match[1];        
          }
        }
      }
      
      if (video_id==null || video_hash==null) {
        var args = unsafeWindow.swfArgs;
        if (args) {
          video_id = args['video_id'];
          video_hash = args['t'];  
        }
      }
      
      if (video_id==null || video_hash==null) return;
     
       var yt_mp4_path ='http://www.youtube.com/get_video?fmt=18&amp;video_id='+video_id+'&amp;t='+video_hash; 
       var div_embed = document.getElementById('watch-embed-div');
       if (div_embed) {
          div_embed.innerHTML = div_embed.innerHTML + '<br /> <span id=\'download-youtube-video\'> <a href=\''+yt_mp4_path+'\'>Download as MP4</a> '+ ((navigator.userAgent.indexOf('Safari')!=-1)?'(control-click and select <i>Download linked file as</i>)' : ('(right-click and select <i>Save '+ (navigator.appName=='Microsoft Internet Explorer'?'target':'link') +' as</i>)')) + '</span>';
      }
      
    })();
}

Deployment Recipe for Joyent Shared Accelerator

This is the deploy.rb I am using with a Shared Accelerator (with a few changes). It assumes you are using Mongrel and a proxy to serve the application. Joyent has good examples for those in the KB.

Not everything is *required* for a Shared Accelerator, but better to have some placeholders if you move your application later. The standard Capistrano :setup task worked for me, surprisingly. Haven't tried it since 2.0 or so.

The tasks for deploy:web:disable and deploy:web:enable are hacks. Ideas would be appreciated. Using the "pkill mongrel" trick hasn't always worked for me (sometimes SMF doesn't restart it), so I do it manually.

This isn't perfect, but hopefully it helps.

### deploy.rb
  set :application, "my_application"
  set :domain, "humboldt.joyent.us"

  set :user, "my_user"
  set :runner, user
  set :admin_runner, user # Does nothing on a Shared Accelerator
  set :scm_username, user
  set(:scm_password){Capistrano::CLI.password_prompt("Subversion Password: ")}
  
  set :scm, :subversion
  set :repository, "svn+ssh://#{scm_username}@#{domain}/users/home/#{user}/svn/#{application}/trunk/"
  set :checkout, "export"

  role :app, domain
  # These aren't required if you are just using one Shared Accelerator, but it's good practice
  role :web, domain
  role :db, domain, :primary => true
  
  set :deploy_to, "/users/home/#{user}/web/#{application}" # Or wherever you want the application root to be

  set :service_name, "smf-service_name" # Irrelevant because SMF doesn't work from the CLI on shared - left in as a reminder of a dream
  set :mongrel_config, "#{deploy_to}/shared/config/mongrel_cluster.yml" # Similarly irrelevant on Shared
  set :use_sudo, false # Don't need sudo on a shared accelerator
  default_run_options[:pty] = true # Much time was lost figuring this one out - see http://weblog.jamisbuck.org/2007/10/14/capistrano-2-1

# Shared Accelerators don't allow CLI access to SMF on Solaris
# Capistrano will throw warnings/errors if you don't overwrite these methods.
# It's a good opportunity to throw in a reminder about it.
namespace :deploy do
  desc "Restart the service"
  task :restart, :roles => :app  do
    puts "Remember to restart this from Webmin for changes to take effect."
    # Some svcadm stuff would go here if it worked
  end
  
  desc "Start the service" # The :spinner task went out of style when Mongrel and the gang came to town
  task :start, :roles => :app  do
    puts "Remember to start this from Webmin for changes to take effect."
  end
  
  desc "Stop the service"
  task :stop, :roles => :app do
    puts "This service must be stopped from Webmin."
  end
  
  # These tasks are used to enable/disable the application by replacing a .htaccess file
  # Surely someone has a better idea.
  namespace :web do
    desc "Present a maintenance page to visitors."
    task :disable, :roles => :web do
      run "cp /users/home/#{user}/web/public/down.txt /users/home/#{user}/web/public/.htaccess"
    end
    
    desc "Makes the application web-accessible again."
    task :enable, :roles => :web do
      run "cp /users/home/#{user}/web/public/up.txt /users/home/#{user}/web/public/.htaccess"
    end
  end
end

Japanese Alphabets Quiz

This is my first Ruby script. It requires two files, hiragana.rb and katakana.rb (I'm pasting them here as well).

Its purpose is to test your knowledge of two Japanese alphabets, Hiragana and Katakana.

# Japanese Alphabets Quiz, version 1.3 :)

puts "Would you rather test your hiragana (1) or katakana (2) knowledge?"

choose = gets.chomp.to_i

if 
	choose == 1
	puts "OK, hiragana, then!"
	require 'hiragana.rb'
	lang_name = "hiragana"
else
	puts "OK, katakana, then!"
	require 'katakana.rb'
	lang_name = "katakana"
end

$score = 0 

10.times do 

	alphabet = $characters
	
	# Select a random pair of key and value from the given hash
	
	character = alphabet.sort_by{ rand }[0...1] 
	
	# Turn the result into an array
	
	pair = character.shift { |key, value| }
	
	# Get the first array value (was the hash key)
	
	question = pair.first
	
	# Ask the question
	
	puts "Which character is " + question + "?"
	
	# Gets the answer from the user, strip spaces and turn it lowercase to match the hash case anyway
	
	answer = gets.chomp.strip.downcase
	
	# Validate user input
	
	if 
		answer == pair.last
		$score += 1
		puts "Correct! " + question + " is " + pair.last + "."
	else
		puts "Wrong! " + question + " is " + pair.last + "."
	end

end

def grade (points)

	case points
	when (0..3)
		"Bad"
	when (4..6)
		"Average"
	when (7..9)
		"Excellent"
	when (10)
		"Perfect"
	end

end

puts "End of " + lang_name + " quiz. You scored " + $score.to_s + " out of 10."

puts "Your grade is " + grade( $score ) + "."


hiragana.rb
# In this hash we set the basic hiragana characters and their respective phonetic counterparts

$characters = 
	{
	'' => 'a',
	'' => 'i',
	'' => 'u',
	'' => 'e',
	'' => 'o',
	'' => 'ka',
	'' => 'ki',
	'' => 'ku',
	'' => 'ke',
	'' => 'ko',
	'' => 'sa',
	'' => 'si',
	'' => 'su',
	'' => 'se',
	'' => 'so',
	'' => 'ta',
	'' => 'ti',
	'' => 'tu',
	'' => 'te',
	'' => 'to',
	'' => 'na',
	'' => 'ni',
	'' => 'nu',
	'' => 'ne',
	'' => 'no',
	'' => 'ha',
	'' => 'hi',
	'' => 'hu',
	'' => 'he',
	'' => 'ho',
	'' => 'ma',
	'' => 'mi',
	'' => 'mu',
	'' => 'me',
	'' => 'mo',
	'' => 'ya',
	'' => 'yu',
	'' => 'yo',
	'' => 'ra',
	'' => 'ri',
	'' => 'ru',
	'' => 're',
	'' => 'ro',
	'' => 'wa',
	'' => 'wo',
	'' => 'n'
	}


# In this hash we set the basic katakana characters and their respective phonetic counterparts

$characters =
		{
		'' => 'a',
		'' => 'i',
		'' => 'u',
		'' => 'e',
		'' => 'o',
		'' => 'ka',
		'' => 'ki',
		'' => 'ku',
		'' => 'ke',
		'' => 'ko',
		'' => 'sa',
		'' => 'si',
		'' => 'su',
		'' => 'se',
		'' => 'so',
		'' => 'ta',
		'' => 'ti',
		'' => 'tu',
		'' => 'te',
		'' => 'to',
		'' => 'na',
		'' => 'ni',
		'' => 'nu',
		'' => 'ne',
		'' => 'no',
		'' => 'ha',
		'' => 'hi',
		'' => 'hu',
		'' => 'he',
		'' => 'ho',
		'' => 'ma',
		'' => 'mi',
		'' => 'mu',
		'' => 'me',
		'' => 'mo',
		'' => 'ya',
		'' => 'yi',
		'' => 'yu',
		'' => 'yo',
		'' => 'ra',
		'' => 'ri',
		'' => 'ru',
		'' => 're',
		'' => 'ro',
		'' => 'wa',
		'' => 'wy',
		'' => 'wo',
	}

Compile & install git on Mac OS X

Requires Xcode.

export PATH=/usr/local/bin:/usr/local/sbin:/usr/local/lib:/usr/local/include:/usr/bin:/bin:/usr/sbin:/sbin
export IFS=$' \t\n'


# see what you already have
which asciidoc gpg gettext git
find /usr/lib /usr/local/lib -iname "*expat*"
python -V   # should be Python 2.4 or newer


# rudix
# http://rudix.org

cd ~/Desktop
curl -L -O http://downloads.sourceforge.net/rudix/rudix-1.5.2-0.dmg
hdiutil mount ~/Desktop/rudix-1.5.2-0.dmg
ls -1 /Volumes/* | egrep -i rudix
open -a Installer /Volumes/rudix/rudix.pkg
hdiutil unmount /Volumes/rudix

which rudix
man rudix


# expat
# also available via http://rudix.org

cd ~/Desktop
curl -L -O http://downloads.sourceforge.net/expat/expat-2.0.1.tar.gz
tar -xvzf expat-2.0.1.tar.gz 
cd expat-2.0.1
./configure --prefix=/usr/local
make
make check
sudo make install

find /usr/local -iname "*expat*"


# Python 2.5.2

cd ~/Desktop
curl -L -O http://downloads.sourceforge.net/rudix/python-2.5.2-1.dmg
hdiutil mount ~/Desktop/python-2.5.2-1.dmg
sudo rudix -i /Volumes/python/python.pkg
hdiutil unmount /Volumes/python

which python
python -V     # Python 2.5.2


# python-docs

cd ~/Desktop
curl -L -O http://downloads.sourceforge.net/rudix/python-docs-2.5.2-1.dmg
hdiutil mount ~/Desktop/python-docs-2.5.2-1.dmg
sudo rudix -i /Volumes/python-docs/python-docs.pkg
hdiutil unmount /Volumes/python-docs

man /usr/local/share/man/man1/python.1
ls -1 /usr/local/share/doc/python/*
find /usr/local/share/doc/python -mindepth 1 -maxdepth 1
find /usr/local/share/doc/python/doc -mindepth 1 -maxdepth 1
find /usr/local/share/doc/python/mac -mindepth 1 -maxdepth 1


# asciidoc
# asciidoc 8.3.0 requires Python 2.4 or newer

cd ~/Desktop
curl -L -O http://www.methods.co.nz/asciidoc/asciidoc-8.3.0.tar.gz
tar -xvzf asciidoc-8.3.0.tar.gz
cd asciidoc-8.3.0
open -e ~/Desktop/asciidoc-8.3.0/INSTALL
sudo ./install.sh

which asciidoc
man asciidoc


# GPG

cd ~/Desktop
curl -L -O http://downloads.sourceforge.net/rudix/gnupg-1.4.9-2.dmg
hdiutil mount ~/Desktop/gnupg-1.4.9-2.dmg
sudo rudix -i /Volumes/gnupg/gnupg.pkg
hdiutil unmount /Volumes/gnupg

which gpg
gpg --version
man gpg



# GetText

cd ~/Desktop
curl -L -O http://downloads.sourceforge.net/rudix/gettext-0.17-1.dmg
hdiutil mount ~/Desktop/gettext-0.17-1.dmg
sudo rudix -i /Volumes/gettext/gettext.pkg
hdiutil unmount /Volumes/gettext

which gettext
gettext --version
man gettext
open /usr/local/share/locale




# git 
# http://rudix.org

cd ~/Desktop
curl -L -O http://downloads.sourceforge.net/rudix/git-1.5.6.2-1.dmg
hdiutil mount ~/Desktop/git-1.5.6.2-1.dmg
sudo rudix -i /Volumes/git/git.pkg
hdiutil unmount /Volumes/git

which git
git --version
man git

sudo rudix -r git.pkg



# git
# http://git.or.cz

cd ~/Desktop
curl -L -O http://kernel.org/pub/software/scm/git/git-1.6.0.4.tar.gz
tar -xzf git-1.6.0.4.tar.gz
cd git-1.6.0.4
./configure
make
sudo make install

which git
git --version


# git man pages

cd ~/Desktop
curl -L -O http://kernel.org/pub/software/scm/git/git-manpages-1.6.0.4.tar.gz
sudo tar -C /usr/local/share/man -xzf git-manpages-1.6.0.4.tar.gz


git --help

git help add
git help bisect
git help shell
git help git-svn
git help git-daemon

git help gittutorial
git help gitcore-tutorial
git help gitglossary


cd ~/Desktop
mkdir -p ~/Desktop/git-test
cd ~/Desktop/git-test
openport 9418   # cf. http://codesnippets.joyent.com/posts/show/1747
git clone git://git.kernel.org/pub/scm/git/git.git
closeport 9418
open ~/Desktop/git-test
find ~/Desktop/git-test/git -mindepth 1 -maxdepth 1 -ls


# To configure git see:
# - http://dysinger.net/2007/12/30/installing-git-on-mac-os-x-105-leopard/
# - http://arthurkoziel.com/2008/05/02/git-configuration/
# - http://www.bergek.com/wp-content/uploads/2008/09/git-install.sh
# - http://git.or.cz/gitwiki/GitTips


References:

- Git - Fast Version Control System
- Wikipedia: Git
- Rudix
- Install git on Mac OS X 10.4 (expat, asciidoc)
- Installing GIT on Mac OS X 10.5 Leopard (GPG, GetText)
- Compiling Git and git-svn on OSX Tiger (git-svn, Perl)
- Getting git-svn working on the Mac
- Git vs. Mac HFS+ filesystem (UFS & git)
- git-osx-installer
- Git Configuration (on Mac OS X)
- GitTips
- Git User's Manual
- Tag: git
- Git Quick Reference
- Git Guide
- Git Internals: Source code control and beyond
- PeepCode Git screencast
- git hosting with Leopard
- Hosting Git repositories, The Easy (and Secure) Way
- The Git Community Book
- Setting up Git on OSX
- Git and Binaries
- Git cheat sheet
- Setting up a new remote git repository
- Sharing git repositories via OS X's built-in web sharing
- GitHub Tips: Removing a Remote Branch
- Using git in the Finder
- GitX - a git GUI for Mac OS X

Copying JUST mp3 files

I wanted to copy just the mp3 files from my iTunes to a backup folder.
First I made a list of all mp3 files, including the full path, in a text file.
Then I went through that file, deleting any files I didn't want backed up.
Then I used rsync to make the backup.

I went through this process to ensure that I only backed up the files I wanted backed up, and no others.

Substitute your paths and fi