lib/koala.rb in koala-0.5.0 vs lib/koala.rb in koala-0.6.0

- old
+ new

@@ -6,10 +6,16 @@ require 'json' # include default http services require 'http_services' +# add Graph API methods +require 'graph_api' + +# add REST API methods +require 'rest_api' + module Koala module Facebook # Ruby client library for the Facebook Platform. # Copyright 2010 Facebook @@ -30,155 +36,54 @@ # Facebook JavaScript SDK, which is the canonical way to implement # Facebook authentication. Read more about the Graph API at # http://developers.facebook.com/docs/api. You can download the Facebook # JavaScript SDK at http://github.com/facebook/connect-js/. - GRAPH_SERVER = "graph.facebook.com" - - class GraphAPI - # A client for the Facebook Graph API. - # - # See http://developers.facebook.com/docs/api for complete documentation - # for the API. - # - # The Graph API is made up of the objects in Facebook (e.g., people, pages, - # events, photos) and the connections between them (e.g., friends, - # photo tags, and event RSVPs). This client provides access to those - # primitive types in a generic way. For example, given an OAuth access - # token, this will fetch the profile of the active user and the list - # of the user's friends: - # - # graph = Koala::Facebook::GraphAPI.new(access_token) - # user = graph.get_object("me") - # friends = graph.get_connections(user["id"], "friends") - # - # You can see a list of all of the objects and connections supported - # by the API at http://developers.facebook.com/docs/reference/api/. - # - # You can obtain an access token via OAuth or by using the Facebook - # JavaScript SDK. See http://developers.facebook.com/docs/authentication/ - # for details. - # - # If you are using the JavaScript SDK, you can use the - # Koala::Facebook::OAuth.get_user_from_cookie() method below to get the OAuth access token - # for the active user from the cookie saved by the SDK. - + class API # initialize with an access token def initialize(access_token = nil) @access_token = access_token end - - def get_object(id, args = {}) - # Fetchs the given object from the graph. - api(id, args) - end - - def get_objects(ids, args = {}) - # Fetchs all of the given object from the graph. - # We return a map from ID to object. If any of the IDs are invalid, - # we raise an exception. - api("", args.merge("ids" => ids.join(","))) - end - - def get_connections(id, connection_name, args = {}) - # Fetchs the connections for given object. - api("#{id}/#{connection_name}", args) - end - - def put_object(parent_object, connection_name, args = {}) - # Writes the given object to the graph, connected to the given parent. - # - # For example, - # - # graph.put_object("me", "feed", :message => "Hello, world") - # - # writes "Hello, world" to the active user's wall. Likewise, this - # will comment on a the first post of the active user's feed: - # - # feed = graph.get_connections("me", "feed") - # post = feed["data"][0] - # graph.put_object(post["id"], "comments", :message => "First!") - # - # See http://developers.facebook.com/docs/api#publishing for all of - # the supported writeable objects. - # - # Most write operations require extended permissions. For example, - # publishing wall posts requires the "publish_stream" permission. See - # http://developers.facebook.com/docs/authentication/ for details about - # extended permissions. - - raise GraphAPIError.new({"type" => "KoalaMissingAccessToken", "message" => "Write operations require an access token"}) unless @access_token - api("#{parent_object}/#{connection_name}", args, "post") - end - - def put_wall_post(message, attachment = {}, profile_id = "me") - # Writes a wall post to the given profile's wall. - # - # We default to writing to the authenticated user's wall if no - # profile_id is specified. - # - # attachment adds a structured attachment to the status message being - # posted to the Wall. It should be a dictionary of the form: - # - # {"name": "Link name" - # "link": "http://www.example.com/", - # "caption": "{*actor*} posted a new review", - # "description": "This is a longer description of the attachment", - # "picture": "http://www.example.com/thumbnail.jpg"} - - self.put_object(profile_id, "feed", attachment.merge({:message => message})) - end - - def put_comment(object_id, message) - # Writes the given comment on the given post. - self.put_object(object_id, "comments", {:message => message}) - end - - def put_like(object_id) - # Likes the given post. - self.put_object(object_id, "likes") - end - - def delete_object(id) - # Deletes the object with the given ID from the graph. - api(id, {}, "delete") - end - - def search(search_terms, args = {}) - # Searches for a given term - api("search", args.merge({:q => search_terms})) - end - - def api(path, args = {}, verb = "get") + + def api(path, args = {}, verb = "get", options = {}) # Fetches the given path in the Graph API. args["access_token"] = @access_token if @access_token # make the request via the provided service - result = Koala.make_request(path, args, verb) + result = Koala.make_request(path, args, verb, options) # Facebook sometimes sends results like "true" and "false", which aren't strictly object # and cause JSON.parse to fail # so we account for that response = JSON.parse("[#{result}]")[0] - # check for errors - if response.is_a?(Hash) && error_details = response["error"] - raise GraphAPIError.new(error_details) - end - response end end - - class GraphAPIError < Exception + + class GraphAPI < API + include GraphAPIMethods + end + + class RestAPI < API + include RestAPIMethods + end + + class GraphAndRestAPI < API + include GraphAPIMethods + include RestAPIMethods + end + + class APIError < Exception attr_accessor :fb_error_type def initialize(details = {}) self.fb_error_type = details["type"] super("#{fb_error_type}: #{details["message"]}") end end - + + class OAuth attr_accessor :app_id, :app_secret, :oauth_callback_url def initialize(app_id, app_secret, oauth_callback_url = nil) @app_id = app_id @app_secret = app_secret @@ -258,11 +163,11 @@ def get_access_token(code) result = fetch_token_string(code) # if we have an error, parse the error JSON and raise an error - raise GraphAPIError.new((JSON.parse(result)["error"] rescue nil) || {}) if result =~ /error/ + raise APIError.new((JSON.parse(result)["error"] rescue nil) || {}) if result =~ /error/ # otherwise, parse the access token parse_access_token(result) end end end @@ -278,6 +183,6 @@ require 'typhoeus' Koala.http_service = TyphoeusService rescue LoadError Koala.http_service = NetHTTPService end -end \ No newline at end of file +end