Archive for July, 2008

How to add additional routes to restful rails controllers

In your controller file

  def test_email
	...#content here
  end

In your routes.rb file

map.resources :flowers, :collection => { :test_email => :get}

Using paperclip for image attachments in rails

Advantage to using paperclip: you don’t have to create separate model for images and then create a join relationship like with attachment_fu

What you’ll need:
- the paperclip plugin: run the following from your terminal in your rail’s project root folder:

script/plugin install git://github.com/thoughtbot/paperclip.git

Useful tutorials:
- Paperclip project page
- Paperclip original tutorial
- Paperclip more useful tutorial

How to:

1. Create a new migration file: script/generate migration add_images_to_flowers and rake db:migrate

class AddImageToFlowers < ActiveRecord::Migration
  def self.up
    add_column :flowers, :image_file_name, :string
    add_column :flowers, :image_content_type, :string
    add_column :flowers, :image_file_size, :integer
  end

  def self.down
    remove_column :flowers, :image_file_size
    remove_column :flowers, :image_content_type
    remove_column :flowers, :image_file_name
  end
end

2. Change your form to use multipart. (I don’t see why http just doesn’t default to multipart with its forms. It’s seems a little ridiculous to have to add multi-part)

	<% form_for [:admin, @flower], :html => { :multipart => true } do |f| %> #if you put your new/edit under admin/flowers_controller.rb
	or
	<% form_for @flower, :html => { :multipart => true } do |f| %>

3. Add the file field to the form

<%= f.label :image %>
<%= f.file_field :image %> #as you can see if uses the pre-name to the above migration fields 'image'. This is one smart plugin.

4. In your model add the following

class Flower < ActiveRecord::Base

  # Paperclip
  has_attached_file :image,
    :styles => {
      :thumb=> "100x100#",
      :small  => "150x150>",
      :medium => "300x300>" }

end

5. Now try uploading an image and check your database to see that it got added. You’ll also see that in your public view it added a folder called images (plural of image) with a subfolder defined by the id of the post, and with more subfolders for the different sizes of your image as you specified in the above model (thumb, small, medium).

Picture 1.png

Pretty darn cool, if you ask me.

This is a great tool for simple single image adding to a model.

6. Add it to your views. This is pretty easy just call the following:

<%= image_tag @flower.image.url %>
<%= image_tag @flower.image.url(:thumb) %>
<%= image_tag @flower.image.url(:small) %>
<%= image_tag @flower.image.url(:medium) %>

I think you get the idea.

Reagan Quotes

reagan.jpg

“We don’t celebrate ‘dependence (on the government) day’ July 4th, we celebrate Independence Day!”

“I can’t help thinking, while much of the 20th century saw the rise of the federal government, the 21st Century will be the century of the states. I have always believed that America is strongest and freest and happiest when it is truest to the wisdom of its founders.”

“Too often, character assassination has replaced debate in principle in Washington, D.C. Destroy someone’s reputation and you don’t have to talk about what he stands for.”

“One thing our Founding Fathers could not foresee…they were farmers, professional men, businessmen giving of their time and effort to a dream and an idea that became a country…was (today) a nation governed by professional politicians who had a vested interest in getting re-elected. They probably envisioned a fellow serving a couple of hitches and then looking eagerly forward to getting back to the farm.”

“The image of George Washington kneeling in prayer in the snow is one of the most famous in American history. He personified a people who knew it was not enough to depend on their own courage and goodness, they must also seek help from God, their Father and Preserver.”

“We make a living by what we get, we make a life by what we give.”

“How can we not believe in the greatness of America? How can we not do what is right and needed to preserve this last best hope of man on earth? After all our struggles to restore America, to revive confidence in our country, hope for our future - after all our hard won victories earned through the patience and courage of every citizen- we cannot, must not and will not turn back. We will finish our job. How could we do less? We’re Americans.”

Automate mysql backup with amazon s3

This tutorial is awesome for automating mysql backup with amazon s3. Plus, it is from a slicehost user - eve n more awesomeness.

RubyScript2Exe - turning your ruby script/app into a .exe on windows

So I created a useful little ruby script on my windows machine, and wanted to turn it into a .exe script. This way I could run it under my windows system scheduler once a day.

I followed this tutorial for setting up your ruby script as a .exe on windows.

RubyScript2Exe docs

Useful scripts with mechanize, hpricot, and htmldoc

Here are some useful scripts with mechanize, hpricot, and htmldoc

First, install mechanize and hpricot and htmldoc (pdfs)

gem install hpricot
gem install mechanize
gem install htmldoc

Save web page as pdf with mechanize and htmldoc

require 'rubygems'
require 'mechanize'
require 'htmldoc'

agent = WWW::Mechanize.new
agent.user_agent_alias = 'Mac FireFox'
agent.redirect_ok = true

page = agent.get('http://scottmotte.com/archive')
pdf = PDF::HTMLDoc.new

pdf.set_option :outfile, "~/Desktop/outfile.pdf"
pdf.set_option :bodycolor, :white
pdf.set_option :links, true

pdf << page.body

if pdf.generate
  puts "Hallelujah"
else
  puts 'No Joy'
end

Log into a website with mechanize, save some data with hpricot, and then insert that data into another website

For this one, I wanted to be able to automatically save my stock values each day, and insert them into my personal application where I graph them on a daily basis. I was tired of doing this by hand so I used mechanize and hpricot to automate the process. (I just need to set this up on schedule as a cron task now.)

require 'rubygems'
require 'mechanize'
require 'hpricot'
require 'open-uri'

agent = WWW::Mechanize.new
agent.user_agent_alias = 'Mac FireFox'
agent.redirect_ok = true

## FIRST TIME ##
page = agent.get('http://scottrade.com')

login_form = page.forms.first
login_form.account = '*****your account number*****'
login_form.password = '*****your password*****'
page = agent.submit(login_form)

link = page.links.text("My Account")
page = link.click

doc = Hpricot.parse(page.body)

# positions
positions = (doc/'span#DetailedBalances_lblCashStocksMutFdsCDBonds').inner_html
positions = positions.gsub( "$", '') #strip the dollar sign
positions = positions.gsub( ",", '') #strip the commas

# cash
cash = (doc/'span#DetailedBalances_lblCashTotalMoneyBalance').inner_html
cash = cash.gsub( "$", '')
cash = cash.gsub( ",", '')

# total
total = (doc/'span#DetailedBalances_lblCashTotalAcctValue').inner_html
total = total.gsub("$", '')
total = total.gsub(",", '')

page = agent.get('/Default.aspx?log=off') #log out

# now insert that content
page = agent.get('http://app.scottmotte.com')

login_form = page.forms.first
login_form.login = '***my username***'
login_form.password = '***my password***'
page = agent.submit(login_form)

page = agent.get('/daily_stock_values/new')

f = page.forms.first
f.set_fields( 'fund_value[positions]' => positions)
f.set_fields( 'fund_value[cash]' => cash)
f.set_fields( 'fund_value[total]' => total)
# the date field gets inserted automatically using rails created_at method. The app is built in rails.
page = agent.submit(f)

page = agent.get('/logout')

Get an image from a website and save it locally

require 'rubygems'
require 'mechanize'
require 'hpricot'
require 'open-uri'
require 'uri'

@agent = WWW::Mechanize.new
@agent.user_agent_alias = 'Mac Safari'
@agent.redirect_ok = true
page = @agent.get("http://intype.info/home/trailers/alpha_3/bg.png")
myStr = page.body
aFile = File.new("mypicture.gif", "wb")
aFile.write(myStr)
aFile.close

Installing Ruby on Windows and Setting up Watir on Windows

This is really poorly written and more of a mind dump than anything. Use it at your own risk. I eventually gave up on cygwin. It caused me some headaches. Instead, I did the following:

1. Installed ruby for windows using the one-click installer from ruby-lang.org (for some reason I had to install under the Administrator account on my windows machine)

2. Installed
windows console 2.0
. It beats using the dos command, but it still is poor compared to the *nix command line.

# helpful commands
cd (just like *nix)
dir (similar to ls -al in *nix)

3. Opened up console and typed:

irb
puts 'hello world'
exit

Good, ruby seems to be working.

3. Installed intype as my text editor of choice.

4. Installed watir

gem install watir

5. Then after trying watir, I wasn’t really all that happy with it so I decided to go with using a combination of mechanize and hpricot. See useful scripts with mechanize and hpricot.



Mind dump

1. Install ruby for windows (use the ruby one-click installer from ruby-lang.org) (i just installed to c:\ruby. it will take about 5 minutes to complete the installation. while you’re waiting download intype or your text editor of choice for windows. e-texteditor comes recommended but will cost you $30 bucks.) Don’t do any of this or your cygwin with ruby will not function correctly.

2. Install cygwin (this will emulate *nix-like command terminals. The windows dos command console is a pain to work in and most all the examples you will find online are for *nix)

a. Download the setup.exe from Cygwin.com and then run setup.exe
b. Install in c:\cygwin
c. Install the local package directory to your desktop
d. Install from direct connection
e. Choose an available download site and press next
f. For the Select Packages make sure you do the following:
i. Go to Devel -> ruby, and change ‘Skip’ to 1.8.7 by clicking on the ‘Skip’ on the ruby line (here’s a tutorial with screenshots (but ignore the packages being installed. they won’t apply to you.))
ii. Go to Devel -> and install all the lines that start with gcc by once again clicking on the prospective line’s ‘Skip’
iii. Go to Devel -> make and install by doing the same as above
iv. Go to Devel -> openssl-devel and install by doing the same as above
v. Under Database -> sqlite you might as well do the same since if you run rails one day you’ll want it
vi. Under Net -> openssl install
vii. Under Net -> openssh install
viii. Under Editors -> vim install
ix. Under Editors -> nano install
x. Under Net -> curl install
xi. Under Shells -> rxvts install all of them
xii. Under System -> ping install
xiii. Under Web -> wget install
g. Then click next and wait for everything to download. It will probably take about 10 minutes.

Open up Cygwin and type in the prompt:

irb

puts 'hello world'

exit

As long as that didn’t throw any errors than your ruby is setup correctly. Time to get watir. Wait first we have to install rubygems.

3. Install ruby gems
a. Go to the rubyforge ruby gems installation page and download the latest version as a tgz file. (rubygems-1.2.0.tgz at the time of this writing)
b. Save this file to My computer c:\cygwin\home\user name\sources (you’ll need to create the directory sources)
c. Open up cygwin and do the following

cd ~/sources
tar -pxzf rubygems-1.2.0.tar
cd rubygems-1.2.0
ruby setup.rb

4. Install watir

gem install watir

Scrubyt perks and rules

-It will skip over tbody for xpaths. Don’t include it in your xpath.

# correct
content '//body/table/tr/td

# incorrect
content '//body/table/tbody/tr/td

-It will skip over font[@size=n] but not over just plain font

-extractor.to_xml will output to the xml you specify within the:

extractor = Scrubyt::Extractor.define do
..
end

-extractor.to_text i’m not sure how to work

Scrubyt screen scraping tutorials

I am beginning to use scrubyt gem and in my opinion the documentation and examples are pretty bad. The name isn’t the greatest either. It’s difficult to type so be careful in the following examples. (should have just called it scruby or scrubby or something. the t is annoying.)

**However**, I am starting to understand how scrubyt works, and it really is one heck of an awesome and powerful gem.

I hope the following small scripts and basic tutorial will help speed your learning process for scrubyt.

Install Scrubyt

sudo gem install scrubyt

Create your first scrubyt script
Create a .rb file to test scrubyt. Call it scrubyt_example.rb and save it in your documents/scripts folder or documents/ruby folder or wherever you like.

Edit that file with the following code

require 'rubygems'
require 'scrubyt'

data = Scrubyt::Extractor.define do
  fetch 'http://google.com'
  title '//head/title'
end

data.to_xml.write($stdout, 1)

Test run the file
In your terminal cd to the folder where you saved the scrubyt_example.rb

cd ~/documents/code/ruby

& then run the file with the ruby command in your terminal from inside that folder

ruby scrubyt_example.rb

Ok, way to go, you just learned how to use the xPath (//head/title) to define the part of the website page you wanted. You can get deeper and deeper into the site content by creating just about any xPath you want (i.e. //body/title/table/tr/td).

NOTE: I am using firebug in firefox 3 to view the path to these html elements. You could just as easily view source, but there is a good chance you’ll make a mistake. I recommend using firebug.

Now let’s get a little more complicated by basically creating a for loop with scrubyt.

require 'rubygems'
require 'scrubyt'

extractor = Scrubyt::Extractor.define do
  # go to website
  fetch 'http://scottmotte.com/archive'
  # move down to the ul and call it content and for each ul *do* the following
  content '//body/div/div/div/ul' do
    # grab the content of the li element and call it post
    post '/li'
  end
end
puts extractor.to_xml

This script loops through all the li items on my archive page at http://scottmotte.com/archive

Ok, way to go. Now let’s learn how to login somewhere. This is actually pretty darn easy with scrubyt. We are also going to click a link to change pages, and spit out the url of the page so that we know we have actually changed pages. (Of course, you’ll need to change this to a website you have login access to [just don't try gmail, it uses heavy javascript and so there is another trick to doing that that I haven't tried yet. Scrubyt is not good at handling javascript because www::mechanize is not.]. As well, your fill_textfield names will be different depending on the website. For example, in youtube they are simply ‘username’ and ‘password’. View source or use firebug to find out.)

# example from http://scrubyt.rubyforge.org/files/README.html
require "rubygems"
require "scrubyt"

data = Scrubyt::Extractor.define do

  fetch 'http://www.investors.com/logOffConfirm.aspx?REG=un'
  fill_textfield 'htmUserName', '***your username***'
  fill_textfield 'htmPassword', '***your password***'
  submit

  click_link 'Today In IBD'
  click_link 'Today In IBD'

  click_link 'The Big Picture'

  url "href", :type => :attribute #this part isn't technically correct
end

data.to_xml.write($stdout, 1)

Note: for some reason, I had to do the click_link ‘Today In IBD’ twice. This seems to be a bug or something weird with investors.com. Either way, you might have a similar problem so try doing the click_link twice.

Note 2: the url “href”, :type => :attribute isn’t technically correct, but it will spit out the present url in your terminal. Just don’t use it for production or in a rails app yet. I’m still learning and figuring out how to make this correct.

Top Rails plugins

10 must have rails plugins