#!/usr/bin/env ruby
# This is a Ruby client library for the Dojo Learning REST API.
#
# For more info and documentation, visit:
#
# http://www.dojolearning.com/developers
#
# Requires simplehttp and json libraries from RubyForge, available
# via:
#
# gem install json
# gem install simplehttp
#
# or from here:
#
# http://json.rubyforge.org/
# http://simplehttp.rubyforge.org/
#
# Example usage:
#
# require 'dojolearning'
#
# dojo = DojoLearning.new('user', 'apikey')
#
# topics = dojo.lesson_topics ();
#
# topics.each { |topic|
# puts '
%s
' % [topic['name']]
#
# lessons = dojo.lesson_list(topic['id'], 0)
#
# lessons.each { |lesson|
# puts '%s
' % [lesson['url'], lesson['title']]
# }
# }
#
# Author:: John Luxford (mailto:lux@dojolearning.com)
# Copyright:: Copyright (c) 2008 Dojo Learning
# License:: LGPL, http://opensource.org/licenses/lgpl-2.1.php
require 'cgi'
require 'rubygems'
require 'simple_http'
require 'json'
# Dojo Learning client class.
class DojoLearning
attr_reader :user, :apikey, :errno, :error
attr_writer :user, :apikey, :errno, :error
# Constructor method.
def initialize(user, apikey)
@uri = 'http://api.dojolearning.com/rest-action/%s?user=%s&apikey=%s%s'
@post_uri = 'http://api.dojolearning.com/rest-action/%s'
@post_args = 'user=%s&apikey=%s%s'
@user = user
@apikey = apikey
@errno = 0
@error = ''
# Generate the dynamic methods
@method_list = self.send_and_receive('', '')
@method_list.each { |k, v|
self.add_method(k, v)
}
end
# Send, receive and parse the request.
def send_and_receive(request, params)
# determine request type
if (@method_list && @method_list[request])
method = @method_list[request]['method']
else
method = 'GET'
end
if (method == 'GET')
# handle GET requests
url = @uri % [request, @user, @apikey, params]
res = SimpleHttp.get(url)
else
# handle POST requests
url = @post_uri % request
params = @post_args % [@user, @apikey, params]
res = SimpleHttp.post(url, params)
end
if res.class == Net::HTTPUnauthorized
@errno = 401
@error = 'Unauthorized'
return false
end
# JSON package doesn't seem to handle simple types properly...
if (res == 'true')
return true
elsif (res == 'false')
return false
elsif (res.match(/^".*"$/))
return res.gsub('\\"', '"').slice(1..-2)
end
return JSON.parse(res)
end
# Dynamically add methods to the object
def add_method(name, data)
code = "def self." + name.gsub(/\./, '_') + '('
sep = ''
data['parameters'].each { |param|
code += sep + param
sep = ', '
}
code += ")\n"
code += "\tm = '" + name + "'\n"
code += "\tp = ''\n"
if (data['parameters'].length > 0)
data['parameters'].each { |k|
code += "\tp += '&" + k + "=' + CGI.escape(" + k + ".to_s)\n"
}
end
code += "\treturn self.send_and_receive(m, p)\n"
code += "end\n\n"
eval(code)
end
end
#--
if $0 == __FILE__
dojo = DojoLearning.new('user', 'apikey')
topics = dojo.lesson_topics()
topics.each { |topic|
puts '%s
' % [topic['name']]
lessons = dojo.lesson_list(topic['id'], 0)
lessons.each { |lesson|
puts '%s
' % [lesson['url'], lesson['title']]
}
}
end