Can't get value from nested pair in Omniauth hash. - ruby

I'll try to keep this simple, my previous wording was maybe a bit too verbose:
Here is the example Omniauth hash: https://github.com/mkdynamic/omniauth-facebook
I can access and save some values from this but not others. The field is writable, so I know its just my syntax (beginner, sorry!)
{
:provider => 'facebook',
:uid => '1234567',
:info => {
:nickname => 'jbloggs',
:email => 'joe#bloggs.com',
:name => 'Joe Bloggs',
:first_name => 'Joe',
:last_name => 'Bloggs',
:image => 'http://graph.facebook.com/1234567/picture?type=square',
:urls => { :Facebook => 'http://www.facebook.com/jbloggs' },
:location => 'Palo Alto, California',
:verified => true
},
:credentials => {
:token => 'ABCDEF...', # OAuth 2.0 access_token, which you may wish to store
:expires_at => 1321747205, # when the access token expires (it always will)
:expires => true # this will always be true
},
:extra => {
:raw_info => {
:id => '1234567',
:name => 'Joe Bloggs',
:first_name => 'Joe',
:last_name => 'Bloggs',
:link => 'http://www.facebook.com/jbloggs',
:username => 'jbloggs',
:location => { :id => '123456789', :name => 'Palo Alto, California' },
:gender => 'male',
:email => 'joe#bloggs.com',
:timezone => -8,
:locale => 'en_US',
:verified => true,
:updated_time => '2011-11-11T06:21:03+0000'
}
}
}
I can do this to get gender and save it.
location:auth.extra.raw_info["gender"]
Obviously though I dont want to save gender to location. I want to get "Palo Alto" and save it. But this doesn't work.
location.auth.extra.raw_info["location"]["name"]
What am I doing wrong? When I try it in console, I'm able to get the value.

try this
location.auth.extra.raw_info.location.name
or this
location.auth.extra.raw_info[:location][:name]

Yeah, what you suggested was what I was trying...and it turns out we were right but FB had changed how that hash was set up so it wasn't working. Lesson learned: subscribe FB's notifications next time :)

Related

ruby on rails using the paypal gem don' return the payer id

I want to user the paypal gem for ruby on rails to do the paying stuff with.
Most of the suff works fine, but I don't get the payer ID, for the last step the payment.execute() I need the payerID
my code looks like this:
##################################################################################
# Build Payment object
#payment = Payment.new({
:intent => "sale",
:payer => {
:payment_method => "paypal"
},
:redirect_urls => {
:return_url => url_for(:controller=>:movies,:action=>:play,:id=>#movie.id),
:cancel_url => url_for(:controller=>:movies,:action=>:play,:id=>#movie.id)},
:transactions => [{
:item_list => {
:items => [{
:name => #movie.movietitle,
:sku => "item",
:price => #movie.movieprice,
:currency => "USD",
:quantity => 1 }]},
:amount => {
:total => #movie.movieprice,
:currency => "USD" },
:description => "This is the payment transaction description." }]})
# Create Payment and return the status(true or false)
if #payment.create
#payment.id # Payment Id
redirect_to #payment.links[1].href
else
#payment.error # Error Hash
end
how can I get the payerID?
Thanks

How do I correctly call Magento SOAP API with Ruby Savon for Category Product Links?

I am trying to call the catalog_product_link.list API method using Savon. However, I keep receiving the error Error cannot find parameter.
Here is what I am using, though I have tried several variations of the call and still cannot get it to go through correctly:
client = Savon.client(wsdl: 'http://localhost/index.php/api/soap/?wsdl')
response = client.call(:login){message(username: 'user', apiKey: 'key')}
session = response.body[:login_response][:login_return]
#These all do not work
client.call(:call){message(:session => session, :method => 'catalog_product_link.list', :type => 'up_sell', :productId => '166')}
client.call(:call){message(:session => session, :method => 'catalog_product_link.list', :type => 'up_sell', :product => '166')}
client.call(:call){message(:sessionId => session, :resourcePath => 'catalog_product_link.list', :args => {:type => 'up_sell', :product => '166'})}
client.call(:call){message(:sessionId => session, :resourcePath => 'catalog_product_link.list', :args => {:type => 'up_sell', :productId => '166'})}
client.call(:call){message(:sessionId => session, :resourcePath => 'catalog_product_link.list', :arguments => {:type => 'up_sell', :product => '166'})}
Is there a different way to format to get this to work?
UPDATE: If I try removing the type parameter, it gives the error Given invalid link type, so it appears it does not like something about multiple parameters.
response = client.call(:call){message(:session => session, :method => 'catalog_product_link.list', :product => '166')}
I was able to get this to work using Builder:
class ServiceRequest
def initialize(session, type, product)
#session = session
#type = type
#product = product
end
def to_s
builder = Builder::XmlMarkup.new()
builder.instruct!(:xml, encoding: "UTF-8")
builder.tag!(
"env:Envelope",
"xmlns:env" => "http://schemas.xmlsoap.org/soap/envelope/",
"xmlns:ns1" => "urn:Magento",
"xmlns:ns2" => "http://xml.apache.org/xml-soap",
"xmlns:xsd" => "http://www.w3.org/2001/XMLSchema",
"xmlns:xsi" => "http://www.w3.org/2001/XMLSchema-instance"
) do |envelope|
envelope.tag!("env:Body") do |body|
body.tag!("ns1:call") do |call|
builder.sessionId(#session, "xsi:type" => "xsd:string")
builder.resourcePath("catalog_product_link.list", "xsi:type" => "xsd:string")
builder.args("xsi:type" => "ns2:Map") do |args|
args.item do |item|
item.key("type", "xsi:type" => "xsd:string")
item.value(#type, "xsi:type" => "xsd:string")
end
args.item do |item|
item.key("product", "xsi:type" => "xsd:string")
item.value(#product, "xsi:type" => "xsd:string")
end
end
end
end
end
builder.target!
end
end
client.call(:call, xml: ServiceRequest.new(session, 'up_sell', '166').to_s)
Thanks to #rubiii for the direction.

Why am I getting =0A inside emails being sent, where there should be a line break?

I'm getting =0A inside my emails where there should be a line break.
#article = DB[:posts][:nodeview_id => view, :nodeview => 'article']
Pony.mail(:html_body => #article[:content], :reply_to => #email, :subject => "New article #{#article[:title]}", :headers => { "X-MC-Tags" => "feedback" } )
And ##article[:content]} in this context, is
apples
bananas
inside the database, no \n or <br> tags.
Here's how Pony is configured.
Pony.options = { :from => 'Compesh <donotreply#compesh.com>', :to => 'blahblahblah#emails.com',
:via => :smtp, :via_options => {
:address => 'smtp.mandrillapp.com', :port => '587',
:user_name => 'XXX', :password => 'XXXXXX'
},
:headers => { "X-MC-AutoText" => "yes" }, :charset => 'utf-8'
}
But in my emails I get
apples=0Abananas
Pony doesn't let me choose the content type, I don't think.
I managed to fix this by converting newlines to a <br> tag. It turns out it had nothing to do with the content type or encoding of the email at a..
mystring.gsub(/(?:\n\r?|\r\n?)/, '<br>')
This specially general regex function, has a way of covering DOS, *NIX, Mac and accidental invalid line endings.

How to not to pass argument if empty?

I upgraded ruby to 1.9.3 from 1.8.x Not sure if pony gem was upgraded during that process too but the point is that I was using this code to send out an emails
Pony.mail(
:to => to,
:from => from,
:subject => subject,
:body => Nokogiri::HTML(body_with_footer).text,
:html_body => body_with_footer, #.gsub("\n","<BR>"),
:attachments => attachment_to_send,
:via => :smtp,
:via_options => {
:address => $smtp,
:port => $smtp_port,
:enable_starttls_auto => false
}
)
attachment_to_send should be a hash of files to be attached. When the hash was empty no attachment was send. Now I got a pony error complaining about the hash being "".
So I introduced a if condition attachment_to_send=="" so I call pony with or without the attachment part.
Is there any way to manage that? So I have only one code where I call pony?
handled with ternary operator attachment_to_send.empty? ? nil : attachment_to_send
details = {
:to => to,
:from => from,
:subject => subject,
:body => Nokogiri::HTML(body_with_footer).text,
:html_body => body_with_footer, #.gsub("\n","<BR>"),
:attachments => attachment_to_send.empty? ? nil : attachment_to_send ,
:via => :smtp,
:via_options => {
:address => $smtp,
:port => $smtp_port,
:enable_starttls_auto => false
}
Pony.mail(details)
prepare your attachment array by checking empty condition following way,
tmp_hash = {:to => to,
:from => from,
:subject => subject,
:body => Nokogiri::HTML(body_with_footer).text,
:html_body => body_with_footer, #.gsub("\n","<BR>"),
:via => :smtp,
:via_options => {
:address => $smtp,
:port => $smtp_port,
:enable_starttls_auto => false
}
}
and
tmp_hash[:attachments] => attachment_to_send
tmp_hash[:attachments] => nil if attachment_to_send.empty?
or
directly,
tmp_hash[:attachments] => attachment_to_send if not attachment_to_send.empty?
and then
Pony.mail( tmp_hash)
should work

Ruby - multidimensional hash

How do I make this multidimensional? Each search result entry has multiple attributes :attributes => ['sAMAccountName','givenName','SN','mail']. and there can be many entries in the result. This code is good for creating only one entry with multiple attributes.
def self.Find(attribute, loginID)
conn = Net::LDAP.new :host => SERVER,
:port => PORT,
:base => BASE,
:auth => {
:username => 'admin',
:password => 'admin',
:method => :simple
}
if conn.bind
result = HashWithIndifferentAccess.new
conn.search( :base => LDAPBASE,
:filter => Net::LDAP::Filter.eq( attribute, loginID+"*" ),
:attributes => ['sAMAccountName','givenName','SN','mail'],
:return_result => true
).each do |entries|
entries.each do |attribute, values|
values.each do |value|
result[attribute] = value
end
end
end
result
end
end
The actual response I get from ldap is like this -
puts result.to_s
{
"dn"=>"CN=somename\\, somefirstname,OU=Users,DC=site,DC=com",
"sn"=>"somename",
"givenname"=>"somefirstname",
"samaccountname"=>"someuserid",
"mail"=>"someone#somthing.com"
}
Since the search is has * wildcard to find all matching entries. Ldap will return multiple entries in the format above. similar to this -
{
"dn"=>"CN=somename\\, somefirstname1,OU=Users,DC=site,DC=com",
"sn"=>"somename1",
"givenname"=>"somefirstname1",
"samaccountname"=>"someuserid1",
"mail"=>"someone1#somthing.com"
},
{
"dn"=>"CN=somename\\, somefirstname2,OU=Users,DC=site,DC=com",
"sn"=>"somename2",
"givenname"=>"somefirstname2",
"samaccountname"=>"someuserid2",
"mail"=>"someone2#somthing.com"
},
{
"dn"=>"CN=somename\\, somefirstname3,OU=Users,DC=site,DC=com",
"sn"=>"somename3",
"givenname"=>"somefirstname3",
"samaccountname"=>"someuserid3",
"mail"=>"someone3#somthing.com"
},
A[a=>1,b=>11,c=>111]
B[a=>2,b=>22,c=>222]
C[a=>3,b=>33,c=>333]
D[a=>4,b=>44,c=>444]
I'm not sure that I understood the question.
def self.Find(attribute, loginID)
conn = Net::LDAP.new :host => SERVER,
:port => PORT,
:base => BASE,
:auth => {
:username => 'admin',
:password => 'admin',
:method => :simple
}
if conn.bind
conn.search( :base => LDAPBASE,
:filter => Net::LDAP::Filter.eq( attribute, loginID+"*" ),
:attributes => ['sAMAccountName','givenName','SN','mail'],
:return_result => true
).reduce(Array.new) do |acc, el|
#
# Any modification of the entry must be here
#
acc + [el]
end
end
end
end
I think Array.map is good choice too
My assumption:
conn.search return Array of Hash
the form of result you want:
[
{"uid":"123","displayName":"User 123","mail":"123#example.com"},
{"uid":"456","displayName":"User 456","mail":"456#example.com"},
{"uid":"789","displayName":"User 789","mail":"789#example.com"}
]

Resources