Class: TAPI::V3::Client

Inherits:
Object
  • Object
show all
Includes:
Configurable
Defined in:
lib/tapi/v3/client.rb

Constant Summary collapse

HTTP_ERRORS =
{
  302 => MovedError,
  205 => ExpiredError,
  401 => InternalServerError,
  404 => NotFoundError,
  500 => InternalServerError
}

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Configurable

#config, included

Constructor Details

#initialize(hash, etag = nil, is_root = false) ⇒ Client

end class methods



121
122
123
124
125
126
# File 'lib/tapi/v3/client.rb', line 121

def initialize(hash, etag = nil, is_root = false)
  @document = {}
  @etag = etag if etag

  update(hash)
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(key, *args) ⇒ Object (protected)



205
206
207
208
209
210
211
212
213
214
215
216
# File 'lib/tapi/v3/client.rb', line 205

def method_missing(key, *args)
  if @document.has_key?(key)
    @document[key]
  else
    if url = urls["#{url_key(key)}_url".to_sym]
      options = args.first || {}
      get(url, client_class(key), options)
    else
      raise NoMethodError, "undefined method `#{key}' for #{self.class}", caller
    end
  end
end

Instance Attribute Details

#documentObject (readonly)

Returns the value of attribute document.



13
14
15
# File 'lib/tapi/v3/client.rb', line 13

def document
  @document
end

#etagObject (readonly)

Returns the value of attribute etag.



13
14
15
# File 'lib/tapi/v3/client.rb', line 13

def etag
  @etag
end

Class Method Details

.base_urlObject



106
107
108
# File 'lib/tapi/v3/client.rb', line 106

def base_url
  config[:base_url] || ""
end

.check_for_errors(curl) ⇒ Object



47
48
49
50
51
52
53
54
55
56
57
58
# File 'lib/tapi/v3/client.rb', line 47

def check_for_errors(curl)
  error_class = HTTP_ERRORS[curl.response_code]
  error_class ||= Error if (401..599).include?(curl.response_code)

  if error_class
    error = error_class.new
    error.request_url = curl.url
    error.response_code = curl.response_code
    error.response_body = curl.body_str
    raise error 
  end
end

.execute_request(method, url, params, etag = nil) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/tapi/v3/client.rb', line 64

def execute_request(method, url, params, etag = nil)
  url = base_url + url
  url = Utils.append_query(url, params) if Hash === params and method == :get
  
  curl = Curl::Easy.new(url)
  
  if auth = http_authentication
    curl.userpwd = auth
  end
  
  curl.headers["If-None-Match"] = etag if etag
  
  server_etag = nil          

  time = Time.now
  case method
  when :get
    curl.http_get
    server_etag = parse_etag(curl.header_str)
    
  when :post
    fields = params.to_a.map {|key, value| Curl::PostField.content(key.to_s, value.to_s)}

    curl.http_post(fields)
  end

  logger.debug "TAPI #{method.to_s.upcase} #{Time.now - time} #{url} #{params.inspect} #{etag} #{server_etag}"
  
  check_for_errors(curl)          

  [curl, server_etag]
end

.http_authenticationObject



25
26
27
# File 'lib/tapi/v3/client.rb', line 25

def http_authentication
  self.class.http_authentication
end

.loggerObject



98
99
100
# File 'lib/tapi/v3/client.rb', line 98

def logger
  Thread.current[:tapi_logger] || Logger.new(STDOUT)
end

.logger=(logger) ⇒ Object



102
103
104
# File 'lib/tapi/v3/client.rb', line 102

def logger=(logger)
  Thread.current[:tapi_logger] = logger
end

.new_from_get(url, options = {}, etag = nil) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/tapi/v3/client.rb', line 34

def new_from_get(url, options = {}, etag = nil)
  klass = options.delete(:instanciate_as) || self
  curl, server_etag = execute_request(:get, url, options, etag)

  if server_etag && etag == server_etag
    logger.debug "Known ETag."
    [nil, server_etag]
  else
    logger.debug "Unknown ETag."
    [klass.new(JSON.parse(curl.body_str), server_etag, true), server_etag]
  end
end

.new_from_post(url, params) ⇒ Object



29
30
31
32
# File 'lib/tapi/v3/client.rb', line 29

def new_from_post(url, params)
  curl, server_etag = execute_request(:post, url, params)
  new(JSON.parse(curl.body_str), nil, true)
end

.parse_etag(str) ⇒ Object



60
61
62
# File 'lib/tapi/v3/client.rb', line 60

def parse_etag(str)
  str.split("\r\n").grep(/^etag/i).first.split(' ').last if str =~ /^etag/i
end

Instance Method Details

#attributesObject



150
151
152
# File 'lib/tapi/v3/client.rb', line 150

def attributes
  @document.keys.map(&:to_s)
end

#class_mappingObject



178
179
180
# File 'lib/tapi/v3/client.rb', line 178

def class_mapping
  config[:class_mapping] ||= {}
end

#loggerObject



128
129
130
# File 'lib/tapi/v3/client.rb', line 128

def logger
  self.class.logger
end

#remote_callsObject



164
165
166
# File 'lib/tapi/v3/client.rb', line 164

def remote_calls
  urls.keys.map{|resource| "fetch_#{/(.*)_url$/.match(resource.to_s)[1]}"}.sort
end

#respond_to?(key, include_private = false) ⇒ Boolean

Returns:

  • (Boolean)


172
173
174
175
176
# File 'lib/tapi/v3/client.rb', line 172

def respond_to?(key, include_private = false)
  @document.has_key?(key) or
    urls["#{url_key(key)}_url".to_sym] or
    super(key, include_private)
end

#to_hashObject



134
135
136
137
138
139
140
141
142
143
144
# File 'lib/tapi/v3/client.rb', line 134

def to_hash
  @document.inject({}) do |hash, (key, val)|
    hash[key] = \
    case val
    when Client then val.to_hash
    when Array then val.map {|v| Client === v ? v.to_hash : v }
    else val
    end
    hash
  end
end

#to_jsonObject



146
147
148
# File 'lib/tapi/v3/client.rb', line 146

def to_json
  to_hash.to_json
end

#to_paramObject



168
169
170
# File 'lib/tapi/v3/client.rb', line 168

def to_param
  id
end

#urlsObject



154
155
156
157
158
159
160
161
162
# File 'lib/tapi/v3/client.rb', line 154

def urls
  if search = @document[:search]
    search.urls
  elsif @document[:resources]
    @document[:resources].to_hash
  else
    Hash.new
  end
end