SyntaxHighlighter

Thursday, April 23, 2009

My Ambigram

It took me a while to figure out what this type of thing was called. It's an "ambigram" - meaning rotationally symmetrical word. Roy Leban, a software designer in our offices at Startpad does this with his first name as a signature and I thought I'd it a shot.

This is what I got.

Wednesday, April 22, 2009

Google Image Search in Rails using the Google Ajax API

Google has a neat Ajax API for searching images on the web. This is neat, but I wanted to integrate it into my site and didn't want to rely on Javascript so heavily. Luckily, Google also supplies a JSON api that's very easy to work with.

Instead, I made a GoogleImage class and reference it in the controller like so. This is in a controller action. The view for this supplies a keyword via a form, and there is a simple 'next' | 'pevious' link that modifies the start parameter.

This is in the view (app/views/search/google_images.html.erb)

<% for image in @google_images %>
<%= link_to(image_tag(image.thumbnail, :style => 'padding:3px; border:solid 1px #EEE; margin:2px; width:100px; float:left'), image.original) %>
<% end %>
<%= clear %>
<%= link_to_unless (params[:start] == 0), 'Prev', :overwrite_params => { :start => (params[:start] - 8) } %> |
<%= link_to_unless (params[:start] > 0 && @google_images.blank?), 'Next', :overwrite_params => { :start => (params[:start] + 8) } %>


This is in the controller (app/controllers/search_controller.rb)


def google_images
params[:start] = params[:start].to_i
@page_title = "Import image from Google"
@google_images = GoogleImage.all(params[:keywords], params[:start])
end



And this is the model (app/models/google_image.rb)

class GoogleImage

require 'json'

attr_accessor :thumbnail, :original, :name, :position

def initialize(params)
super()
self.name = params[:name]
self.thumbnail = params[:thumbnail]
self.original = params[:original]
self.position = params[:position]
end

def self.find (keyword, position = 0)
url = "http://ajax.googleapis.com/ajax/services/search/images?rsz=large&start=#{position}&v=1.0&q=#{CGI.escape(keyword)}"
json_results = open(url) {|f| f.read };
results = JSON.parse(json_results)
image_array = results['responseData']['results']
image = image_array[0] if image_array
google_image = self.new(:thumbnail => image['tbUrl'], :original => image['unescapedUrl'], :position => position, :name => keyword.titleize)
end

def self.all (keyword, position = 0)
return [] if (keyword.nil? || keyword.strip.blank?)
url = "http://ajax.googleapis.com/ajax/services/search/images?rsz=large&start=#{position}&v=1.0&q=#{CGI.escape(keyword)}"
json_results = open(url) {|f| f.read };
results = JSON.parse(json_results)
begin
image_array = results['responseData']['results']
google_images = image_array.map{|image| self.new(:thumbnail => image['tbUrl'], :original => image['unescapedUrl'], :name => keyword.titleize) }
google_images.each_index{|i| google_images[i].position = position + i }
rescue
[]
end
end

end


A couple things to note
- the "start" parameter is not a page number. It's the index of the image in this search.
- Google seems to allow the first 64 images to come back. No more.
- Display is limited to 4 or 8 results (that's due to the result size param 'rsz').

Tuesday, April 14, 2009

Posting a Status Update to Facebook

OK - following up on my post about sending a status update to Twitter - here is a simple how-to with Facebook posts.

I really like the facebook system. It's got a lot more bells and whistles, which I usually don't like, but they went through some effort to let you pick a thumbnail to go along with the post and give you the option to send a message or post to your wall. Very nicely done. On the negative side, when a user clicks on the link from facebook, it opens in an iframe in a facebook URL. Not the worst experience - it's easy to close.

Anyway, without further ado, here's my code...

I link to this action via the link_to helper


<%= link_to image_tag('icon/facebook.gif'), {:controller => 'articles', :action => 'facebook', :id => @article}, :popup => ['new_window','width=600,height=400'], :rel => 'nofollow' %>



This is in the controller


def facebook_post
@article = Article.find(params[:id])
url = CGI.escape(url_for(@article, :only_path => false)
title = CGI.escape(@article.title)
redirect_to "http://www.facebook.com/sharer.php?u=#{url}&t=#{title}"
end

This will pop up a window that is 600x400 (works well with the facebook page that opens up).

Tuesday, April 07, 2009

Finding recursive objects in ActiveRecord in Rails

Here's the issue, say you wanted to find all the students that are in a course (avoiding the 'class' keyword) with you. And say you had models that looked like this...

Class Student <>
has_many :courses

Class Course <>
has_many :students

You might try this in the Student class...

def
class_mates
Student.find :all, :include => { :courses => :students }, :conditions => ['students.id = ?', self.id]
end

But, of course, this would only return self.

To find the classmates, you need to find the name of the alias used on the joined table and put your condition there. Rails will probably give it an alias like 'course_students'. You can confirm this by running the query with a condition on the course table and looking in the logs. Once you know the name of the aliased table you can do this...

def class_mates
Student.find :all, :include => { :courses => :students }, :conditions => ['course_students.id = ? and students.id != ?', self.id, self.id], :group => 'students.id'
end

This will return all students that are in a class with you, and it will remove you from the list.

Now, if you want to find out how many classes they are in together, that's trickier. I've only been able to do that with find_by_sql.

Let me know if you find a better way.