Ruby simple Web Service client performing a call to Solr - ruby

I need some help in doing this: I have to build the following URL in order to perform a query aganst an Apache Solr instance:
http://localhost:8080/solr/select?q=*%3A*&fq=deal_discount%3A[20+TO+*]&fq=deal_price%3A[*+TO+100]&fq={!geofilt+pt%3D45.6574%2C9.9627+sfield%3Dlocation_latlng+d%3D600}
As you can see, the URL contains 3 times the parameter named "fq". What I'm just wondering is how to use the URI.parse() method if I need to pass three times the parameter "fq" within the Hash that is the second argument of the parse() method.
Here's a simple snippet:
path = 'http://localhost:8080/solr/select'
pars = { 'fq' => 'deal_price [* TO 100]', 'fq' => '{!geofilt pt=45.6574,9.9627 sfield=location_latlng d=600}' } # This is obviously wrong!
res = Net::HTTP::post_form( URI.parse(path), pars )
The solution would be passing the full URL as a String, but I cannot find a method that provide this kind of signature.
Could you please post a simple solution to my problem? Thanks in Advance.

Thaks for your help. Yes, you're right... A get method was what I need. Anyway I had to make a little change to your code because Net:HTTP.get() threw an exception "Unknown method hostname"
uri = URI(solrUrl)
req = Net::HTTP::Get.new(uri.request_uri)
res = Net::HTTP.start(uri.hostname, uri.port) {|http|
http.request(req)
}
This solved my problem. Thanks indeed.

Your URL suggest that you should use HTTP GET to query solr while your snippet uses POST so that is one thing to change. But I think your main problem is with the parameters, a Hash may only contain one entry for a key so you can't use a Hash in this case. One easy way is to construct the URL by hand.
params_array = ['deal_price [* TO 100]',
'{!geofilt pt=45.6574,9.9627 sfield=location_latlng d=600}']
base_url = "http://localhost:8080/solr/select"
query_string = "?fq=#{params_array.join('&fq=')}"
url = base_url + query_string
result = Net::HTTP.get url
A bit compact maybe - a more readable version may be (according to taste):
params_array = ['deal_price [* TO 100]',
'{!geofilt pt=45.6574,9.9627 sfield=location_latlng d=600}']
url = "http://localhost:8080/solr/select&"
params_array.each do |param|
url << "&fq=#{param}"
end
result = Net::HTTP.get url

Related

Ruby URI: build URI with "param[]=value" for array params

I'm trying to query an API (lichess API). And I can't get the params to be correctly taken into account, because URI formats the URL not in the expected format for array params.
The expected format is this one: curl https://explorer.lichess.ovh/lichess?ratings[]=2200&ratings[]=2500. So the ratings params is an Array of values, and the url should be using ratings[]=value.
I'm currently generating my URI like this, as per the doc:
base = "https://explorer.lichess.ovh/master"
params = {
ratings: [1600, 1800]
}
uri = URI(base)
uri.query = URI.encode_www_form(params)
But this generate the URL like this: https://explorer.lichess.ovh/master?ratings=1600&ratings=1800... which is not the expected format, and is not understood by Lichess API.
Does Ruby provide any built-in way to generate the params in the expected format, or will I need to build the URL manually (which feels like revinventing the wheel)?
Rails/ActiveSupport has a to_query method which will do what you want.
2.1.5 :010 > params.to_query
=> "ratings%5B%5D=1600&ratings%5B%5D=1800"
Also, have a look at this comment which explains why URI.encode_www_form doesn't return square brackets.

Ruby return's HTTPVersionNotSupported object

I'm trying to make a get request to a service of mine with a valid URL string (if I put it into my browser, I get the expected response). However, when I run the following function:
def dispatch_uri(url)
uri = Addressable::URI.parse(url)
http = Net::HTTP.new(uri.host, uri.port)
request = Net::HTTP::Get.new(uri.request_uri)
response = http.request(request).to_s
response
end
The response variable holds a Net::HTTPVersionNotSupported, which has no body and isn't, of course, the expected response.
What am I doing wrong and how should I address this problem?
So, the answer is simpler than I thought.
Net::HTTP is both unable to work with an UTF-8 URL or Addressable::URI, however, Addressable gives us a fantastic tool to solve this problem: normalize.
Normalize converts your UTF=8 to a codified ASCII HTML compatible string, so a working code is:
def dispatch_uri(url)
uri = URI(Addressable::URI.parse(url).normalize.to_s)
response = Net::HTTP.get(uri)
response
end
This normalized string can be used to create a standard URI object and, thus, you are able to use a regular Net::HTTP request.

How to get the full URL of the route?

I have a Sinatra template file, which sends a POST request to the route /en/signup (en is the locale).
I need to extract the en from /en/signup. I tried to use request.path in the following code, but contains only /signup, not /en/signup. The log file shows that /en/signup was called.
What construct can I use in the route post '/signup' in order to get /en/signup?
Wake up, Neo.
From route file:
before '/:locale/*' do
I18n.locale = params[:locale]
request.path_info = '/' + params[:splat ][0]
end
That solved my problem: redirect to('/' + I18n.locale.to_s + '/signup-success').
If you can use java:
var url = document.URL;
var pieces = url.split("/");
Then simply split where and when you need to. The variable pieces is an array. For further splitting use pieces = pieces[1 (or others) ].split("/ (or others ");
I hope this helps!
Hello Sir if you use php try the code below. it will get the full path of the url for instance /example/en/signup.
$_SERVER['REQUEST_URI']
In Addition you can get including the http host (localhost) try the code below
$output = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
echo $output;

Differences of body vs body_stream in HttpGenericRequest

What is the differences between body vs body_stream in Net::HttpGenericRequest. Documentation says...empty.
Example code:
uri = URI('http://www.example.com/todo.cgi')
req = Net::HTTP::Post.new(uri.path)
req.body = "ABCDEF"
req.body_stream = "ABCDEF" # Any difference?
I believe the difference is in what kind of argument each one receives, as you can see at the documentation.
http://ruby-doc.org/stdlib-1.9.3/libdoc/net/http/rdoc/Net/HTTPGenericRequest.html#method-i-body-3D
Net::HTTPGenericRequest#body receive a string as argument.
req.body("ABCDEF")
Net::HTTPGenericRequest#body_stream receive a input as argument.
req.body_stream(File.open("/tmp/example.txt"))
I hope this helps you.

Post nested params (hash) using HTTPClient

I needed a to have a multipart http post from one app to another that included a file attachment and a nested params hash. I tried using HTTPClient which worked for the file attachment, however I could not get params to send in a nested format.
data_params = Hash.new
data_params[:params] = Hash.new
data_params[:params][:f] = Hash.new
data_params[:params][:d] = Hash.new
data_params[:params][:d][:name] = "Mich"
data_params[:params][:d][:city] = "Ostin"
data_params[:params][:f][:event] = "Sundance"
http_client = HTTPClient.new
body = data_params[:params]
response = http_client.post('http://localhost:3030/receiver/receive_test_data/', body)
with the receiver app seeing the params as {"d"=>"nameMichcityOstin","f"=>"eventSundance"} (with the hash collapsed into strings on the nested level)
I wonder if this is a limitation on http posts or am I simply doing something wrong. I have worked with JSON before, which I know supports a nested structure, but there I have no idea how to add file attachments. I appreciate any suggestions or alternative methods that would comply with 'best practices' on doing something like this.
If using Rails:
> {:a=>53,:b=>{:c=>7}}.to_query
=> "a=53&b[c]=7"
http://apidock.com/rails/ActiveSupport/CoreExtensions/Hash/to_query
I'm not sure which HTTPClient library you're using so I haven't been able to try this, but what if you use keys like this
data_params[:params]['d[name]'] = "Mich"
data_params[:params]['d[city]'] = "Ostin"
i.e. data_params[:params] is just a one level hash.
and then the receiving application will unpack this into the nested hash that you expect.

Resources