Skip to content

Commit

Permalink
remove GraphNode (replaced by GraphResponse); wholesale changes and b…
Browse files Browse the repository at this point in the history
…ig feature-adds to GraphResponse
  • Loading branch information
mccolin committed Sep 20, 2011
1 parent bf857ab commit e94fb9d
Show file tree
Hide file tree
Showing 5 changed files with 177 additions and 51 deletions.
4 changes: 3 additions & 1 deletion lib/doesopengraph.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@
#
# DoesOpenGraph - Module definition and loader

require 'hashie'

require "doesopengraph"
require "doesopengraph/graph_api"
require "doesopengraph/graph_request"
require "doesopengraph/graph_response"
require "doesopengraph/graph_node"

module DoesOpenGraph

Expand Down
40 changes: 11 additions & 29 deletions lib/doesopengraph/graph_api.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
module DoesOpenGraph

class OpenGraphException < Exception; end
class IncapableOfUpdateMethods < OpenGraphException; end
class InvalidRequestMethod < OpenGraphException; end
class InvalidResponseFromFacebook < OpenGraphException; end


Expand All @@ -28,6 +30,10 @@ def initialize(acctok=nil)
@history = Array.new
end

def renew(acctok)
@access_token = acctok
end


def node(id, connection=nil, params={})
path = connection.nil? ? id.to_s : File.join(id.to_s, connection.to_s)
Expand Down Expand Up @@ -64,13 +70,11 @@ def num_requests
end

def previous_request
method, path, params = @history.last
return {:method=>method, :path=>path, :params=>params}
@history.last
end

def repeat
pr = previous_request
return request(pr[:method], pr[:path], pr[:params])
previous_request.request()
end


Expand All @@ -79,32 +83,10 @@ def repeat


def request(method, path, params={})
@history << [method, path, params]

base = @access_token.nil? ? HTTP_GRAPH_ENDPOINT : HTTPS_GRAPH_ENDPOINT
href = File.join(base, path)

if !%w(get post delete).include?(method.to_s)
raise "Invalid HTTP method #{method} passed to request" and return nil
end

params[:access_token] = @access_token if @access_token

begin
response = Typhoeus::Request.send(method, href, :params=>params)
data = JSON.parse(response.body)
return GraphResponse.new(data, self) if path == "search"
return GraphNode.new(data, self)
rescue JSON::ParserError => jsone
return true if response.body == "true"
return false if response.body == "false"
raise InvalidResponseFromFacebook.new("Invalid JSON or poorly formed JSON returned for #{path}") and return nil
rescue Exception => e
raise OpenGraphException.new("Error in OpenGraph response: #{e}") and return nil
end
api_request = GraphRequest.new(self, method, path, params)
@history << api_request
return api_request.request()
end




end # GraphAPI
Expand Down
13 changes: 0 additions & 13 deletions lib/doesopengraph/graph_node.rb

This file was deleted.

58 changes: 58 additions & 0 deletions lib/doesopengraph/graph_request.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# AWEXOME LABS
# DoesOpenGraph
#
# GraphRequest - A request to the OpenGraph API.
#

module DoesOpenGraph
class GraphRequest

attr_reader :api, :method, :path, :params

# Build a Request object from its component parts
def initialize(api, method, path, params={})
@api = api
@method = method
@path = path
@params = params
end


# Perform the request
def request
base = @api.access_token ? GraphAPI::HTTPS_GRAPH_ENDPOINT : GraphAPI::HTTP_GRAPH_ENDPOINT
href = File.join(base, @path)

if !%w(get post delete).include?(@method.to_s)
raise InvalidRequestMethod.new("Invalid HTTP method #{@method} passed to request") and return nil
end

params[:access_token] = @api.access_token if @api.access_token

begin
response = Typhoeus::Request.send(@method, href, :params=>@params)
puts "RESPONSE RECEIVED FROM FACEBOOK ON REQUEST TO PATH #{@path}:\n#{response.body}\n\n"

return GraphResponse.new(response.body, self)

# TODO: Parse known error responses from Facebook, such as:
# TODO: {"error":{"message":"Unknown path components: \/status","type":"OAuthException"}}

rescue Exception => e
raise OpenGraphException.new("Error in OpenGraph response: #{e}") and return nil
end
end


# Repeat the same request with optionally different parameters
def repeat(params={})
@params.merge(params)
request()
end


end # GraphRequest
end # DoesOpenGraph



113 changes: 105 additions & 8 deletions lib/doesopengraph/graph_response.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,114 @@
module DoesOpenGraph
class GraphResponse

attr_reader :content, :api
attr_reader :content, :object, :request

# Build a Response object from request content and store the api
def initialize(content, api=nil)
@content = content.is_a?(Hash) ? content : Hash.new
@api = api
# Build a Response object from raw JSON HTTP response
def initialize(raw_content, request=nil)
@request = request
self.update(raw_content)
end

# Use secret patching to provide accessors to connections within node

# Update the stored content of this node and parse
def update (raw_content)
@content = raw_content
self.parse
end

# Parse the stored raw content and translate into a usable object
def parse
begin
parsed_content = JSON.parse(@content)
@object = parsed_content.is_a?(Hash) ? Hashie::Mash.new(parsed_content) : parsed_content

rescue JSON::ParserError => parse_error
@object = nil
if parse_error.message.match("unexpected token")
@object = true if @content == "true"
@object = false if @content == "false"
end
if @object.nil?
raise InvalidResponseFromFacebook.new("Invalid JSON returned from Facebook: #{parse_error.message}")
end
end
end


# Update this node from theFetch an updated view of this node
def reload
raise IncapableOfUpdateMethods.new("Cannot update content without stored request") if request.nil?
up = request.request()
@content = up.content
@object = up.object
return self
end

# Introspect on the connections available to this node
def introspect
raise IncapableOfUpdateMethods.new("Cannot update content without stored request") if request.nil?
request.repeat(:metadata=>1)
end

# Get a connection of this node
def get(connection, params={})
raise IncapableOfUpdateMethods.new("Cannot update content without stored request") if request.nil?
request.api.get(object.id, connection, params={})
end

# Load the next page of the response if paging is available
def next_page; page("next"); end
def previous_page; page("previous"); end

# Load a specific page of results if available:
def page(pg, pp=25)
if pg.is_a?(String)
if object.paging
if page_url = object.paging[pg]
data = page_url.match(/\?(\S+)/)[1].split("&").collect{|pair| pair.split("=")}.select{|k,v| k!="access_token"}
params = Hash.new
data.each {|k,v| params[k.to_sym] = v}
return request.repeat(params)
end
end
else
return request.repeat(:limit=>pp, :offset=>(pg-1)*pp)
end
return nil
end


# Delete this node from the graph
def delete
raise IncapableOfUpdateMethods.new("Cannot update content without stored request") if request.nil?
request.api.delete(object.id)
end

# Like this node, if supported
def like
raise IncapableOfUpdateMethods.new("Cannot update content without stored request") if request.nil?
request.api.post(object.id, "likes")
end

# Unlike this node, if supported
def unlike
raise IncapableOfUpdateMethods.new("Cannot update content without stored request") if request.nil?
request.api.delete(object.id, "likes")
end


# What keys are available on this OpenGraph node?
def keys
object.is_a?(Hash) ? object.keys.collect{|k|k.to_sym} : Array.new
end

# Include our return top-level keys in the methods list:
def methods()
keys + super()
end

# Use method-missing to provide top-level keys of response Hash as methods
def method_missing(m, *args, &block)
content.include?(m.to_s) ? content[m.to_s] : nil
object.include?(m.to_s) ? object.send(m.to_s) : super(m, args)
end

end # GraphResponse
Expand Down

0 comments on commit e94fb9d

Please sign in to comment.