Never been to CodeSnippets before?

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!)

Strip html in ruby

def h(string)
  string.gsub(/<\/?[^>]*>/, "")
end

Get first 100 followers for twitter user and export to timestamped csv

// description of your code here

#!/usr/bin/env ruby

require 'rubygems'
require 'net/http'
require 'rexml/document'
require 'fastercsv'

def get_followers(screen_name)
  url = "http://twitter.com/statuses/friends/#{screen_name}.xml"
  file = "#{screen_name}-dump#{Time.now}.csv"
  i = 0
  result = REXML::Document.new(Net::HTTP.get URI.parse(url))
  
  csv_data = FasterCSV.open(file,"w") do |csv|
    csv << [
      'Name',
      'Screen Name',
      'Location',
      'Description',
      'Friends Count',
      'Followers Count',
      'Updates',
      'URL',
      'Latest Tweet'
    ]
    result.elements.each('users/user') do |r|
      
      puts i += 1 
      csv << [
        r.elements['name'].text,
        r.elements['screen_name'].text,
        r.elements['location'].text,
        r.elements['description'].text,
        r.elements['friends_count'].text,
        r.elements['followers_count'].text,
        r.elements['statuses_count'].text,
        r.elements['url'].text
      ]

    end

  end
  
  return result.elements.count


end


ruby xml => array using hpricot

// description of your code here
this code takes a chunk of xml representing a recordset pulled from a database by a website
and convert it into a ruby array
require 'rubygems'
require 'hpricot'

xml = %{ 
<query>  
<status>
  <id>1</id>
  <created_at>a date</created_at>
  <text>some text</text>
</status> 
<status>
  <id>2</id>
  <created_at>a date 2</created_at>
  <text>some text 1</text>
</status> 
<status>
  <id>3</id>
  <created_at>a date 3</created_at>
  <text>some text 2</text>
</status> 
</query>
}
          
record = Array.new
recordset = Array.new

doc = Hpricot::XML(xml)


# add a row with column names       
# for beginners: notice that :query and :status match the xml structure
names = (doc/:query/:status)[0] 
# names is an Array that contains sub part of the XML (between <status></status>)  
names.each_child do
   |e|  
   if e.innerHTML != nil then   # => because carriage return between <tag></tag> are considered elements too
     # strange hpricot deos not provide a method to get the tag name
     # or i cant read the doc ??
     tag = e.to_s.split('<')[1].split('>')[0]
     record << tag
   end
end   
recordset << record
record = []

# add rows with data
(doc/:query/:status).each do |status|   
  status.each_child do
     |e|  
     if e.innerHTML != nil then
       record <<  e.innerHTML
     end
  end   
 recordset << record
 record = []
end     

recordset.each { |r| p r}      

Log a backtrace in rails

If you're in a tough spot, debugging-wise, in your rails app, you can log your entire backtrace to see who called whom. Just put this snippet in the troublesome spot:

      begin
        raise "boom"
      rescue => detail
        RAILS_DEFAULT_LOGGER.info detail.backtrace.join("\n")
      end

Converting FileColumn store versions from old format to new format (/x) to (/0000/000x)

As of somewhen, the file_column rails plugin changed its storage layout and it doesn't seem to provide any way to migrate. Here's a simple snippet that'll do it.

Start an irb session in the directory where your file_column stores its files. By default that's RAILS_ROOT/public. In irb, run the following:

Dir['*/*/*'].grep(%r{[^/]+/[^/]+/\d+}).map { |s| [s.sub(/\d+$/, ''), $&.to_i] }\
  .map { |s, n| ["#{s}#{n}", (d = "#{s}%04d" % (n / 10000)), "#{d}/%04d" % (n % 10000)] }\
  .each { |f, d, t| `mkdir -p #{d} && mv #{f} #{t}` }


Or, as a migration

class UpgradeFileColumns < ActiveRecord::Migration
  def self.up
    # note I use a custom store path here
    Dir.chdir("#{RAILS_ROOT}/public/files")
    Dir['*/*/*'].grep(%r{[^/]+/[^/]+/\d+}).map { |s| [s.sub(/\d+$/, ''), $&.to_i] }\
      .map { |s, n| ["#{s}#{n}", (d = "#{s}%04d" % (n / 10000)), "#{d}/%04d" % (n % 10000)] }\
      .each { |f, d, t| `mkdir -p #{d} && mv #{f} #{t}` }
  end

  def self.down
  end
end


Reset your itunes library xml

Resets playcounts to 1
Useful when moving libraries from other machines, I guess

sudo gem install plist
./script_name "path/to/itunes_library.xml"

It'll make a path/to/itunes_library.xml.mod - check it, verify it, then swap it with the real one at your own risk!

#!/usr/bin/env ruby
require 'rubygems'
require 'plist'

filename = ARGV[0]
r = Plist::parse_xml(filename)

r["Tracks"].each { |track| track[1]["Play Count"] = 1 if track[1].has_key?("Play Count") }

r.save_plist("#{filename}.mod")

Ruby link_button_to

A helper for a link_button_to.

def link_button_to(name, options = {}, html_options = {})        
    url = url_for(options)          
    html_options["onclick"] = "javascript:document.location.href='#{url}'; return false;"
    html_options.merge!("type" => "button", "value" => name)        
    tag("input", html_options)    
end


Usage: <%= link_button_to "Edit", url_for(:action=>"edit"), :class=>"my_custom_class" -%>

Friendlier Error Messages in Rails

// Just modify your error_messages_for in your views...

<%= error_messages_for :order, :header_message => "Please Try Again!", :message => "We had some problems saving your information:" %>       

Export to Excel

Controller
class PersonController < ApplicationController
  def export
    headers['Content-Type'] = "application/vnd.ms-excel"
    headers['Content-Disposition'] = 'attachment; filename="report.xls"'
    headers['Cache-Control'] = ''
    @person = People.find(:all)
  end
end


View (link to export)
<%= link_to "Export as Excel", export_person_url %>


View (Export)
#Render partial so your Layout wont be sent to the spreadsheet
<%= render :partial => 'report' %>


Partial
<table border="1">
  <tr>
    <th>Name</th>
  </tr>
  <% @person.each do |p| %>
    <tr>
      <td><%= p.name %></td>
    <% end %>
  </tr>
</table>

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',
	}