I want to do a GET request like that using the standard Ruby client net/http:
stores/?ids=2,24,13
I'm trying to do it this way, where store_ids is an array of ids, but it is not working. If I pass a single id as a param for ids, the response is correct.
def get_stores_info
uri = URI(BASE_URL)
params = { ids: store_ids, offset: DEFAULT_OFFSET, limit: DEFAULT_LIMIT }
uri.query = URI.encode_www_form(params)
response = Net::HTTP.get_response(uri).body
result = JSON.parse response
end
You can transform store_ids to string:
store_ids = [2,24,13]
params = { ids: store_ids.join(','), offset: 0, limit: 25 }
# these are to see that it works.
encoded = URI.encode_www_form(params) # => "ids=%5B2%2C+24%2C+13%5D&offset=0&limit=25"
CGI.unescape(encoded) # => ids=2,24,13&offset=0&limit=25
Here's a Replit.
Related
List item
Hi,
I need to pytest this function
def lambda_handler(event, context):
message = json.loads(event['Records'][0]['Sns']['Message'])
But it failed by json error
def test_lambda_handler():
event = {
"Records": [
{
"Sns" : { "Message" : "test" }
}
]
}
response = fw_init.lambda_handler( event,"")
JSONDecodeError("Expecting value", s, err.value) from None
E json.decoder.JSONDecodeError: Expecting value: line 1 column 1 (char 0)
Function loads() deserializes JSON from string. You trying to decode "Message" field value as JSON.
lambda_handler function's first argument is a JSON-formatted string, according to AWS documentation.
You need to pass an serialized data to lambda_handler function:
response = fw_init.lambda_handler(json.dumps(event) ,"")
In function lambda_handler() you need to deserialize data first, and then get field value:
def lambda_handler(event, context):
data = json.loads(event)
message = data['Records'][0]['Sns']['Message']
I'm trying to create a List in Dashing and I've managed to bring in my external JSON, but I'm having problems iterating through it to create the new JSON array to post it out to my List widget. Here's the current code:
require 'rubygems'
require 'json'
require 'pp'
name_list = Hash.new({ value: 0 })
SCHEDULER.every '10s' do
json = File.read('/Users/research/inoutdash/sweet_dashboard_project/jobs/list.json')
response = JSON.parse(json)
name_list[response] = {label: response.keys, value: response.values}
send_event('whosHere', { items: name_list.values })
puts response.keys
puts response.values
end
Here's my JSON file it's reading from:
{
"Mike":"Here",
"Jon": "Out"
}
The output to the widget currently looks like this:
MikeJon Here,Out
How to I properly iterate through the parsed json response and pass it to the send_event?
Just in reply to Matt's question:
So what I need is one 'whosHere' event with all the values from the JSON file formatted for the List widget - which needs JSON formatted as label: X, value: Y.
So what I need it to do is format it as a json array with:
label: "Mike", value: "Here"
label: "Jon", value: "Out"
where now it's storing as:
label: Mike,Jon, value:Here,out
You can use collect to accomplish this. It iterates over a collection and returns an Array where each element is the result of a block.
name_list = response.collect { |(name, status)| { :label => name, :value => status } }
# [{:label=>"Mike", :value=>"Here"}, {:label=>"Jon", :value=>"Out"}]
I am doing an mongodb aggregation using mongoid, using ModleName.collection.aggregate(pipeline) . The value returned is an array and not a Mongoid::Criteria, so if a do a first on the array, I get the first element which is of the type BSON::Document instead of ModelName. As a result, I am unable to use it as a model.
Is there a method to return a criteria instead of an array from the aggregation, or convert a bson document to a model instance?
Using mongoid (4.0.0)
I've been struggling with this on my own too. I'm afraid you have to build your "models" on your own. Let's take an example from my code:
class Searcher
# ...
def results(page: 1, per_page: 50)
pipeline = []
pipeline <<
"$match" => {
title: /#{#params['query']}/i
}
}
geoNear = {
"near" => coordinates,
"distanceField" => "distance",
"distanceMultiplier" => 3959,
"num" => 500,
"spherical" => true,
}
pipeline << {
"$geoNear" => geoNear
}
count = aggregate(pipeline).count
pipeline << { "$skip" => ((page.to_i - 1) * per_page) }
pipeline << { "$limit" => per_page }
places_hash = aggregate(pipeline)
places = places_hash.map { |attrs| Offer.new(attrs) { |o| o.new_record = false } }
# ...
places
end
def aggregate(pipeline)
Offer.collection.aggregate(pipeline)
end
end
I've omitted a lot of code from original project, just to present the way what I've been doing.
The most important thing here was the line:
places_hash.map { |attrs| Offer.new(attrs) { |o| o.new_record = false } }
Where both I'm creating an array of Offers, but additionally, manually I'm setting their new_record attribute to false, so they behave like any other documents get by simple Offer.where(...).
It's not beautiful, but it worked for me, and I could take the best of whole Aggregation Framework!
Hope that helps!
I am trying to find a way to get the "shares" count for a google+ post, given the url of the post.
I have searched through stackoverflow and found only the pos.plusone.get method that gets the plus one counts, not the shares:
url = "https://plus.google.com/+JohnBattelle/posts/bpxzZb3z5qt"
mh = { method: "pos.plusones.get", id: "p", params: {nolog: true, id: url, source: "widget", userId: "#viewer", groupId: "#self"}, jsonrpc: "2.0", key: "p", apiVersion: "v1"}
r = Typhoeus::Request.new("https://clients6.google.com/rpc?key=AIzaSyCKSbrvQasunBoV16zDH9R33D88CeLr9gQ", method: :post, body: mh.to_json, headers: {"Accept" => "application/json", "Content-type" => "application/json" } )
x = r.run
x.body
Returns:
"{\n \"id\": \"p\",\n \"result\": {\n \"kind\": \"pos#plusones\",\n \"id\": \"https://plus.google.com/+JohnBattelle/posts/bpxzZb3z5qt\",\n \"isSetByViewer\": false,\n \"metadata\": {\n \"type\": \"URL\",\n \"globalCounts\": {\n \"count\": 58.0\n }\n },\n \"abtk\": \"AEIZW7Sct6yKBGo7SA4ZRVvfJerD/H1RhuV/6YxCYfQC6HfEId6oDE8z43pCF4BPmRuxktNaxNSj\"\n }\n}\n"
I have tried sending the hash 'mh' with different values for method parameter, but each returns Not Found. The various values I tried are:
pos.plus_shares.get
pos.shares.get
pos.plus_share.get
pos.public.shares.get
Has anyone been able to find a way to get the shares counts?
The method you are using is a private/internal Google API. It could change without notice and break your code.
The supported method is activities.get. (I'm not all that familiar with Ruby so the code might be wrong.
activitieId = "z13pxxpyyovky5ayk04cibwrzqbdcr3abtc0k"
apiKey = "AIzaSyCKSbrvQasunBoV16zDH9R33D88CeLr9gQ"
r = Typhoeus::Request.new("https://www.googleapis.com/plus/v1/activities/" + activityId + "?key=" + apiKey } )
x = r.run
activity = JSON.parse(x.body)
resharers = activity.object.resharers.totalItems
The only other way I found out so far is through Nokogiri, Tried the following in rails console:
url = "https://plus.google.com/+JohnBattelle/posts/bpxzZb3z5qt"
file = open(url)
doc = Nokogiri::HTML(file)
puts doc.xpath("//div[#jscontroller='tH7URd']").first.children.xpath("//span[#class='MM jI']").first.children
Returns:
4
which is the correct shared count as of now.
But I would like to see a better way of getting this count..
Thanks to abraham I could figure out the final solution in ruby. Here it is for anyone struggling to get this data:
First, get the redirected url, to overcome the issue related to multiple google plus url formats eg. plus.google.com/u/0/+AccntName/posts/ou2342
def self.get_redirected_url(url)
url_parse = URI.parse(url)
http_response = Net::HTTP.start(url_parse.host, url_parse.port, :use_ssl => url_parse.scheme == 'https') {|http| http.request Net::HTTP::Get.new url_parse.request_uri }
return url if http_response['location'].nil?
http_response['location']
end
Next, extract the user id and post path from the url, and start using the GooglePlus gem to get the job done:
attributes = { plusone_count: 0 , share_count: 0, comment_count: 0 }
redirected_url = URI.parse(get_redirected_url(url))
user_id = redirected_url.request_uri.match(/\+*\w+/).to_s
post_path = redirected_url.request_uri.match(/posts\/\w+/).to_s
person = GooglePlus::Person.get(user_id)
return attributes if person.nil?
cursor = person.list_activities
cursor.each do |item|
item_url = item.attributes['url']
if item_url.match(post_path)
activity_id = item.attributes['id']
activity = GooglePlus::Activity.get(activity_id)
attributes[:plusone_count] = activity.attributes['object']['plusoners'['totalItems']
attributes[:share_count] = activity.attributes['object']['resharers'['totalItems']
attributes[:comment_count] = activity.attributes['object']['replies'['totalItems']
break
end
end
I have a few models in Ruby that I need to send to a Java/RestEasy server via HTTParty/Put.
configuration_mapping.rb:
def as_json(options = {})
{:configGroup => #group, :coordinates => {#key => #value}}
end
def self.put(endpoint, content, tier = 'nursery')
response = HTTParty.put(base_uri + endpoint, json_payload(content))
end
def self.json_payload(content)
{
:body => content.to_json,
:format => :json,
:headers => {"Content-Type" => "application/json", "content-type" => "application/json", "Accept" => "application/json"}
}
end
The JSON gets double escaped:
{ :body=>" {
\"configGroup\":\"test\",
\"coordinates\":{
\"Integration Test Key\":\"moo\"
} } ", :format=>:json, :headers=>{" Content-Type"=>"application/json", "content-type"
=>"application/json", "Accept" =>"application/json" } }
And Jackson JSON parser borks:
2011-11-27 15:34:11,179 ERROR [tp-1442358158-0] [REPORT] []
[asy.core.SynchronousDispatcher] Failed executing PUT
/v1/groups/test/mappings;tester=Integration
Test;tier=qa;timeStamp=-4712-01-01
org.jboss.resteasy.spi.ReaderException:
org.codehaus.jackson.map.JsonMappingException: Can not deserialize
instance of java.lang.String out of START_OBJECT token at [Source:
org.mortbay.jetty.HttpParser$Input#4092fef5; line: 1, column: 22] at
I tried letting httparty convert to json for me, thinking httparty escaped the characters, writing my own as_json method, but this is the output which is not the json I wanted, the wrong fields are in here and my as_json method is not called:
{:body=>Config::Client::ConfigurationMapping:0x00000100c78930
#dimensions={"tester"=>"Integration Test", "tier"=>"qa",
"timeStamp"=>"-4712-01-01"}, #key="Integration Test Key",
#group="test", #value="moo">, :format=>:json,
:headers=>{"Content-Type"=>"application/json",
"content-type"=>"application/json", "Accept"=>"application/json"}}
What is causing the string to become double escaped?
I figured out the problem, my json wasn't formatted correctly. I reformatted the packet and it worked.