Class: RETS::Base::Core
- Inherits:
-
Object
- Object
- RETS::Base::Core
- Defined in:
- lib/rets/base/core.rb
Constant Summary collapse
- GET_OBJECT_DATA =
["object-id", "description", "content-id", "content-description", "location", "content-type", "preferred"]
Instance Attribute Summary collapse
-
#request_hash ⇒ String
readonly
Can be called after any Core call that hits the RETS Server.
-
#request_size ⇒ String
readonly
Can be called after any Core call that hits the RETS Server.
-
#request_time ⇒ Float
readonly
Can be called after any #get_object or #search call that hits the RETS Server.
-
#rets_data ⇒ Hash
readonly
Can be called after any Core call that hits the RETS Server.
Instance Method Summary collapse
-
#get_metadata(args) {|:type, :attrs, :metadata| ... } ⇒ Object
Requests metadata from the RETS server.
-
#get_object(args) {|:headers, :content| ... } ⇒ Object
Requests an object from the RETS server.
-
#has_capability?(type) ⇒ Boolean
Whether the RETS server has the requested capability.
-
#initialize(http, urls) ⇒ Core
constructor
A new instance of Core.
-
#logout ⇒ Object
Attempts to logout of the RETS server.
-
#search(args) {|:data| ... } ⇒ Object
Searches the RETS server for data.
Constructor Details
#initialize(http, urls) ⇒ Core
Returns a new instance of Core.
26 27 28 29 |
# File 'lib/rets/base/core.rb', line 26 def initialize(http, urls) @http = http @urls = urls end |
Instance Attribute Details
#request_hash ⇒ String (readonly)
Can be called after any RETS::Base::Core call that hits the RETS Server.
13 14 15 |
# File 'lib/rets/base/core.rb', line 13 def request_hash @request_hash end |
#request_size ⇒ String (readonly)
Can be called after any RETS::Base::Core call that hits the RETS Server.
9 10 11 |
# File 'lib/rets/base/core.rb', line 9 def request_size @request_size end |
#request_time ⇒ Float (readonly)
Can be called after any #get_object or #search call that hits the RETS Server.
17 18 19 |
# File 'lib/rets/base/core.rb', line 17 def request_time @request_time end |
#rets_data ⇒ Hash (readonly)
Can be called after any RETS::Base::Core call that hits the RETS Server.
24 25 26 |
# File 'lib/rets/base/core.rb', line 24 def rets_data @rets_data end |
Instance Method Details
#get_metadata(args) {|:type, :attrs, :metadata| ... } ⇒ Object
Requests metadata from the RETS server.
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/rets/base/core.rb', line 75 def (args, &block) raise ArgumentError, "No block passed" unless block_given? unless @urls[:getmetadata] raise RETS::CapabilityNotFound.new("No GetMetadata capability found for given user.") end @request_size, @request_hash, @request_time, @rets_data = nil, nil, nil, nil @http.request(:url => @urls[:getmetadata], :read_timeout => args[:read_timeout], :params => {:Format => :COMPACT, :Type => args[:type], :ID => args[:id]}) do |response| stream = RETS::StreamHTTP.new(response) sax = RETS::Base::SAXMetadata.new(block) Nokogiri::XML::SAX::Parser.new(sax).parse_io(stream) @request_size, @request_hash = stream.size, stream.hash @rets_data = sax.rets_data end nil end |
#get_object(args) {|:headers, :content| ... } ⇒ Object
Requests an object from the RETS server.
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 |
# File 'lib/rets/base/core.rb', line 122 def get_object(args, &block) raise ArgumentError, "No block passed" unless block_given? unless @urls[:getobject] raise RETS::CapabilityNotFound.new("No GetObject capability found for given user.") end req = {:url => @urls[:getobject], :read_timeout => args[:read_timeout], :headers => {}} req[:params] = {:Resource => args[:resource], :Type => args[:type], :Location => (args[:location] ? 1 : 0), :ID => args[:id]} if args[:accept].is_a?(Array) req[:headers]["Accept"] = args[:accept].join(",") else req[:headers]["Accept"] = "image/png,image/gif,image/jpeg" end # Will get swapped to a streaming call rather than a download-and-parse later, easy to do as it's called with a block now start = Time.now.utc.to_f @request_size, @request_hash, @request_time, @rets_data = nil, nil, nil, nil @http.request(req) do |response| body = response.read_body @request_time = Time.now.utc.to_f - start @request_size, @request_hash = body.length, Digest::SHA1.hexdigest(body) # Make sure we aren't erroring if body =~ /(<RETS (.+)\>)/ # RETSIQ (and probably others) return a <RETS> tag on a location request without any error inside # since parsing errors out of full image data calls is a tricky pain. We're going to keep the # loose error checking, but will confirm that it has an actual error code code, text = @http.get_rets_response(Nokogiri::XML($1).xpath("//RETS").first) unless code == "0" @rets_data = {:code => code, :text => text} if code == "20403" return else raise RETS::APIError.new("#{code}: #{text}", code, text) end end end # Using a wildcard somewhere if response.content_type == "multipart/parallel" boundary = response.type_params["boundary"] boundary.gsub!(/^"|"$/, "") parts = body.split("--#{boundary}\r\n") parts.last.gsub!("\r\n--#{boundary}--", "") parts.each do |part| part.strip! next if part == "" headers, content = part.split("\r\n\r\n", 2) parsed_headers = {} headers.split("\r\n").each do |line| name, value = line.split(":", 2) next unless value and value != "" parsed_headers[name.downcase] = value.strip end # Check off the first children because some Rap Rets seems to use RETS-Status # and it will include it with an object while returning actual data. # It only does this for multipart requests, single image pulls will use <RETS> like it should. if parsed_headers["content-type"] == "text/xml" code, text = @http.get_rets_response(Nokogiri::XML(content).children.first) next if code == "20403" end if block.arity == 1 yield parsed_headers else yield parsed_headers, content end end # Either text (error) or an image of some sorts, which is irrelevant for this else headers = {} GET_OBJECT_DATA.each do |field| next unless response.header[field] and response.header[field] != "" headers[field] = response.header[field].strip end if block.arity == 1 yield headers else yield headers, body end end end nil end |
#has_capability?(type) ⇒ Boolean
Whether the RETS server has the requested capability.
52 53 54 |
# File 'lib/rets/base/core.rb', line 52 def has_capability?(type) @urls.has_key?(type) end |
#logout ⇒ Object
Attempts to logout of the RETS server.
37 38 39 40 41 42 43 44 45 |
# File 'lib/rets/base/core.rb', line 37 def logout unless @urls[:logout] raise RETS::CapabilityNotFound.new("No Logout capability found for given user.") end @http.request(:url => @urls[:logout]) nil end |
#search(args) {|:data| ... } ⇒ Object
Searches the RETS server for data.
245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 |
# File 'lib/rets/base/core.rb', line 245 def search(args, &block) # puts "starting search..." if !block_given? and args[:count_mode] != :only raise ArgumentError, "No block found" end unless @urls[:search] raise RETS::CapabilityNotFound.new("Cannot find URL for Search call") end req = {:url => @urls[:search], :read_timeout => args[:read_timeout]} req[:params] = {:Format => "COMPACT-DECODED", :SearchType => args[:search_type], :QueryType => "DMQL2", :Query => args[:query], :Class => args[:class], :Limit => args[:limit], :Offset => args[:offset], :RestrictedIndicator => args[:restricted]} req[:params][:Select] = args[:select].join(",") if args[:select].is_a?(Array) req[:params][:StandardNames] = 1 if args[:standard_names] if args[:count] == 1 req[:params][:Count] = 2 elsif args[:count_mode] == :both req[:params][:Count] = 1 end @request_size, @request_hash, @request_time, @rets_data = nil, nil, nil, {} # puts "req: #{req.to_s}" start = Time.now.utc.to_f @http.request(req) do |response| # puts "URL: #{req[:url]}" if args[:disable_stream] stream = StringIO.new(response.body) @request_time = Time.now.utc.to_f - start else stream = RETS::StreamHTTP.new(response) end sax = RETS::Base::SAXSearch.new(@rets_data, block) Nokogiri::XML::SAX::Parser.new(sax).parse_io(stream) if args[:disable_stream] @request_size, @request_hash = response.body.length, Digest::SHA1.hexdigest(response.body) else @request_size, @request_hash = stream.size, stream.hash end end nil end |