in rjs this is one way to reference an element by class within an element by id
1 # $$('#comments-11 .author') 2 page.select("##{@comment.dom_id} .author").first.visual_effect :highlight
Language: Ruby / Tags: rjs / Posted by: kbarker / On: April 25th, 2007
Grep with globs alias for zsh
1 alias grep='grep --with-filename --context=1 --color --line-number '1 grep whatever **/*.rbLanguage: Shell/Scripting / Tags: zsh / Posted by: spicycode / On: April 24th, 2007
zsh/bash keyboard shortcuts
1 Line Navigation: 2 Beginning of Line 3 ⁃ control + a 4 End of Line 5 ⁃ control + e 6 Move back a character 7 ⁃ control + b 8 Move forward a character 9 ⁃ control + f 10 Move one word backward 11 ⁃ escape + b 12 Move forward one word 13 ⁃ escape + f 14 Line Editing: 15 Delete the word before the cursor 16 ⁃ control + w 17 Swap the last two characters before the cursor 18 ⁃ control + t 19 Swap the last two words before the cursor 20 ⁃ escape + t 21 Erase/Yank the word before the cursor 22 ⁃ control + w 23 Paste in front of cursor 24 ⁃ control + y 25 Clear line after the cursor 26 ⁃ control + k 27 Clear line before the cursor 28 ⁃ control + u 29 History: 30 Search through previously used commands 31 ⁃ control + r
Language: Shell/Scripting / Tags: zsh, bash / Posted by: spicycode / On: April 6th, 2007
VIM Tips
Source: http://www.cs.utk.edu/~cjohnson/computing/vim_tips.txt
1 gk, gj - Move up or down one screen line. (Helpful if lines wrap.) 2 3 ga - Display ASCII, hex and octal value of character under cursor. 4 Helpful to search/replace control characters. For example, 5 /<C-v>x1a will search for Control-Z (^Z). (<C-v> is not literal, 6 it means hit Control and v at the same time.) 7 8 gd - Jump to declaration of local variable in a C program. 9 This doesn't seem to work for multiple declarations on one line. 10 ge - Move to end of previous word. 11 gE - Same thing, but words are considered separated by whitespace. 12 W - Go to beginning of next word after whitespace. 13 B - Go to character after closest whitespace left of cursor. 14 E - Go to character before closest whitespace right of cursor. 15 '. - Jumps to last modified line. 16 `. - Jumps to last modified position. 17 18 ; - Repeat last character search (f,F,t,T). 19 , - Repeat last character search in the other direction. 20 21 C-x C-f - Complete filename under cursor 22 23 g <C-g> - Display byte, word, line, etc. cursor is on. 24 <count>go - Go to count byte. 25 26 <C-x> - Decrements first number after the cursor. 27 <C-a> - Increments first number after the cursor. 28 29 read !... - Inserts standard output of shell command. 30 31 <C-b> - Moves cursor to beginning of command-line. 32 <C-e> - Moves cursor to end of command-line. 33 <C-w> - Deletes word before cursor on command-line. 34 <C-u> - Wipes command-line clean. 35 [I - Grep current buffer for word under cursor. 36 37 vi *.txt - Open a series of files and replace all 38 argdo %s/pat/rep/gc | wn occurrences of pat with rep. 39 40 set shortmess=a Outlaws "Hit ENTER to continue" prompts.
Language: Shell/Scripting / Tags: vi, vim / Posted by: spicycode / On: April 6th, 2007
Intercepting activerecord attributes
Source: http://smartic.us/2007/3/15/intercepting-activerecord-attributes
So, you wrote a Rails application to track Marathon events. In a sudden change of heart, you pick up your company and move it from the United States to Germany. Why rewrite your app to handle metric distances? Rails provides a solution: write_attribute and read_attribute. For more information, you can refer to the official documentation.1 class Marathon < ActiveRecord::Base 2 def distance=(meters) 3 write_attribute(:distance, meters * 1609.344) 4 end 5 6 def distance 7 read_attribute(:distance) / 0.000621371192 8 end 9 end
Language: Ruby / Tags: rails, activerecord / Posted by: spicycode / On: March 18th, 2007
Production data loading with Capistrano
Source: http://push.cx/2007/capistrano-task-to-load-production-data
I was working on a migration that had a decent chance of messing up my database and wanted assurance it would work with production data, not just my fixtures. Building on Bojan Mihelac's code to download files, I wrote a Capistrano task to load the production database into my local database. And then capistrano 1.4.0 was released with a built-in get method for downloading files. So if you have 1.4.0, you can just throw away that whole function.1 # Get file remote_path from FIRST server targetted by 2 # the current task and transfer it to local machine as path, SFTP required 3 # http://source.mihelac.org/articles/2007/01/11/capistrano-get-method-download-files-from-server 4 def actor.get(remote_path, path, options = {}) 5 execute_on_servers(options) do |servers| 6 self.sessions[servers.first].sftp.connect do |tsftp| 7 logger.info "Get #{remote_path} to #{path}" 8 tsftp.get_file remote_path, path 9 end 10 end 11 end
1 desc "Load production data into development database" 2 task :load_production_data, :roles => :db, :only => { :primary => true } do 3 require 'yaml' 4 5 database = YAML::load_file('config/database.yml') 6 7 filename = "dump.#{Time.now.strftime '%Y-%m-%d_%H:%M:%S'}.sql" 8 on_rollback { delete "/tmp/#{filename}" } 9 10 run "mysqldump -u #{database['production']['username']} –password=#{database['production']['password']} #{database['production']['database']} > /tmp/#{filename}" do |channel, stream, data| 11 puts data 12 end 13 get "/tmp/#{filename}", filename 14 exec "/tmp/#{filename}" 15 exec "mysql -u #{database['development']['username']} –password=#{database['development']['password']} #{database['development']['database']} < #{filename}; rm -f #{filename}" 16 end
Language: Ruby / Tags: capistrano, rails, activerecord / Posted by: spicycode / On: March 18th, 2007
Managing Memcache with Capistrano
Source: http://blog.caboo.se/articles/2007/2/18/bust-a-cap-in-dat-ass
Capistrano rocks for deployment. If you haven’t ever used it to deploy an app, you’re seriously missing out. There’s a lot of good recipes floating around online and this stuff changes so often that there’s probably something out there that’s better. However I figured I’d share how I’m currently managing our memcache daemons at work. memcached, rails wtf?We’re using defunkt’s cache_fu plugin right now to cache models in our system. It’s pretty straightforward to use; an acts_as class method, and a config/memcached.yml file. The memcached.yml file lets you provide one or more servers that the memcache clients can connect to. Unfortunately there’s no centralized way to manage those memcache daemons on your deploy hosts. With our good friend cap, some ruby, and a little time invested we can roll our own solution. Whatcha Want?
The requirements for this task are dead simple.
- use cap to get out to the remote hosts
- the memcache daemon list comes from cache_fu’s yml file
- write a script to start, stop, restart, get the status of, and commit mass genocide against(I want all processes kill -9’d right now).
1 #!/usr/bin/env ruby 2 # this goes in your script/ directory 3 # it parses your memcached.yml file and hooks you up w/ some info 4 # it keeps you from having to mess w/ stale memcached daemons for whatever reason. 5 require 'yaml' 6 7 class MemcachedCtl 8 attr_accessor :memcached, :memory, :pids, :servers, :ip_address, :ethernet_device 9 def initialize 10 env = ENV['RAILS_ENV'] || 'development' 11 self.memcached = `which memcached`.chomp 12 self.servers = [ ] 13 self.pids = { } 14 self.ethernet_device = ENV['ETH'] || 'eth0' 15 self.ip_address = get_ip_address || '0.0.0.0' 16 self.memory = '128' 17 18 config = YAML.load_file(File.expand_path(File.dirname(__FILE__) + "/../config/memcached.yml")) 19 self.servers = [ config['defaults']['servers'] ].flatten rescue ['127.0.0.1:11211'] 20 self.servers = [ config[env]['servers'] ].flatten if config[env]['servers'] 21 self.servers.reject! { |server| host,port = server.split(/:/); self.ip_address == host } 22 self.memory = config[env]['memory'] unless config[env]['memory'].nil? 23 24 each_server do |host,port| 25 `ps auwwx | grep memcached | grep '\\-l #{ip_address} \\-p #{port}' | grep -v grep`.split(/\n/).each do |line| 26 self.pids[port] = line.split(/\s+/)[1] 27 end 28 self.pids[port] ||= 'Down' 29 end 30 end 31 32 def execute(cmd) 33 send(cmd) 34 end 35 36 def restart; stop; sleep 1; start; end 37 38 def status 39 each_server { |host,port| puts "Port #{port} -> #{pids[port] =~ /\d+/ ? 'Up' : 'Down'}" } 40 end 41 42 def kill 43 each_server { |host,port| `kill -9 #{pids[port]} > /dev/null 2>&1` if pids[port] =~ /\d+/ } 44 end 45 46 def stop; kill; end 47 48 def start 49 each_server do |host,port| 50 `#{memcached} -d -m #{memory} -l #{ip_address} -p #{port}` 51 STDERR.puts "Try memcached_ctl status" unless $? == 0 52 end 53 end 54 55 protected 56 def each_server(&block) 57 servers.each do |server| 58 host,port = server.split(/:/) 59 yield host, port 60 end 61 end 62 63 def get_ip_address # this works on linux you might have to tweak this on other oses 64 line = `/sbin/ifconfig #{ethernet_device} | grep inet | grep -v inet6`.chomp 65 if line =~ /\s*inet addr:((\d+\.){3}\d+)\s+.*/ 66 self.ip_address = $1 67 end 68 end 69 end 70 ########################################################################### 71 cmd = ARGV.shift 72 unless cmd.nil? 73 MemcachedCtl.new.execute(cmd) 74 end
Get Your Cap On
So I named the script memcached_ctl and added it to my script/ directory in svn and redeployed. Now I can start poppin caps in our memcache daemons. If I throw the following code at the bottom of my config/deploy.rb I can see what’s up with my memcache daemons on my production hosts. If I were smart/motivated I’d make a gem and let you good people include these tasks, you know like you should be doing for mongrel_cluster.1 # ==================================== 2 # Memcached Server TASKS 3 # ==================================== 4 %w(start stop restart kill status).each do |cmd| 5 desc "#{cmd} your memcached servers" 6 task "memcached_#{cmd}".to_sym, :roles => :app do 7 run "RAILS_ENV=production #{ruby} #{current_path}/script/memcached_ctl #{cmd}" 8 end 9 end
Language: Ruby / Tags: rails, capistrano, memcache, caching / Posted by: spicycode / On: March 18th, 2007
Automatically tagging releases with capistrano
Source: http://blog.teksol.info/articles/2006/10/20/automatically-tagging-your-releases-using-capistrano
Even though Capistrano “tags” each release by creating a new folder on the production server(s), it might be interesting to have a historical perspective in your repository anyway. This makes it easier to know exactly what went up for a release. I would like to share the following Capistrano recipe for your pleasure: config/deploy.rb1 require 'uri' 2 task :after_deploy do 3 source = repository 4 dest = URI.parse(repository).merge("../releases/#{File.basename(release_path)}") 5 cmd = "svn copy --revision=#{revision} --quiet --message \"Auto tagging release #{release_path}\" #{source} #{dest}" 6 puts cmd 7 `#{cmd}` 8 end
Language: Ruby / Tags: rails, subversion, capistrano / Posted by: spicycode / On: March 18th, 2007
Backup your production database with capistrano
Source: http://blog.caboo.se/articles/2006/12/28/a-better-capistrano-backup
Say you have a remote server and you want to back up your remote DB to your home machine but you're behind a firewall. Here's my quick solution/hack of the default capistrano backup task. Remotely, it will dump your database to /tmp and bzip2 it. Locally, it will scp the file to your RAILS_ROOT/backups. You need to have all your ssh keys set up for this to work. It probably will fail if you're using a gateway.1 role :db, "caboo.se", :primary => true 2 set :user, "bananas" 3 4 desc "Backup the database" 5 task :backup, :roles => :db, :only => { :primary => true } do 6 filename = "/tmp/#{application}.dump.#{Time.now.to_f}.sql.bz2" 7 8 on_rollback { delete filename } 9 run "mysqldump -u root -p mephisto_production | bzip2 -c > #{filename}" do |ch, stream, out| 10 ch.send_data "assword\n" if out =~ /^Enter password:/ 11 # set this to your db password.. yuk! 12 end 13 `rsync #{user}@#{roles[:db][0].host}:#{filename} #{File.dirname(__FILE__)}/../backups/` 14 delete filename 15 end
Language: Ruby / Tags: rails, capistrano, backup / Posted by: spicycode / On: March 18th, 2007
Manage Gems within Capistrano
1 require 'capistrano' 2 # Installs within Capistrano as the plugin _gem_. 3 # Prefix all calls to the library with <tt>gem.</tt> 4 # Manages installing gems and versioned gems. 5 module GemInstaller 6 7 # Default install command 8 # 9 # * doesn't install documentation 10 # * installs all required dependencies automatically. 11 # 12 GEM_INSTALL="gem install -y --no-rdoc" 13 14 # Upgrade the *gem* system to the latest version. Runs via *sudo* 15 def update_system 16 sudo "gem update --system" 17 end 18 19 # Updates all the installed gems to the latest version. Runs via *sudo*. 20 # Don't use this command if any of the gems require a version selection. 21 def upgrade 22 sudo "gem update --no-rdoc" 23 end 24 25 # Removes old versions of gems from installation area. 26 def cleanup 27 sudo "gem cleanup" 28 end 29 30 # Installs the gems detailed in +packages+, selecting version +version+ if 31 # specified. 32 # 33 # +packages+ can be a single string or an array of strings. 34 # 35 def install(packages, version=nil) 36 sudo "#{GEM_INSTALL} #{if version then '-v '+version.to_s end} #{packages.to_a.join(' ')}" 37 end 38 39 # Auto selects a gem from a list and installs it. 40 # 41 # *gem* has no mechanism on the command line of disambiguating builds for 42 # different platforms, and instead asks the user. This method has the necessary 43 # conversation to select the +version+ relevant to +platform+ (or the one nearest 44 # the top of the list if you don't specify +version+). 45 def select(package, version=nil, platform='ruby') 46 selections={} 47 cmd="#{GEM_INSTALL} #{if version then '-v '+version.to_s end} #{package}" 48 sudo cmd do |channel, stream, data| 49 data.each_line do | line | 50 case line 51 when /\s(\d+).*\(#{platform}\)/ 52 if selections[channel[:host]].nil? 53 selections[channel[:host]]=$1.dup+"\n" 54 logger.info "Selecting #$&", "#{stream} :: #{channel[:host]}" 55 end 56 when /\s\d+\./ 57 # Discard other selections from data stream 58 when /^>/ 59 channel.send_data selections[channel[:host]] 60 logger.debug line, "#{stream} :: #{channel[:host]}" 61 else 62 logger.info line, "#{stream} :: #{channel[:host]}" 63 end 64 end 65 end 66 end 67 68 end
1 Capistrano.plugin :gem, GemInstaller
Language: Ruby / Tags: capistrano, rubygems, rails / Posted by: spicycode / On: March 18th, 2007