11.27.07

Getting an exported heroku project working

Posted in Programming, Ruby, heroku, rails at 6:00 am by Robert Horvick

After exporting a project from heroku to do some local work there were two things I needed to do:

  1.  Create config/database.yml - it is good that this file is not exported.  It contains no details that are useful outside of the heroku environment.  But don’t forget you need it (if you don’t know what to put there - create an empty rails project and grab that one).
  2. create the databases referenced in config/database.yml
  3. Execute “rake db:sessions:create” - this will create a migration that is necessary to enable SQL session storage.
  4. Execute “rake db:migrate” - this will execute all of your migrations as well as the SQL session migration.

After this my project was working.

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

11.26.07

heroku.com + script.aculo.us = broken ajax

Posted in Programming, Ruby, ajax, heroku, rails at 4:55 pm by Robert Horvick

Update: As I expected the guys are heroku turned around a fix very quickly.  I tested autocompletion tonight and it worked perfect.  heroku + script.aculo.us = working like a champ :) 

They say that constructive criticism (e.g. complaints) should occur in a sandwich of positive thoughts.  Generally I think that’s a bunch of PC granola-farming nonsense.  People need to hear what people need to hear.  If I suck - tell me.  If I’m lucky you’ll tell me why.  If I’m really lucky you may offer advice on how to improve.

But knowing that something sucks is the baseline.

But I’m going to break my rule and go with the PC warm-fuzzy approach.

Positive: Heroku kicks ass

Rails site online fast, syntax highlighting editor, backup/restore, nginx, postgres … love it.  I’ve been able to make a lot of progress in this environment (and being able to work on the site from multiple computers is very nice).

Negative: Heroku injects some code into every response

This breaks ajax behaviors by altering partials (and includes prototype.js which breaks script.aculo.us) … in short ajaxy rails is broken.

When I make an ajax request I expect to get back something like:

<ul class="restaurants">

  <li class="restaurant">    <div class="name">rest name</div>

  </li>

  <li class="restaurant">

    <div class="name">O'Charley's</div>

  </li>

  <li class="restaurant">

    <div class="name">Sunday Deal</div>

  </li>

  <li class="restaurant">

    <div class="name">Monday Deal</div>

  </li>

  <li class="restaurant">

    <div class="name">Sunday Cheap</div>

  </li>

</ul>

But what I actually get back is:

<!-- heroku toolbar -->

<script src="http://heroku.com/javascripts/prototype.js” type=”text/javascript”></script>

<script src=”http://heroku.com/javascripts/effects.js” type=”text/javascript”></script>

<script src=”http://heroku.com/toolbar/heroku_toolbar.js” type=”text/javascript”></script>

<link href=”http://heroku.com/toolbar/heroku_toolbar.css” media=”screen” rel=”Stylesheet” type=”text/css” />

<script type=”text/javascript”>HerokuToolbar.html = ‘<div id=”heroku_toolbar”><a href=”http://heroku.com” id=”heroku_logo”></a><a href=”http://edit.kidseatfree.heroku.com/?uri=%2Fdeal%2Fauto_complete_for_restaurant_name” id=”heroku_back_button”></a><a href=”javascript:HerokuToolbar.toggle()” mce_href=”javascript:HerokuToolbar.toggle()” id=”heroku_inspect_button”></a><img id=”heroku_spinner” src=”http://heroku.com/toolbar/images/spinner.gif” style=”display: none”><span id=”heroku_login_info”><a href=”http://heroku.com/myapps”>robert.horvick@gmail.com</a> | <a href=”http://heroku.com/logout”>logout</a></span></div>’</script>

<span class=”heroku_marker heroku_start” style=”display: none”>/mnt/home/userapps/347/app/views/deal/_restaurants.rhtml</span>

<ul class=”restaurants”>

  <li class=”restaurant”>    <div class=”name”>rest name</div>

  </li>

  <li class=”restaurant”>

    <div class=”name”>O’Charley’s</div>

  </li>

  <li class=”restaurant”>

    <div class=”name”>Sunday Deal</div>

  </li>

  <li class=”restaurant”>

    <div class=”name”>Monday Deal</div>

  </li>

  <li class=”restaurant”>

    <div class=”name”>Sunday Cheap</div>

  </li>

</ul>

<span class=”heroku_marker heroku_finish” style=”display: none”></span>

Ah crap.  Now my autocomplete doesn’t render … oh but it gets worse.

Reincluding prototype.js causes the scriptaculous extending of Ajax.Autocompleter to be lost and now autocomplete events don’t fire (in fact FireBug shows an error because Ajax.Autocompleter is not a constructor).

Bug reported.

Positive: The folks at heroku kick ass

I have reported quite a few issues - some bugs, some feature ideas, some random rants about usability or business models.  But in every case these guys have turned around fixes or offered workarounds in a matter of hours. 

The issue I just described - I’m confident that they will be able to work past it quickly or provide some sort of workaround for the specific case of partials.

So there you go.

A feedback sandwich.

Now I’m hungry.

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

11.25.07

A rails form that creates multiple models at once

Posted in MySQL, Programming, Ruby, rails at 6:10 pm by Robert Horvick

I want to create a simple site that allows users to add event, restaurant and location details through an ajax-ish interface.  Ultimately I have a design in mind but to get there I need to be able to submit details of multiple models through a single form (there are about 10 fields over 4 models that will need to be defined).

I wanted to use the action view “form_for”, a single submit and have the submission automatically map the fields to their proper object so that my controller method could look like this (sans error handling):

def create
    if request.post?
@deal = Deal.new(params[:deal])
@deal.Restaurant = Restaurant.new(params[:restaurant])
@deal.Location = Location.new(params[:location])
      @deal.save
    end
  end

Long story short - what you need to do is use the “fields_for” call within the form to get the model information. The form in the view looks like:

<% form_for :deal, :url => { :action => :create } do |form| %>
  <% fields_for :restaurant do |r| %>
Restaurant: <%= r.text_field :name %><br/>
  <% end %>    

  <% fields_for :location do |l| %>
Address 1: <%= l.text_field :address1 %><br/>
Address 2: <%= l.text_field :address2 %><br/>
City: <%= l.text_field :city %><br/>
State: <%= l.text_field :state %><br/>
Zip: <%= l.text_field :zip %><br/>
  <% end %>    

  Details: <%= form.text_area :description, :rows => 3 %>
  <%= submit_tag %>
<% end %>

In this example three models are used - Deal, Restaurant and Location.

The form is based on Deal (since I want the submit to go to Deal::create and I defined two fields_for blocks - one for Restaurant and Location.

The params.inspect output of the form data is:

Parameters: {”restaurant”=>{”name”=>”rest name”}, “deal”=>{”description”=>”Kids can eat whatever they want in under 3 minutes.”}, “commit”=>”Save changes”, “location”=>{”city”=>”some place”, “address1″=>”address one”, “zip”=>”12345″, “address2″=>”", “state”=>”NC”}}

Notice that restaurant, deal and location are all their own hash which can be passed to the new method on the respective models.

Worked like a champ.

Details on the schema is:

    create_table :locations do |t|
      t.column :address1, :string, :limit => 60
      t.column :address2, :string, :limit => 60
      t.column :city, :string, :limit => 40
      t.column :state, :string, :limit => 2
      t.column :zip, :string, :limit => 10
      t.column :phone, :string, :limit => 16
t.column :lng, :string, :limit => 30
      t.column :lat, :string, :limit => 30
      t.column :restaurant_id, :int
    end    

    create_table :restaurants do |t|
      t.column :name, :string, :limit => 60
    end    

    create_table :deals do |t|
      t.column :restaurant_id, :int
      t.column :location_id, :int
      t.column :description, :text
    end

And the models relationships:

class Deal < ActiveRecord::Base
  belongs_to :Restaurant
  belongs_to :Location
...
end    

class Location < ActiveRecord::Base
  belongs_to  :Restaurant
end    

class Restaurant < ActiveRecord::Base
  has_many  :Location
  has_many  :Deal
...
end
[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

11.21.07

Setting data on hidden fields during form submit using AJAX (Google maps geocode example)

Posted in Programming, Ruby, rails at 7:30 pm by Robert Horvick

Using heroku I’m working on a small rails app that needs to integrate with google maps

The Plan 

I want to do is allow a user to provide a location which I will store and later be able to render on a google map. 

Now, to use Google Maps to store location data you want to be using geocodes (i.e. longitude/latitude values).  There are a few reasons for this:

  1. Ultimately adding a marker requires a geocode.
  2. Google limits how many address-to-geocode conversions a site can perform (I’ve seen daily and weekly limits - they were 15,000 and 50,000 respectively [which doesn't add up - but whatever]).
  3. Converting from address to geocode takes a second or longer.  Why make the viewer wait when the information only needs to be gathered once?

So the plan was to do the following:

  1. Accept the data in a standard address form.
  2. Contact the google web service for geocode creation
  3. Cache the geocode with the location record in SQL
  4. Subsequent requests would use the cached record

 Reality Bites 

The problem is that heroku does not allow outgoing connections so I can’t perform #2.  So I need to get the information from the caller without actually making them enter it.  What I came up with was:

  1. Get the data from the user
  2. Perform the geocode lookup in javascript on form submit
  3. Note the geocodes on a pair of hidden form fields
  4. Submit using javascript

Get the data from the user

Let’s get right to it.  This is the form code in the rails view (index.rhtml):

    <%= form_tag( {:controller => “location”, :action => “create”},

                  {’id’ => ‘frmAddress’, ‘method’ => ‘post’, ‘onSubmit’ => ’showAddress(this); return false;’} ) %>

     <p>

        <%= text_field_tag( :address ) %>

        <%= hidden_field_tag( :lat ) %>

        <%= hidden_field_tag( :lng ) %>

        <%= submit_tag(”Go”) %>

      </p>

      <div id=”map_canvas” style=”width: 500px; height: 300px”></div>

    <%= end_form_tag %>

Time for a little breakdown:

    <%= form_tag( {:controller => “location”, :action => “create”},
                  {’id’ => ‘frmAddress’, ‘method’ => ‘post’, ‘onSubmit’ => ’showAddress(this); return false;’} ) %>
 

We are submitting the form to the location controller’s “create” action.  We will submit using the post method.  The ‘id’ isn’t needed in this example - ignore it.  When the submit button is clicked we will call the showAddress javascript function and pass the form as the parameter.  So what’s with return false?

OMG - this is so important.  I can NOT stress this enough.

When submitting a form via javascript you must (MUST) have this return false.  If you don’t the form will submit twice - once via the javascript submit and once via the normal form post.

Say it with me - if javascript is submitting the form I will return false.  I will return false!!!

By the way - Agile Web Development With Rails had this information on 537 (form_remote_tag and remote_form_for documentation).       

        <%= hidden_field_tag( :lat ) %>
        <%= hidden_field_tag( :lng ) %>

These are the hidden fields for the longitude and latitude.

Everything else is plain-jane form stuff.

Lookup, record, submit

function showAddress(frm) {   
      if (geocoder) {
        geocoder.getLatLng(
          frm.address.value,
          function(point) {
            if (!point) {
              alert(address + ” not found”);
            } else {
              frm.lat.value = point.lat();
              frm.lng.value = point.lng();
              frm.submit();
            }
          }
        );
      }
 

This is mostly the stock google sample code except that I am storing away the latitude and longitude in the hidden form fields and I changed the function to take the form instead of the address value.

Also I submitted the form.

Now in the controller’s create method I can access the parameters like:

  def create
    @lat = params[:lat]
    @lng = params[:lng]
    @address = params[:address]
  end
 

And display them in the view like:

  Long: <%= @lng %><br/>
  Lat: <%= @lat %><br/>
  Address: <%= @address %><br/>
 

So it’s not the server-side solution I had hoped for but it gave me a chance to try something AJAX-ish and to make use of a more complex form submission approach.

Alright … now what have I done wrong?

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

11.17.07

Merb on Windows: It works!!!

Posted in Programming, Ruby, merb at 12:09 am by Robert Horvick

UPDATE: Installing Merb on Windows is now a lot easier!  Check it out here

This post outlines the exact steps I took to get merb working on Windows (to be specific - Vista Home Premium)

  1. Install InstantRails (I have no reason to believe this won’t work with the one-click installer).
  2. Start InstantRails and open a Ruby Console window (the steps following take place in that window)
  3. Execute “gem install hoe”  (RubyInline depends on hoe)
  4. Download http://web.mit.edu/~agp/www/parsetree-win32/ParseTree-2.0.2-mswin32.gem
  5. Download http://web.mit.edu/~agp/www/parsetree-win32/RubyInline-3.6.4.gem
  6. Execute “gem install RubyInline-3.6.4.gem”
  7. Execute “gem install ParseTree-2.0.2.mswin32.gem”
  8. Execute “gem install ruby2ruby”
  9. Execute “gem install json”  (choose json 1.1.1 (mswin32))
  10. Execute “gem install merb -y”
  11. Execute “merb myapp”
  12. Execute “cd myapp”
  13. Execute “set INLINEDIR=c:/temp”  (the slash direction matters!)
  14. Execute “merb”
  15. Browse to http://localhost:4000 and …

Merb Splash Screen

So a big thanks to Ezra for providing the pointers I needed.

Hopefully these steps will prove useful for others.

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

11.16.07

Merb on Windows: PEBKAC! (dependency and user error)

Posted in Programming, Ruby, merb at 11:56 pm by Robert Horvick

After my last merb post Ezra left a comment with some concrete suggestions to move forward with getting merb working on Windows.  My next post will cover that exact topic but I wanted to create a post to captute the stack traces of the errors I hit when trying to get merb running.

The first was a dependency issue.  Merb requires json but I did not have it installed.  I think the merb gem should have noted this dependency but honestly I don’t understand gems enough to know for sure.  The output of the merb command and call stack is:

C:\InstantRails\ruby\merb>merb
Merb started with these options:

:query_string_whitelist: []

:reloader: true
:environment: development
:merb_root: C:/InstantRails/ruby/merb
:exception_details: true
:cache_templates: false
:reloader_time: 0.5
:host: 0.0.0.0
:use_mutex: true
:port: “4000″
:session_id_cookie_only: true

Using pure ruby JSON lib
Using pure ruby JSON lib
C:/InstantRails/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require’: no such file to load — json/pure (LoadError)
        from C:/InstantRails/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `require’
        from C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/merb-0.4.1/lib/merb.rb:28
        from C:/InstantRails/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:32:in `gem_original_require’
        from C:/InstantRails/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:32:in `require’
        from C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/merb-0.4.1/lib/merb/server.rb:236:in `initialize_merb’
        from C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/merb-0.4.1/lib/merb/server.rb:573:in `mongrel_start’
        from C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/merb-0.4.1/lib/merb/server.rb:509:in `run’
        from C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/merb-0.4.1/bin/merb:6
        from C:/InstantRails/ruby/bin/merb:16:in `load’
        from C:/InstantRails/ruby/bin/merb:16

I fixed this by installing json 1.1.1 (mswin32).

C:\InstantRails\ruby\merb>gem install json
Select which gem to install for your platform (i386-mswin32)
 1. json 1.1.1 (mswin32)
 2. json 1.1.1 (ruby)
 3. json 1.1.0 (mswin32)
 4. json 1.1.0 (ruby)
 5. Skip this gem
 6. Cancel installation
> 1
Successfully installed json-1.1.1-mswin32
Installing ri documentation for json-1.1.1-mswin32…

No definition for cState_configure

No definition for cState_configure
Installing RDoc documentation for json-1.1.1-mswin32…

No definition for cState_configure

No definition for cState_configure

With the dependencies resolved I re-ran merb but hit another error message.  I’ll give you the output and call stack first and see if you see the problem:

C:\InstantRails\ruby\merb>merb
Merb started with these options:

:query_string_whitelist: []

:reloader: true
:environment: development
:merb_root: C:/InstantRails/ruby/merb
:exception_details: true
:cache_templates: false
:reloader_time: 0.5
:host: 0.0.0.0
:use_mutex: true
:port: “4000″
:session_id_cookie_only: true

C:/InstantRails/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require’: no such file to load — C:/InstantRails/ruby/merb/config/merb_init.rb (LoadError)
        from C:/InstantRails/ruby/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `require’
        from C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/merb-0.4.1/lib/merb/server.rb:250:in `initialize_merb’
        from C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/merb-0.4.1/lib/merb/server.rb:573:in `mongrel_start’
        from C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/merb-0.4.1/lib/merb/server.rb:509:in `run’
        from C:/InstantRails/ruby/lib/ruby/gems/1.8/gems/merb-0.4.1/bin/merb:6
        from C:/InstantRails/ruby/bin/merb:16:in `load’
        from C:/InstantRails/ruby/bin/merb:16

See it yet?

Require failed to find the file C:/InstantRails/ruby/merb/config/merb_init.rb.  But why?

Because I’m an idiot :).  I ran the merb command from the wrong directory.  I needed to move to the application directory at which point I re-ran merb and …

Wait for the next post!

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

11.14.07

ActiveRecord - How do those dynamic finders and attributes work?

Posted in Programming, Ruby at 8:32 pm by Robert Horvick

In my effort to understand more about ActiveRecord, and Ruby in general, I have been digging through AR line by line.

One of my first goals was to figure out how the dynamic attributes and find_* methods worked. I mean … you call a method and it’s not there and then somehow it gets created.

In the .NET world I would expect something like:

try {
    object.Invoke("Method", args);
} catch(MissingMethodException) {
    // Use the CodeDOM or Emit to generate some code and defer to the created object
}

Was that happening here? Turns out it’s not far off.

I started by creating a case I knew would fail:

class MissingMethod
end

mm = MissingMethod.new
mm.does_not_exist("argument")

# Exception: undefined method `does_not_exist' for #<MissingMethod:0x32171c4>

So how to capture that? Well - I figured ActiveRecord::Base needed to do that so I started there and found “method_missing”. Awesome :)

So I add a handler and now I’m looking like:

class MissingMethod
  def method_missing(method_id, *arguments)
    puts method_id
  end
end

mm = MissingMethod.new
mm.does_not_exist("argument")

# does_not_exist

Sweet.

Now I want to get that whole dynamic goodness thing to happen. So I set out to create a class that would take any missing method that starts with “call_*” and extract the “*” portion, see if that method exists and call it with the original arguments if it does.

So obj.call_real_method(arg) would in turn call obj.real_method(arg).

So now I’m left with a few tasks:

  1. split off the real method name
  2. figure out if it exists
  3. call it

The splitting was easy to figure out:

if match = /^call_([_a-zA-Z]\w*)$/.match(method_id.to_s)
  method = match.captures[0]

Figuring out if it existed took a little more research. I dug into the method_missing handler in ActiveRecord and fairly quickly ran into respond_to? which, after checking some docs, looked perfect.

if(respond_to?(method))

Finally I needed to pass along the call. I did not see an obvious invoke method so I checked out places in ActiveRecord that called respond_to? and noticed the pattern of calling __send__ shortly after. This looked promising. A few doc checks later and my sample was done.

class MissingMethod
  def method_missing(method_id, *arguments)
     if match = /^call_([_a-zA-Z]\w*)$/.match(method_id.to_s)
       method = match.captures[0]
       if(respond_to?(method))
         __send__ method, arguments
       else
         super
       end
     else
       super
     end
  end

  def display(arg)
    puts arg
  end
end

mm = MissingMethod.new
mm.call_display(”Hello World”)

When run prints “Hello World”

As for ActiveRecord - it is doing more than that, obviously. It is not just deferring to existing methods but rather also generating them, adding them to a hash and then calling the generated method from the hash. But this is that point of diminishing interest. I can see the goal line from here so it’s time to move on to the next topic before I get bogged down in the details instead of getting my head around the big picture.

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

11.13.07

ActiveRecord has_one versus belongs_to (finally understood)

Posted in Programming, Ruby at 6:57 pm by Robert Horvick

I spent some time googling for an answer to the question I’ve had about when to use has_one or belongs_to.  I came across Duane’s blog where he addressed this exact issue.

Ultimately the phrase that made it sink in was:

“With belongs_to, the table accepts responsibility for the foreign key. With has_one, the table expect the other table to hold it.” (which he attributes to this wiki).

The main shift is that I need to stop thinking in terms of the foreign keys and not the containing objects.

So thanks, Duane.

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Quieting MySQL - Disabling beep in Windows.

Posted in MySQL, Programming at 12:17 am by Robert Horvick

I write code in bed at night on my laptop.  I tend to make typos in the dark (yeah … that’s why).  In MySQL interactive shell an error generates a beep on windows (ASCII BEL).  It is loud.  Being night, this bothers my wife.  I need to avoid this.

I googled for “disable beep in mysql” and the first hit was MySQL bug 17088 “Command line tools beep too loud on Windows”.

The answer?  Turn off the beep service on windows.

> net stop beep

Beeps stopped.

Wife sleeps.

Typos continue.

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

11.12.07

Getting friendly with ActiveRecord (without Rails)

Posted in Programming, Ruby at 8:06 pm by Robert Horvick

I’ve been puttering around Ruby and Rails for a while now but it’s been mostly surface-level stuff.  Following examples, customizing little things here and there.  But I haven’t really dived in and gotten my hair wet.

Since I’m off the merb wagon the next task on the list was getting more familiar with ActiveRecord without getting bogged down in Rails and all things Webish.

My starting point was the excellent tutorial that I’m, in some ways, going to restate in this blog.

I started by connecting to MySQL and creating a database (TaskList) and a task table:

CREATE TABLE tasks (
  `id` INT PRIMARY KEY NOT NULL AUTO_INCREMENT,
  `title` VARCHAR(255) DEFAULT NULL
);

I deviated from the tutorial slightly here by adding AUTO_INCREMENT to the id column.  This makes creating the objects a little easier because I can let SQL worry about their ID assignments.

Next I took the sample code from the tutorial, customized it for my settings, and added a little flare at the end:

require 'rubygems'

require 'active_record'ActiveRecord::Base.establish_connection({
      :adapter => “mysql”,
      :username => “root”,
      :database => “TaskList”
})

# define a simple model

class Task < ActiveRecord::Base
end

eat     = Task.create “title” => “Eat”
drink   = Task.create “title” => “Drink”
bemerry = Task.create “title” => “Be Merry”

Task.find(:all).each { |t| puts t.title }

The program output is:

Eat

Drink

Be Merry 

Running it subsequent times adds new tasks with the same values:

Eat
Drink
Be Merry
Eat
Drink
Be Merry

So nothing ground breaking here.  I read a tutorial.  I did what it said.  It worked.  Life is good.

Now it’s time to start branching out a little.  Things I want to do now are:

  • Add support for task states (start with static and add support for user defined)
  • Have the ability to assign tasks to users
  • Add a due date to tasks

This should give me the basics for some simple relations.  With that foundation I should have enough footing with ActiveRecord that I’m ready to move on to something else.

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

« Previous entries