Fetching images binary data from the CRML - ruby

Trying to fetch :all (first :item) from the CRML Media Resource. Using Estately RETS repo. Here is my ruby example file:
require 'rets'
client = Rets::Client.new({
login_url: 'url',
username: 'user',
password: 'password',
version: 'RETS/1.7.2'
})
begin
client.login
rescue => e
puts 'Error: ' + e.message
exit!
end
puts 'We connected! Lets get all the photos for a property...'
photos = client.find (:first), {
search_type: 'Media',
class: 'Media',
query: '(MediaModificationTimestamp=2017-04-15+),(MediaType=Image)'
}
photo = open(photo = photos['MediaURL'])
require 'base64'
image = Base64.encode64(photo.read)
File.open('property-1.gif', 'wb') do|f|
f.write(Base64.decode64(image))
end
puts photos.length.to_s + ' photos saved.'
client.logout
but I'm only getting one image instead of the 26 expected. Not sure also if this will be the best method of retrieving all of the images for all of the listings, after I get the first one working. Here is more information regarding this issue https://github.com/estately/rets/issues/210

require 'rets'
client = Rets::Client.new({
login_url: 'url',
username: 'username',
password: 'password',
version: 'RETS/1.7.2'
})
begin
client.login
rescue => e
puts 'Error: ' + e.message
exit!
end
puts 'We connected! Lets get all the photos for a property...'
photos = client.find (:all), {
search_type: 'Media',
class: 'Media',
query: '(ResourceRecordKeyNumeric=117562969),(MediaType=Image)'
}
photos.each_with_index do |data, index|
photo = open(photo = data['MediaURL'])
puts data['MediaURL']
require 'base64'
image = Base64.encode64(photo.read)
File.open("property-#{index.to_s}.jpg", 'wb') do |f|
f.write(Base64.decode64(image))
end
end
puts photos.length.to_s + ' photos saved.'
client.logout

You can try giving listing IDs comma separated to get all images of multiple listings at a time, in your query part.
photos = client.find (:all), {
search_type: 'Media',
class: 'Media',
query: '(ResourceRecordKeyNumeric=117562969,117562970,117562971),(MediaType=Image)'
}

Related

Rspec is different from the app

I'm currently working on a Ruby/Sinatra App and now I'm stuck because my rspec testing is not working properly on the controller. But when I tried my API using curl or web the code just works!.
Here are my file, spesificly on that line of code
listproduct_controller.rb
get '/' do
products = Product.all
payload = []
products.each do |product|
payload.push({ :exhibit_name => product.exhibit_name, :icon => product.icon })
end
return {
:status => 'SUCCESS',
:message => 200,
:payload => payload
}.to_json
end
and here are my spec file
listproduct_controller_spec.rb
context "GET to /products" do
before { allow(Product).to receive(:all) }
before { allow(Product).to receive(:find_by) }
it "returns status 200 OK" do
get '/'
puts(last_response)
expect(last_response).to be_ok
end
it "show a list of product's name and its icon" do
get '/'
#products = Product.all.to_a
expect(last_response.body).to include_json(#products)
end
end
When I puts the last_response on spec it shows this
500
{"Content-Type"=>"text/html", "Content-Length"=>"212150"}
#<Rack::BodyProxy:0x0000000480b1d8>
but when im using curl or apps it just works and return
200 status code with the payload
Can anyone help me what I did wrong?
UPDATE :
I solved it, it was the problem on the database, where all the product in the development database were not on the test database so it returns 500 of empty database.

Generate XML sub items using iteration

I want to use this Ruby code to generate XML file with 10 terminals:
module WriteXML
def write_data_xml
builder = Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
xml.genesis {
xml.terminals {
/// create here some loop to iterate
xml.terminal {
xml.name "PPRO_Terminal"
xml.type "ppro"
xml.credentials {
xml.username 'user1'
xml.password 'passwd1'
xml.token '5e36e51de2dde626804a8772dc26238c4d722bbc'
}
}}
////////
}
end
puts builder.to_xml
file = File.new("credentials.xml", "w")
File.open('credentials.xml', 'w') do |file|
file << builder.to_xml
end
end
end
How I can use iteration in order to save code when I want to create many terminals?
Depends on where you keep the data that identify these terminals, is that in a table ? Then you could do something like this
def write_data_xml credential
builder = Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
xml.genesis {
xml.terminals {
xml.terminal {
xml.name credential.name
xml.type credential.type
xml.credentials {
xml.username credential.username
xml.password credential.password
xml.token credential.token
}
}}
}
end
File.open("credentials.xml", "a+") { |file| file.write builder.to_xml}
end
end
Suppose you use activerecord you could then
Credentials.each do |credential|
write_data_xml credential
end
If no table, you could use an array of structs where you gather the needed data.
EDIT on request of the OP, here a version that doesn't follow the single responsibility principle
def write_data_xml
builder = Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
xml.genesis {
xml.terminals {
Credentials.each do |credential|
xml.terminal {
xml.name credential.name
xml.type credential.type
xml.credentials {
xml.username credential.username
xml.password credential.password
xml.token credential.token
}
end
}}
}
end
File.write("credentials.xml", builder.to_xml)
end
end
EDIT2
here an example of how to use this with an array of structs since there is no database yet
Credentials = []
Credential = Struct.new(:name, :type, :username, :password, :token)
Credentials << Credential.new('PPRO_Terminal', 'ppro', 'user1', 'passwd1', '5e36e51de2dde626804a8772dc26238c4d722bbc')
Credentials << Credential.new( 'PPRO_Terminal2', 'ppro', 'user2', 'passwd2', '...')
p Credentials
[#<struct Credential name="PPRO_Terminal", type="ppro", username="user1", password="passwd1", token="5e36e51de2dde626804a8772dc26238c4d722bbc">, #<struct Credential name="PPRO_Terminal2", type="ppro", username="user2", password="passwd2", token="...">]
NB at least, create this outside of the method

How do I access the Magento REST API with Ruby?

I want to start working with Magento's REST API, but I can't seem to get it working.
To start with I need to get access tokens, here's what I'm trying:
require 'oauth'
#consumer = OAuth::Consumer.new("4200100753b2c8b03bde1f5b062c5a80", "c06abdcb734c85dfd7bb115c6a67ae4d", {:site=>"http://178.62.173.99/"})
#request_token = #consumer.get_request_token
# => oauth-0.4.7/lib/oauth/consumer.rb:216:in `token_request': 404 Not Found (OAuth::Unauthorized)
But I keep getting a 404 error.
What should I try next?
Here's a Ruby module I've written to create an access token for the Magento REST API:
module Token
def create_consumer
OAuth::Consumer.new(
CONSUMER_KEY,
CONSUMER_SECRET,
:request_token_path => '/oauth/initiate',
:authorize_path=>'/admin/oauth_authorize',
:access_token_path=>'/oauth/token',
:site => URL
)
end
def request_token(args = {})
args[:consumer].get_request_token(:oauth_callback => URL)
end
def get_authorize_url(args = {})
args[:request_token].authorize_url(:oauth_callback => URL)
end
def authorize_application(args = {})
m = Mechanize.new
m.get(args[:authorize_url]) do |login_page|
auth_page = login_page.form_with(:action => "#{URL}/index.php/admin/oauth_authorize/index/") do |form|
form.elements[1].value = ADMIN_USERNAME
form.elements[2].value = ADMIN_PASSWORD
end.submit
authorize_form = auth_page.forms[0]
#callback_page = authorize_form.submit
end
#callback_page.uri.to_s
end
def extract_oauth_verifier(args = {})
callback_page = "#{args[:callback_page]}".gsub!("#{URL}/?", '')
callback_page_query_string = CGI::parse(callback_page)
callback_page_query_string['oauth_verifier'][0]
end
def get_access_token(args = {})
args[:request_token].get_access_token(:oauth_verifier => args[:oauth_verifier])
end
def save_tokens_to_json(args = {})
auth = {}
auth[:time] = Time.now
auth[:token] = args[:access_token].token
auth[:secret] = args[:access_token].secret
File.open("#{args[:path]}#{args[:filename]}.json", 'w') {|f| f.write(auth.to_json)}
auth
end
def get_new_access_tokens
new_consumer = self.create_consumer
new_request_token = self.request_token(consumer: new_consumer)
new_authorize_url = self.get_authorize_url(request_token: new_request_token)
authorize_new_application = self.authorize_application(authorize_url: new_authorize_url)
extract_new_oauth_verifier = self.extract_oauth_verifier(callback_page: authorize_new_application)
new_access_token = self.get_access_token(request_token: new_request_token, oauth_verifier: extract_new_oauth_verifier)
save_tokens_to_json(filename: 'magento_oauth_access_tokens', path: '/', access_token: new_access_token)
return 'Successfully obtained new access tokens.'
end
end
Run #get_new_access_tokens to get an access token.
Don't forget to define the following variable:
CONSUMER_KEY
CONSUMER_SECRET
URL
ADMIN_USERNAME
ADMIN_PASSWORD
Check out mage on rails. It should work right out of the box. Check out this page for annotated ruby code showcasing the oauth flow

Validate In-App-Purchase Android/Google on Server side

I would like to use the purchase token from the in app purchases in an android app to validate it to the google server on my own server.
With the following code I can validate a token, but I have to authenticate myself with my OAuth credentials every time:
class GooglePlayVerification
require 'google/api_client'
# Refer:
# https://code.google.com/p/google-api-ruby-client/issues/detail?id=72
# and
# http://jonathanotto.com/blog/google_oauth2_api_quick_tutorial.html
# and
# http://milancermak.wordpress.com/2012/08/24/server-side-verification-of-google-play-subsc/
GOOGLE_KEY = 'xxx.apps.googleusercontent.com'
GOOGLE_SECRET = 'xxxx'
APP_NAME = 'xx.xx.xx'
SCOPE = "https://www.googleapis.com/auth/androidpublisher"
def self.token
##token ||= begin
require 'oauth2'
raise "Missing client_id variable" if GOOGLE_KEY.to_s.empty?
raise "Missing client_secret variable" if GOOGLE_SECRET.to_s.empty?
raise "Missing scope variable" if SCOPE.to_s.empty?
redirect_uri = 'https://localhost/oauth2callback'
auth_client_obj = OAuth2::Client.new(GOOGLE_KEY, GOOGLE_SECRET, {:site => 'https://accounts.google.com', :authorize_url => "/o/oauth2/auth", :token_url => "/o/oauth2/token"})
puts "1) Paste this URL into your browser where you are logged in to the relevant Google account\n\n"
puts auth_client_obj.auth_code.authorize_url(:scope => SCOPE, :access_type => "offline", :redirect_uri => redirect_uri, :approval_prompt => 'force')
puts "\n\n\n2) Accept the authorization request from Google in your browser:"
puts "\n\n\n3) Google will redirect you to localhost, but just copy the code parameter out of the URL they redirect you to, paste it here and hit enter:\n"
code = gets.chomp.strip
access_token_obj = auth_client_obj.auth_code.get_token(code, {:redirect_uri => redirect_uri, :token_method => :post})
puts "Result: #{access_token_obj.inspect}\n\n"
puts "Token is: #{access_token_obj.token}"
puts "Refresh token is: #{access_token_obj.refresh_token}"
{
:access_token => access_token_obj.token,
:refresh_token => access_token_obj.refresh_token,
:expires_in => access_token_obj.expires_in,
:expires_at => access_token_obj.expires_at
}
end
end
def self.refresh_token
refresh_client_obj = OAuth2::Client.new(GOOGLE_KEY, GOOGLE_SECRET, {:site => 'https://accounts.google.com', :authorize_url => '/o/oauth2/auth', :token_url => '/o/oauth2/token'})
refresh_access_token_obj = OAuth2::AccessToken.new(refresh_client_obj, token[:access_token], {refresh_token: token[:refresh_token]})
refresh_access_token_obj.refresh!
puts "refresh token: #{refresh_access_token_obj.inspect}"
##token = {
:access_token => refresh_access_token_obj.token,
:refresh_token => refresh_access_token_obj.refresh_token,
:expires_in => refresh_access_token_obj.expires_in,
:expires_at => refresh_access_token_obj.expires_at
}
end
# ie. https://developers.google.com/android-publisher/v1/
# eg.
# #subscription_id com.stocklight.stocklight.standardsubscription
# #purchase_token xxx
def self.verify_subscription(subscription_id, purchase_token)
response = RestClient.get "https://www.googleapis.com/androidpublisher/v1.1/applications/#{APP_NAME}/inapp/#{subscription_id}/purchases/#{purchase_token}?access_token=#{token[:access_token]}"
puts "Respnse \n #{response.inspect}"
puts response.code == 200
puts JSON.parse(response)
return response.code == 200 && JSON.parse(response)['kind'] =='androidpublisher#inappPurchase'
rescue
return false
end
end
Has anyone an idea how to authenticate a server without such things like OAuth on the server? Is there another authentification possibility?
Thanks!
Here is my ruby code:
def self.verify_subscription(subscription_id, transaction_id)
json = JSON.parse(transaction_id)
order = ["orderId", "packageName", "productId", "purchaseTime", "purchaseState", "purchaseToken"]
signature = json["signature"]
data = {}
order.each do |o|
data[o] = json[o]
end
key = OpenSSL::PKey::RSA.new(Base64.decode64(GOOGLE_PUBLIC_KEY))
verified = key.verify(OpenSSL::Digest::SHA1.new, Base64.decode64(signature), data.to_json)
verified
end

Illegal characters in email when sent via smtp with Sendgrid on Rails 3.1.3

I am importing a list of contacts from gmail and using a checkbox to select the returned emails and send an invitation out to users after they have been selected. When I look at the my logs the output has the email in the correct format and everything seems fine.
When I look at my email activity on Sendgrid I am seeing additional characters attached to the email address hence making it fail. I do not have any issues sending email with my other mailers using sendmail but this one seems to add these additional characters and I do not know where they are coming from.
Has anyone else seen this happening? Or have a suggestion on how to fix this?
Expected result
Email: test#gmail.com
Actual result
Email: "test#gmail.com"#i04-01
user_mailer
def invitation(email_addresses)
#host = ((Rails.env == "production") ? "http://www.test.com" : "http://localhost:3000")
attachments.inline['people.jpg'] = File.read("#{Rails.root}/app/assets/images/people.jpg")
#attachments.inline['people.jpg'] = File.read("#{Rails.root}/app/assets/images/Girl.jpeg")
email_addresses.each do |email|
mail(:to => email, :subject => "Hello from test!")
end
end
user_controller
def import
##user = User.find(params[:id])
##users = User.find(session[:user_id])
begin
#sites = {"gmail" => Contacts::Gmail, "yahoo" => Contacts::Yahoo, "hotmail" => Contacts::Hotmail}
#contacts = #sites[params[:from]].new(params[:login], params[:password]).contacts
#users, #no_users = [], []
#contacts.each do |contact|
#if u = User.find(:first , :conditions => #users.email = �#{contact[1]}� , :include =>[:user])
if u = User.find(:first, :conditions => "email = '#{contact[1]}'")
#users << u
else
#no_users << {:name => contact[0], :email => contact[1]}
end
end
#if #contacts.save
#end
respond_to do |format|
format.html { render :template => 'shared/_contact_list', :layout => false }
format.xml { render :xml => #contacts.to_xml }
end
end
end
def send_bulk_mail
name_email =[]
email_addresses=[]
names=[]
post=params[:post]
post.each do |k,v|
if v=="1"
name_email << k
end
end
name_email.each do |n|
email_addresses << n.split(",")[1]
end
UserMailer.invitation(email_addresses).deliver
end
Thanks

Resources