keeping things simple (hopefully)
February 14, 2009
Filed under: Uncategorized — Jason @ 2:03 pm

Had some issues installing Nokogiri this morning on my slicehost account running Ubuntu (Hardy 8.04). Every time I tried installing the gem, I would get this :


sudo gem install nokogiri
Building native extensions.  This could take a while...
ERROR:  Error installing nokogiri:
	ERROR: Failed to build gem native extension.

/usr/bin/ruby1.8 extconf.rb install nokogiri
checking for #include

... no
need libxml
*** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of
necessary libraries and/or headers.  Check the mkmf.log file for more
details.  You may need configuration options.

Provided configuration options:
	--with-opt-dir
	--without-opt-dir
	--with-opt-include
	--without-opt-include=${opt-dir}/include
	--with-opt-lib
	--without-opt-lib=${opt-dir}/lib
	--with-make-prog
	--without-make-prog
	--srcdir=.
	--curdir
	--ruby=/usr/bin/ruby1.8

Gem files will remain installed in /usr/lib/ruby/gems/1.8/gems/nokogiri-1.1.1 for inspection.
Results logged to /usr/lib/ruby/gems/1.8/gems/nokogiri-1.1.1/ext/nokogiri/gem_make.out

Solution?

Not sure really, I did all of these, but it wasnt’ until the last one that the gem successfully installed.



sudo aptitude install libxml
sudo aptitude install libxml2
sudo aptitude install libxml-dev
sudo aptitude install libxml2-dev
sudo aptitude install libxslt
sudo aptitude install libxslt-dev

And that’s it. After that, the gem installed just fine.

February 13, 2009
Filed under: Uncategorized — Jason @ 10:13 pm
December 16, 2008
Filed under: Ruby — Jason @ 3:57 pm

Some scraping code I did for fun last night. I used Nokogiri and Ruby to scrape this site for the names and photos. Take a look at the code if you want to mess around with it.

I wrote this is code b/c I didn’t want to click through the 100 pages of the top 100 movie characters site. I mean, it’s like 100 clicks. I just wanted to see the name and the pictures. The following are the results.

1. Tyler Durden

2. Darth Vader

3. The Joker

4. Han Solo

5. Dr. Hannibal Lecter

6. Indiana Jones

7. The Dude

8. Captain Jack Sparrow

9. Ellen Ripley

10. Vito Corleone

11. James Bond

12. John McClane

13. Gollum

14. The Terminator

15. Ferris Bueller

16. Neo

17. Hans Gruber

18. Travis Bickle

19. Jules Winnfield

20. Forrest Gump

21. Michael Corleone

22. Ellis ‘Red’ Redding

23. Harry Callahan

24. Ash

25. Yoda

26. Ron Burgundy

27. Tony Montana

28. Gandalf

29. Daniel Plainview

30. Jigsaw

31. Aragorn

32. Jason Bourne

33. Tequila

34. Rocky Balboa

35. Maximus Decimus Meridius

36. Harry Potter

37. Edward Scissorhands

38. Donnie Darko

39. Marty McFly

40. Patrick Bateman

41. Mary Poppins

42. Alex DeLarge

43. The Man With No Name

44. Peter Venkman

45. Amelie Poulain

46. Anton Chigurh

47. Blade

48. Tony Stark

49. Walter Sobchak

50. Quint

51. Mal Reynolds

52. George Bailey

53. Luke

54. Luke Skywalker

55. Lt. Frank Drebin

56. Juno MacGuff

57. Brick Tamland

58. Rick Blaine

59. Tommy Devito

60. Ace Ventura

61. R.P. McMurphy

62. Mathilda

63. Wall-E

64. Withnail

65. White Goodman

66. The Bride

67. Frank Booth

68. Napolean Dynamite

69. Keyser Soze

70. Atticus Finch

71. Snake Plissken

72. V

73. Jack Torrance

74. E.T

75. Marge Gunderson

76. Dr. Emmett Brown

77. Ed

78. Axel Foley

79. Boba Fett

80. Norman Bates

81. Wolverine

82. Marv

83. Mr Blonde

84. Agent Smith

85. Vincenzo Coccotti

86. Roy Batty

87. Dracula

88. Jessica Rabbit

89. Princess Leia Organa

90. The Wicked Witch Of The West

91. Scarlett O’Hara

92. Randal Graves

93. Martin Q. Blank

94. Buzz Lightyear

95. Freddy Krueger

96. Ethan Edwards

97. Clarice Starling

98. Charles Foster Kane

99. HAL-9000

100. Martin Riggs

September 23, 2008
Filed under: Rails, Ruby — Jason @ 4:49 am

I recently needed to divide a signup form into to 2 separate pages in order to neatly organize the flow. I went through a bunch of different techniques before I came up with a solution I was happy with. Below I outline each of those techniques.

My initial thought was to simply save this data into a cookie. I determined this to be a bad idea b/c although unlikely, the data might exceed 4KB, which is the limit for cookies as far as I know (anyone know where this comes from?). I didn’t want to run into any possible cookie overflow errors.

The second idea I had was to save the record to the database but keep the record in an inactivated state. This solution annoyed me because, if a user abandoned the process, there would be orphaned records. This would require some sort of cron script to clean it up–more work than I am willing to do. Also, I would have to save data without going through all the validations, which didn’t smell right.

My third solution was to serialize the parameters as YAML and store them in hidden text area boxes on the page. Having to marshal the params hash to and from YAML is somewhat overkill. Additionally, this method started to see some breakage once the there were validation errors on the second submission form. Since I was passing YAML to the next page, the serialization of the parameters nested the data. For example, a simple hash serialized in YAML looks like this:


--- !map:HashWithIndifferentAccess
name: Jason
address: !map:HashWithIndifferentAccess
  city: New York
  zip: "10009"
  street1: 123 Main Street
  street2: Apartment 8
  state: New York
email: foo@bar.com

After a few validation errors it would look like this:


--- |+
 --- |
  --- !map:HashWithIndifferentAccess
  name: Jason
  address: !map:HashWithIndifferentAccess
    city: New York
    zip: "10009"
    street1: 123 Main Street
    street2: Apartment 8
    state: New York
  email: foo@bar.com

My final solution, and probably the simplest, was to take the entire params hash and turn that into hidden fields. So I wrote this little helper function to handle that.


  def params_to_hidden_fields(params, scope=[], depth=0, options={})
    # Reject parameters you don't want to stay persistent
    reject_list = %w(action controller authenticity_token)
    reject_list = reject_list + options[:reject] if options[:reject]
    params = params.reject{|key, value| reject_list.include?(key)}
    puts reject_list

    #The final output to return
    output = ""

    # Cycle through each object in the hash
    params.each do |key, value|
      # If the value is a Hash, recursively call this function on that Hash
      # otherwise turn it into a hidden field
      output << if value.class == HashWithIndifferentAccess
        "#{params_to_hidden_fields(value, scope + [key], depth+1, options)}"
      else
        # This conditional sets the scope for the hidden fields.  Nested objects in
        # Rails are displayed like this:
        #    <input type="hidden" name="main_object[:subj_object][:key]" id="main_object_subj_object_key" value="value" />
        # so we need keep track of the parent calls
        name = if scope.empty?
          "#{key}"
        else
          scope.first.to_s + scope[1..scope.length].inject(""){|sum, crumb| "#{sum}[#{crumb}]" } + "[#{key}]"
        end

        # Same as technique as above but for ID, the Rails way
        id = if scope.empty?
          "#{key}"
        else
          scope.first.to_s + scope[1..scope.length].inject(""){|sum, crumb| "#{sum}_#{crumb}" } + "_#{key}"
        end

        # Basic output
        "<input type=\"hidden\" name=\"#{h name}\" id=\"#{h id}\" value=\"#{h value}\" />\n"
      end
    end
    output
  end

I’ve commented the code, but here’s an explanation of the parameters for the function

PARAMETERS

  • params: A Hash in which to turn into hidden fields
  • scope: An Array for handling nested hashes within the recursion
  • depth: An Integer for counting the depth of nesting. Can be used for formatting purposes
  • options: A Hash of options. Right now it only handles the :reject option which is an array of keys in which to ignore.

This works great. The only issues I had were nested hashes and the parameters for action, controller, authenticity_token. I handled the nesting issue by recursively handling any values that were hashes. I handled the unwanted param values by stripping them out.

This is the output of the params_to_hidden_fields method with the same hash as the YAML above.


<input type="hidden" name="name" id="name" value="Jason" />
<input type="hidden" name="address[city]" id="address_city" value="New York" />
<input type="hidden" name="address[zip]" id="address_zip" value="10009" />
<input type="hidden" name="address[street1]" id="address_street1" value="123 Main Street" />
<input type="hidden" name="address[street2]" id="address_street2" value="Apartment 8" />
<input type="hidden" name="address[state]" id="address_state" value="New York" />
<input type="hidden" name="email" id="email" value="foo@bar.com" />

I would love to hear any thoughts or questions on this approach. Also, if you have any ideas feel free to post them up.

August 22, 2008
Filed under: Ruby — Jason @ 4:15 pm

When trying to start out with using scRubyt, I started immediately got slammed by a stupid gem dependency error. This happened to me a few times a while back and I forgot how to fix it. I remember one time I had to uninstall a particular gem version in order to get it to work and realized another app needed. Ugghh.

Anyway, the gist of the problem is this: if you already have RubyInline installed and it’s greater than version 3.6.3, you’re gonna get this error:

Gem::Exception: can't activate RubyInline (= 3.6.3), already activated RubyInline-3.7.0]

or something similar.

After some google-fooing I came across this post where Ryan Davis gives a clue on what to do. The code snippet below works great with both versions of RubyInline installed. If you don’t even have RubyInline 3.6.3 installed then just install via this command sudo gem install RubyInline -v 3.6.3

Then remove the current require statements


require 'rubygems'
require 'scrubyt'

and replace with


require 'rubygems'
gem 'RubyInline', '= 3.6.3'
require 'scrubyt'

Good luck scraping!

May 22, 2008
Filed under: Thought Provoking — Jason @ 10:43 pm

Yesterday I stumbled across one of the most moving lectures I’ve ever seen. Randy Pausch, a professor of Computer Science at Caregie Mellon, was diagnosed with pancreatic cancer and was told he only had 3 to 6 months to live. This lecture follows that diagnosis.

I would be doing a disservice to this man by trying to sum up what he departed onto his audience so I encourage you to watch it. It’s an hour and twenty minutes long, but just watch the first 5 minutes… I’m sure you’ll stay for the whole thing.

April 23, 2008
Filed under: BeenVerified — Jason @ 5:37 pm

Finally after a few months of nonstop, round-the-clock coding we’ve relaunched BeenVerified. Check out the BeenVerified Blog for details. Oh, and check out the new look and feel of BeenVerified as well…

January 10, 2008
Filed under: Funny, Thought Provoking — Jason @ 1:29 am

Browsing around Facebook and LinkedIn today I noticed that there are some people that just have way too many friends. How many people can you possibly be friends with… for real? And then a funny thought came to my mind:

“The more friends you have within online social networks and mmorpgs, the less likely you are to have real friends in the real world.”

I name this The Law of Inverse Online Friends. (If anyone can think of a better name, please share it with me)

Now, I know people may get upset with that law because of 2 things: First, that is definitley not a tautology (in the logical meaning) and second, who am I to say what a ‘real’ friend is? If you are one of those people, then relax, you are exempt from this law. Just take the stick out of your ass and get a life :)

[update:  Since the posting of this article, I have quadrupled my friends in facebook... ]

December 15, 2007
Filed under: Uncategorized — Jason @ 8:49 pm

This was a good post in getting GMail set up in Rails. But if you follow it exactly you’ll run into a a hiccup if you’re running Rails 2.0.

Rails 2.0 has depricated the ActionMailer::Base.server_settings= function and opted for the more aptly named smtp_settings. So just use this for your settings and you’ll be okay.


ActionMailer::Base.delivery_method = :smtp
ActionMailer::Base.smtp_settings = {
  :address => "smtp.gmail.com",
  :port => 587,
  :domain => "mycompany.com",
  :authentication => :plain,
  :user_name => "username",
  :password => "password"
}

Also don’t forget, your username will be your FULL email address (e.g. funkydude@mycompany.com)

Filed under: Uncategorized — Jason @ 8:47 pm

Needed something to generate random numeric strings that were 9 characters long


def random_numeric_string
	length = 1000000000
	(rand(length)+(length)).to_s[1..9]
end

If anyone has a better way, please let me know.

Next Page »