Welcome to openkapow Sign in | Join
in Search

Mashup demos

These are demo mashups that shows the potential of using openkapow robots.

About the "Image-Tag Matching Game" demo

  This demo is a game where the users tries to match groups of images to groups of tags based on what word they have in common. The words, images and tags are all taken from external sites which makes the game dynamic and every game is unique. The demo is all written in Ruby on Rails and uses AJAX to create the user interface.
  

The Demo

The process of the Image-Tag matching game is as follows:
  1. A REST robot goes to Digg Spy and gets 5 words from Digg stories that have recently been added, voted upon or commented. These words are called "seed words" since they seed the game with values.
  2. The seed words are used as input to a REST robot that searches Flickr for images related to the word in question. If no images are found on Flickr the robot tries Zooomr instead.
  3. The seed words are also used as input to a REST robot that goes to Del.icio.us to find related tags, if no such tags are found at Del.icio.us the robot goes to Wordpress instead.
  4. The images and tags related to a seed word are grouped together and showed to the user.
  5. The user then have a limited time to try to determine which group of images that are connected to which group of tags (ie have a common seed word). Matches are done by dragging and dropping the images on top of the tags.

The Robots

All in all there are 3 robots in this demo. On to get the seed words from Digg Spy, one to get images from Flickr or Zooomr and finally one to get related tags from Del.icio.us or Wordpress. All these robots used in this demo are REST robots that return XML.

Since all robots need to be executed as quickly as possible (to not make the waiting time for the user too long) they are all tweaked for higher performance using page changes to lower the size of pages, not using frames or cookies to send as little data back and forth between the sites and the openkapow server etc. For more details about robot performance enhancing take a look at the tutorial "Improve robustness and performance of an RSS robot" (same techniques that works for an RSS robot works for a REST robot).

The GameController

This is the main Ruby on Rails controller in the demo. The method used to acctually play the game is named play_the_game. It is from this method that the robot that gets the seed words, and the robots that gets the images and tags are called. In order to make the demo quicker to execute the robots to get images and tags are run in parallell threads.

threads = []
seed_words.each{ |word|
    threads << Thread.new {
        @related_tags[word] = get_related_tags_for_word(word)
     }
}
seed_words.each{ |word|
    threads << Thread.new {
        @related_images[word] = get_related_images_for_word(word)
    }
}
threads.each {|thread| thread.join}

In the end of the play_the_game method the partial view images_and_tags is called to show all the images and tags that the robots have returned to the user.

Calling a REST Service from Ruby on Rails

All REST robots are called from one Controller, the OpenKapowRESTServiceController. This controller only have one method, call_rest_service, which take the path to the openkapow REST service (the path is everything after "http://service.openkapow.com"). The call_rest_service method then performs a GET request to openkapow and returns a RestResponse model.

class OpenKapowRESTServiceController < ApplicationController
    model :rest_response

    hide_action :call_rest_service

    def call_rest_service(path)
      require 'net/http'
      begin
         Net::HTTP.start("service.openkapow.com") do |http|
          response = http.get(path, 'Accept' => 'text/xml')
          response_code = response.code
          xml = nil
          message = response.message
          if response_code == "200"
              xml = response.body
          end
          @rest_response = RestResponse.new(response_code, xml, message)
        end
      rescue => err
        #If nothing else works, return HTTP 503 = Service Unavailable
        @rest_response = RestResponse.new("503", nil, "#{err.message}")
      end
    end
 
end

Below is an example of a call to OpenKapowRESTService.call_rest_service. First a new instance of the controller class needs to be created, then call_rest_service is called with the REST robots path (including input values & specifying the result format XML). If the HTTP response code returned in response.response_code is "200" (which means all went OK) then the returned XML needs to be parsed and handled. If something went wrong then the error message is written to the flash and later written out in the views to inform the user of the errors.

@open_kapow_rest_controller = OpenKapowRESTServiceController.new
....
response =
  @open_kapow_rest_controller.call_rest_service
      ("/demo/getrelatedimages.rest?resultformat=xml&searchText1=#{word}")   
if response.response_code== "200" and !response.xml.nil?
    ....
    //parse XML
    ....
else
    flash[:error] ="An error occurred when contacting Flickr and/or    
                          Zooomr:<br/>#{response.message}"
end

Note that the RestResponse model is not associated with ActiveRecord since there is no need to save anything from the model into a database. Nothing in the whole application uses ActiveRecord which means that there are some changes to the default Rails configurations, for more information check the free excerpt from Rails Recipes.

Parse XML in Ruby on Rails

In this demo all XML returned by REST robots are parsed using REXML. Below is an example of such parsing, in this case the code parses the XML returned by the robot that gets images from Flickr or Zooomr. The returned XML is in the format:

    <imageGroup>
        <image1>..</
image1>
        <
image2>..</image2>
        <
image3>..</image3>
        <
image4>..</image4>
     </imageGroup>


A new REXML::Document is created from the XML the robot returned. In this XML all <imageGroup> tags are looped through (this is done even if there should just be one <imageGroup> tag per response) and then the text from the imageX elements are added to the image array.

doc = REXML::Document.new(response.xml)
doc.elements.each('result/imageGroup') do |group|         
    images = add_text_to_array_if_not_empty(images, group.elements["image1"].text)
    images = add_text_to_array_if_not_empty(images, group.elements["image2"].text)
    images = add_text_to_array_if_not_empty(images, group.elements["image3"].text)
    images = add_text_to_array_if_not_empty(images, group.elements["image4"].text)
end

The add_text_to_array_if_not_empty adds a new item to an array unless the text in question is empty (to avoid empty items in an array).

The Views

The main view is play.rhtml and in this view the partial view _images_and_tags.rhtml show all acctual images and tags to match up. These views contains both AJAX code generated by the Ruby on Rails prototype helpers and javascript functions that manipulate the content to enable all the necessary layers to show and hide and works as needed.

One example of this is shown below, where the "Play the Game Now" link is printed out using the Ruby on Rails prototype helper method link_to_remote to create an AJAX call that loads the result of the GameController.play_the_game method into the content div (the method acctually loads the images_and_tags partial view into this div). When the link is clicked the progressBar div will be shown (this div contains the animated circle that shows that the demo is working) and the playGame div will be hidden (this is the div that contains the link itself). Furthermore the resetCorrectGuesses javascript function will be executed to set the number of guesses to 0. Once the AJAX call is complete the progressBar div will once again be hidden.

<div id="playGame">
        <p><%= link_to_remote("Play the Game Now",
                               :update => "content",
                               :loading => "Element.show('progressBar');
                                            Element.hide('playGame');
                                            resetCorrectGuesses();",
                               :complete => "Element.hide('progressBar');",
                               :url => {:action => :play_the_game})%>
        </p>
</div>

In the images_and_tags partial view all the groups of images and tags are printed. Each groups of images is made into a draggable_element and each group of tags are made into a drop zone using the method drop_receiving_elements

Summary

This demo shows how to use openkapow robots together with Ruby on Rails. Basically the robots are used to expand the functionality of the Ruby on Rails code and it shows how to make a Rails based mashup that used openkapow robots to interact with websites for functionality and data. The rapid coding that is possible in Rails fits very well with the rapid robot development possible in openkapow.
Published Wednesday, November 22, 2006 9:21 AM by Andreas

Comments

 

majas2008 said:

great!!!!!!!!

January 21, 2007 5:08 AM
Anonymous comments are disabled
Copyright 2006, 2007 KapowTech.com All Rights Reserved Company | Contact | Terms | Privacy