Thursday, January 28, 2010

Amazon on Rails what?

I'm building a Rails web app and was wondering what is the best way to get a list of products that Amazon would return based on a search term?

For example, if I sent amazon the term "iphone", I'd get a list of iphones back from Amazon. - http://stackoverflow.com/questions/1586836

Confusion of confusions...

sudo gem install rubygems-update
sudo /var/lib/gems/1.8/bin/update_rubygems
sudo gem install ECS amazon-ecs aws ruby-aws aws right_aws ruby-aaws

I had the same question and immediately became confused as to which of these is what I need.


Will the real Ruby on Rails Product Advertising API please stand up?


Amazon's Product Advertising API (formerly known as Amazon E-Commerce API (ECS), formerly known as just Amazon Web Services (AWS), is sometimes referred to as Amazon's Associates Web Service (AAWS)). Ugh!
If you don't believe me: http://www.google.com/search?q=amazon+ecs
Notice that the first hit is APAA.

aws-product-sign
http://umlaut.rubyforge.org/svn/trunk/lib/aws_product_sign.rb
http://bibwild.wordpress.com/2009/05/18/authenticating-to-amazon-product-api-in-ruby/

Ruby/(A)AWS (previously Ruby/AWS)
gem install ruby-aaws
Ruby/(A)AWS is a Ruby library interface to Amazon's Associates Web Service.
A Ruby language library that allows programmatic access to the popular Amazon Web sites via the AWS v4 API. It is the successor to the once popular, but now obsolete Ruby/Amazon.
by Ian Macdonald
http://rubyforge.org/projects/ruby-aaws/
https://rubyforge.org/projects/ruby-aaws/
http://ruby-aaws.rubyforge.org/
http://www.caliban.org/ruby/ruby-aws/
http://developer.amazonwebservices.com/connect/entry.jspa?externalID=1651&categoryID=14

amazon-product-advertising-api
A nice rubyish interface to the Amazon Product Advertising API, formerly known as the Associates Web Service and before that the Amazon E-Commerce Service.
http://amazon-pa-api.rubyforge.org/
http://github.com/completelynovel/amazon-product-advertising-api

AWS means Amazon Web Services. It used to mean Amazon's Associates Web Service
http://developer.amazonwebservices.com/connect/entry.jspa?externalID=846
http://aws.amazon.com/documentation/


ruby-aws
gem install ruby-aws
framework for Amazon Web Services, including full-featured library for accessing Mechanical Turk.
http://rubyforge.org/projects/ruby-aws/
http://ruby-aws.rubyforge.org/ruby-aws/
by David Parrott


Amazon E-Commerce API (ECS) is old. The docs haven't been updated since 2005.
http://docs.amazonwebservices.com/AWSEcommerceService/2005-10-05/index.html

ECS
gem install ECS
ECS is a Ruby interface to Amazon E-Commerce Service.
http://ecs.rubyforge.org/
http://developer.amazonwebservices.com/connect/entry.jspa?externalID=826&categoryID=14
by wzph

amazon-ecs
gem install amazon-ecs
A generic Amazon E-commerce REST API with configurable default options and method call options.
http://www.pluitsolutions.com/projects/amazon-ecs
http://www.pluitsolutions.com/2006/12/07/ruby-amazon-e-commerce-rest-services-api-amazon-ecs/
example: http://www.bookjetty.com/search?db=us&q=curious+george
by PluitSolutions

Saturday, January 23, 2010

REST & CORS Browser Details

Today my Saturday project was to create a page that systematically tests the RESTful and CORS (XHR2) capabilities of browsers.

I've used synchronous (not async) calls to keep browsers from hammering my small server, so you'll have to wait for all 50 or so calls to complete, which takes a minute or two.

RESTTest:
http://resttest.coolaj86.info/

CORSTest:
http://resttest.whatsayye.com/

Later I'll clean it up and turn it into a table and, perhaps, store the results of visitors to create a version that only runs the tests if they haven't already been run on your browser.


If you would like to help, please contact me.
I'm coolaj86, I use google's mail system.

Wednesday, January 20, 2010

Connecting to BYU LDAP with Ruby

require 'rubygems'
require 'net/ldap'

class AuthBYU
  def initialize
    # Off-campus connections MUST be secure. On campus connection can be insecure
    @ldap = Net::LDAP.new(:port => 636, :encryption => :simple_tls)
    #ldap = Net::LDAP.new(:port => 389)
  end

  def login(routey_id, routey_password)
    ldap.host = "ldap.byu.edu"
    ldap.auth "uid=#{routey_id},ou=People,o=BYU.edu", routey_password
    ldap.bind # true | false | throw timeout
  end

  def ry_login(*args)
    login(*args)
  end

  def cs_login(cs_id,cs_password)
    # Only works on-campus and only with insecure connections
    ldap = Net::LDAP.new(:port => 389)
    ldap.host = "ldap.cs.byu.edu"
    ldap.auth "uid=#{cs_id},ou=people,dc=cs,dc=byu,dc=edu", cs_password
    ldap.bind
  end

  def caedm_login(caedm_id, caedm_password)
    # I can't find the info for this one
    #ldap = Net::LDAP.new(:port => 389)
    #ldap.host = "????.et.byu.edu"
    #ldap.auth "uid=#{caedm_id},ou=accounts,ou=caedm,dc=et,dc=byu,dc=edu", caedm_password
    #ldap.bind
    false
  end

  private
    attr_accessor :ldap
end

# Test by hand
puts "Username:"
username = gets.chomp
puts "Password (Visible):"
password = gets.chomp

b = AuthBYU.new
if b.login username, password 
  puts "Is good\n"
else
  puts "Is not so good\n"
end

Active Scaffold 404 / 500 "Couldn't find Abcxyz with ID=edit_associated"

ActiveScaffold website hasn't been updated with a little detail that's fairly important.

map.resources :abcxyz_types, :active_scaffold => true
  map.resources :abcxyzs, :active_scaffold => true

You need to tell config.routes.rb that you're using active scaffold.

ActiveRecord::RecordNotFound in AssignmentsController#show

Couldn't find Assignment with ID=edit_associated

/var/lib/gems/1.8/gems/activerecord-2.3.3/lib/active_record/base.rb:1586:in `find_one'
/var/lib/gems/1.8/gems/activerecord-2.3.3/lib/active_record/base.rb:1569:in `find_from_ids'
/var/lib/gems/1.8/gems/activerecord-2.3.3/lib/active_record/base.rb:616:in `find'
/var/lib/gems/1.8/gems/actionpack-2.3.3/lib/action_controller/base.rb:1327:in `send'
/var/lib/gems/1.8/gems/actionpack-2.3.3/lib/action_controller/base.rb:1327:in `perform_action_without_filters'
/var/lib/gems/1.8/gems/actionpack-2.3.3/lib/action_controller/filters.rb:617:in `call_filters'
/var/lib/gems/1.8/gems/actionpack-2.3.3/lib/action_controller/filters.rb:610:in `perform_action_without_benchmark'
/var/lib/gems/1.8/gems/actionpack-2.3.3/lib/action_controller/benchmarking.rb:68:in `perform_action_without_rescue'
/var/lib/gems/1.8/gems/activesupport-2.3.3/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/var/lib/gems/1.8/gems/activesupport-2.3.3/lib/active_support/core_ext/benchmark.rb:17:in `ms'
/var/lib/gems/1.8/gems/actionpack-2.3.3/lib/action_controller/benchmarking.rb:68:in `perform_action_without_rescue'
/var/lib/gems/1.8/gems/actionpack-2.3.3/lib/action_controller/rescue.rb:160:in `perform_action_without_flash'
/var/lib/gems/1.8/gems/actionpack-2.3.3/lib/action_controller/flash.rb:146:in `perform_action'
/var/lib/gems/1.8/gems/actionpack-2.3.3/lib/action_controller/base.rb:527:in `send'
/var/lib/gems/1.8/gems/actionpack-2.3.3/lib/action_controller/base.rb:527:in `process_without_filters'
/var/lib/gems/1.8/gems/actionpack-2.3.3/lib/action_controller/filters.rb:606:in `process'
/var/lib/gems/1.8/gems/actionpack-2.3.3/lib/action_controller/base.rb:391:in `process'
/var/lib/gems/1.8/gems/actionpack-2.3.3/lib/action_controller/base.rb:386:in `call'
/var/lib/gems/1.8/gems/actionpack-2.3.3/lib/action_controller/routing/route_set.rb:434:in `call'

[Edit, later on, in the evening]
As it turns out, the official website isn't as official as the wiki. Go figure.
http://wiki.github.com/activescaffold/active_scaffold/getting-started

Monday, January 18, 2010

Firefox, why don't you parse error messages?

My JSON webservice uses HTTP Status codes.

I know it's a novel idea to use internationally agreed upon standards (and hardly anyone does it...) but come on Firefox! WTF!? I thought standards are what you were all about!?

I send a bad password via xhr and my webservice responds 422 Unprocessable Entity with JSON which describes the error in greater detail.

Firefox turns that response into an empty string!!! But if the status code is 2xx it works fine. Huh? What? Huh?

jQuery 1.4 is set up to parse using window.JSON and As it turns out an empty string isn't proper JSON and an exception is thrown. WebApp go BOOM!

I'd like to submit a bug to Mozilla, but I have to wait for their mail system to get through to mine... and hence I decided to blog about it.


In the meantime... I guess I lie and use 200 status codes? I don't know. That seems to be the simplest solution.

Thursday, January 14, 2010

Use python to share files on a local network quickly

Create a folder with the files you want to share and get into that folder in a terminal.

python -m SimpleHTTPServer

get your ip address

ifconfig

Have the people on your network quickly grab the file.

Tada!

Monday, January 11, 2010

The DoubleDIP Design Pattern

The Double Data-Interface-Presenter Pattern

In this pattern, the Presenter of the first application becomes the Data of the second application, kind of like a Dual-MVC, but using presenter logic rather than a dumb template / view.

As an example, you might have a non-degradable web-service (people who don't use javascript are nuts) in which your application client uses your web-service's API.


I'm building a toolkit to make a variety of web applications with incredible user interfaces at incredible speed... so far it's been a long slow process of finding the right tools for my toolkit, but things are shaping up.

Apache (good enough for now)
* mod_upload
* x-sendfile
Passenger Fusion
Ruby on Rails (My favorite web service framework)
JSON (a subset of YAML / YML)
jQuery (My favorite javascript framework)
PURE.js (the best Javascript Templating system I've seen)
jQuery.jStore or persist.js (a Javascript ORM of sorts for HTML5 LocalStorage)

and a sprinkling of Google's magic here and there.

and a heavy dose of figuring out how to perform local caches

and a spattering of forwards-compatible HTML5 semantic classes