Rails 3.1 mail encoding issue - ruby-on-rails

I have a Payment mailer class that creates email:
class PaymentMailer < ActionMailer::Base
include LocaleWrapper
helper :application
def payment_notification(payment)
host = payment.try(:host)
#payment = payment
#user = payment.user
using_locale((#user && #user.locale) || I18n.locale) {
attachments["#{set_default_domain_name_from(host)}_receipt_#{Time.now.strftime("%Y_%m_%d")}.pdf"] = WickedPdf.new.pdf_from_string(
render_to_string(pdf: "#{set_default_domain_name_from(host)}_receipt_#{Time.now.strftime("%Y_%m_%d")}.pdf", template: filtre_mail_template_by_host(host), layout: "pdf.html"))
headers['Precedence'] = 'bulk'
mail(:to => #user.email, :subject => I18n.t("mailer_subjects.payment_completed"), :from => "no-reply##{set_default_domain_name_from(host)}") do |format|
format.text(:content_transfer_encoding => "base64")
format.html
end
}
end
I have observer method that saves email in the database:
def delivered_email(email)
Rails.logger.info email.inspect
html_body = (email.multipart? ? email.html_part : email).body.to_s
text_body = (email.multipart? ? email.text_part : email).body.to_s
outgoing_mail = OutgoingMail.new({
:to => email.to.join(', '),
:from => email.from.join(', '),
:subject => email.subject.to_s,
:sent_at => email.date,
:html_body => html_body,
:text_body => text_body,
:multipart => email.multipart?,
})
outgoing_mail.save
save_attachments(email, outgoing_mail)
end
Problem is with multipart email's plain text version, which returns ASCII 8bit string and mysql throws Mysql2::Error: Incorrect string value error.
(rdb:1) text_body
"N\x16\xA7\x93*.~\x8A\xF2\xA2\xEA\xDC\xA2{k\x89\xBB\xAD\x8A\x89\xD2y\xEA]}\xABmi\xC8fz{_\xA2\xBAZ\xCAg\xA7\xB5\xD7\xADj)l"
(rdb:1) text_body.encoding
#<Encoding:ASCII-8BIT>
I have tried using #force_encoding method, but there is no success:
(rdb:1) text_body.force_encoding("UTF-8")
"N\u0016\xA7\x93*.~\x8A\xF2\xA2\xEAܢ{k\x89\xBB\xAD\x8A\x89\xD2y\xEA]}\xABmi\xC8fz{_\xA2\xBAZ\xCAg\xA7\xB5\u05EDj)l"
Why am i getting ASCII 8bit string instead of UTF-8?

Related

Switching from Postmark to Postfix

We want to switch from Postmark to Postfix, but with Postfix the mail with the attachment(PDF file) is arriving as garbage:
Date: Sun, 10 Apr 2016 13:17:56 +0300
Mime-Version: 1.0
Content-Type: application/pdf; charset=UTF-8; filename=test_order1460278254278.pdf
Content-Transfer-Encoding: base64
Content-Disposition: attachment; filename=test_order1460278254278.pdf
Content-ID: <570a2854317a9_1c6f12f77f841854#app1.mail>
JVBERi0xLjQKJeLjz9MKNSAwIG9iago8PC9CYXNlRm9udC9QV1dNR1QrQXJp
YWxNVC9EZXNjZW5kYW50Rm9udHNbNiAwIFJdL1R5cGUvRm9udC9TdWJ0eXBl
L1R5cGUwL0VuY29kaW5nL0lkZW50aXR5LUgvVG9Vbmljb2RlIDkgMCBSPj4K
ZW5kb2JqCjEwIDAgb2JqCjw8L0Jhc2VGb250L1dYSkRSSytMdWNpZGFTYW5z
LVR5cGV3cml0ZXJCb2xkL0Rlc2NlbmRhbnRGb250c1sxMSAwIFJdL1R5cGUv
Rm9udC9TdWJ0eXBlL1R5cGUwL0VuY29kaW5nL0lkZW50aXR5LUgvVG9Vbmlj
b2RlIDE0IDAgUj4+CmVuZG9iagoxNSAwIG9iago8PC9CYXNlRm9udC9UaW1l
This is my code:
class UserMailer < ActionMailer::Base
default :from => "mailer#xodapp1.com"
default :bcc => "do_not_reply#xodapp1.com"
default :reply_to => "do_not_reply#xodapp1.com"
def send_email(agent, customer, subject, body, mail_to = nil, mail_cc = nil, url_attachment = nil , name_attachment = nil)
#attachments[name_attachment] = {:content => open(url_attachment).read, :mime_type => MIME::Types.type_for(name_attachment).first} unless url_attachment.nil?
mail_to = !mail_to.nil? ? mail_to : "\"#{customer.name}\" <#{customer.email}>"
mailers_to = mail_to.split(',')
mail_cc = !mail_cc.nil? ? mail_cc.split(',') : agent.email
if [nil, []].include?(mail_cc)
mail_cc = UserMailer.default[:bcc]
end
body = "Copy attached" if body.nil? || body.empty?
mail_obj = mail(:to => mailers_to,
:from => "\"#{agent.name}\" <mailer#xodapp1.com>",
:bcc => mail_cc,
:subject => subject,
:content_type => "text/html",
:body => body.html_safe,
:reply_to => "#{!agent.email.nil? ? agent.email : UserMailer.default[:reply_to]}"
)
mail_obj.attachments[name_attachment] = open(url_attachment).read unless url_attachment.nil?
return mail_obj
end
end
I remove the content_type and change the order:
class UserMailer < ActionMailer::Base
default :from => "mailer#cavsystems.com"
default :bcc => "do_not_reply#cavsystems.com"
default :reply_to => "do_not_reply#cavsystems.com"
def send_email(agent, customer, subject, body, mail_to = nil, mail_cc = nil, url_attachment = nil , name_attachment = nil)
#attachments[name_attachment] = {:content => open(url_attachment).read, :mime_type => MIME::Types.type_for(name_attachment).first} unless url_attachment.nil?
mail_to = !mail_to.nil? ? mail_to : "\"#{customer.name}\" <#{customer.email}>"
mailers_to = mail_to.split(',')
mail_cc = !mail_cc.nil? ? mail_cc.split(',') : agent.email
if [nil, []].include?(mail_cc)
mail_cc = UserMailer.default[:bcc]
end
body = "Copy attached" if body.nil? || body.empty?
attachments[name_attachment] = open(url_attachment).read unless url_attachment.nil?
mail(:to => mailers_to,
:from => "\"#{agent.name}\" <mailer#cavsystems.com>",
:bcc => mail_cc,
:subject => subject,
#:content_type => "text/html",
:body => body.html_safe,
:reply_to => "#{!agent.email.nil? ? agent.email : UserMailer.default[:reply_to]}"
)
#mail_obj.attachments[name_attachment] = open(url_attachment).read unless url_attachment.nil?
#return mail_obj
end
end
Now the email is arriving with the pdf attachment but the HTML code is raw :-(
It's o.k. because we need the pdf not the html.
It will be great if the HTML will be visible.

How to use Rhodes without Rhosync or RhoConnect?

I know we can sync data using rhodes without Rhosync or Rhoconnect by using direct web service, but I'm here little bit confuse where to place that code for webservice call and how do we initialize it. Can anyone help me with small example?
Thanks in Advance.
I got it and it works for me.
class ProductController < Rho::RhoController
include BrowserHelper
# GET /product
def index
response = Rho::AsyncHttp.get(:url => "example.com/products.json",
:headers => {"Content-Type" => "application/json"})
#result = response["body"]
render :back => '/app'
end
# GET /product/{1}
def show
id =#params['id']
response = Rho::AsyncHttp.get(:url => "example.com/products/"+ id +".json",
:headers => {"Content-Type" => "application/json"})
#result = response["body"]
end
# GET /product/new
def new
#product = product.new
render :action => :new, :back => url_for(:action => :index)
end
# GET /product/{1}/edit
def edit
id =#params['product_id'].to_s
response = Rho::AsyncHttp.get(:url => "example.com/products/#{id}.json",
:headers => {"Content-Type" => "application/json"})
#result = response["body"]
end
# POST /product/create
def create
name = #params['product']['name']
price = #params['product']['price']
body = '{"product" : {"name" : "'+ name +'","price" :"'+ price +'" } }'
#result = Rho::AsyncHttp.post(:url => "example.com/products.json",
:body => body, :http_command => "POST", :headers => {"Content-Type" => "application/json"})
redirect :action => :index
end
# POST /product/{1}/update
def update
name=#params['product']['name']
price=#params['product']['price']
body = '{"product" : {"name" : "' + name + '","price" :"' + price + '" } }'
id = #params["product_id"].to_s
response = Rho::AsyncHttp.post(:url => "example.com/products/#{id}.json",
:body => body, :http_command => "PUT",:headers => {"Content-Type" => "application/json"})
redirect :action => :index
end
# POST /product/{1}/delete
def delete
id = #params["product_id"].to_s
response = Rho::AsyncHttp.post(:url => "example.com/products/#{id}.json",
:http_command => "DELETE",
:headers => {"Content-Type" => "application/json"})
redirect :action => :index
end
end
Most easy form of http server request is next:
Rho::AsyncHttp.get(
:url => "http://www.example.com",
:callback => (url_for :action => :httpget_callback)
)
where httpget_callback is name of the controller callback method.
See more details at official Rhodes docs.

Rhoconnect webservice login need

I am very new guy in Rhomobile and I want to login a webservice using Rhoconnect can anyone help me how to implement this.
I've tried with in Settings Controler:
def do_login
if #params['username'] and #params['password']
begin
SyncEngine.login(#params['username'], #params['password'], (url_for :action => :login_callback) )
#response['headers']['Wait-Page'] = 'true'
redirect :action => :index
rescue Rho::RhoError => e
#msg = e.message
render :action => :login
end
else
#msg = Rho::RhoError.err_message(Rho::RhoError::ERR_UNATHORIZED) unless #msg && #msg.length > 0
render :action => :login
end
end
Where SyncEngine.login(#params['username'], #params['password']) call the sourecadapter method login; where I'm calling
def login(username, password)
user_info = {:username => username, :password => password }
response = RestClient.get(#base+#params['username']+#params['password'])
result = RestClient.post(:url => "my-webservice" )
#msg=result["body"]
render :action => :index
end
I've tried in:
class Application < Rhoconnect::Base
class << self
def authenticate(username,password,session)
result = RestClient.post(:url => "mywebservice" )
true # do some interesting authentication here...
end
end
But I got nothing..
plz give some idea me; how to solve this
SyncEngine.login call from Rhodes app will call authenticate(username, password, session)
method in application.rb of your RhoConnect app. Then, you can code the authenticate method to call your implementation of user authentication as follows:
def authenticate(username, password, session)
# for example
resp = RestClient.post(:url => "mywebservice", :login => {:username => username, :password => password})
#parse resp as needed and return the result either true or false
# i.e. status contains value true or false in the response body
result = JSON.parse(resp.body)['status']
end
Hope that helps.

How to get gateway response from model into controller - Ruby on Rails

My application uses activemerchant to process payments. I'm using Eway as my payment gateway. I'm storing credit card details with Eway to keep them out of my application database.
I'm using a method store which returns a response with a customer billing id that I can use at a later time to process the order.
http://rdoc.info/github/Shopify/active_merchant/master/ActiveMerchant/Billing/EwayManagedGateway
My main issue is how do I get the response value into my controller so I can save it to the member model.
I've created a simple ruby file to test this all works and it does. I just need to convert this code to work inside my rails app.
require "rubygems"
gem 'activemerchant', '1.15.0'
require 'activemerchant'
ActiveMerchant::Billing::Base.mode = :production
gateway = ActiveMerchant::Billing::EwayManagedGateway.new(
:login => '12345678',
:username => 'mylogin#example.com',
:password => 'mypassword'
)
credit_card = ActiveMerchant::Billing::CreditCard.new(
:type => "visa",
:number => "4444333322221111",
:verification_value => "123",
:month => "11",
:year => "2011",
:first_name => "John",
:last_name => "Citizen"
)
options = {
:order_id => '1230123',
:ip => "127.0.0.1",
:email => 'john.citizen#example.com',
:billing_address => { :title => "Mr.",
:address1 => '123 Sample Street',
:city => 'Sampleville',
:state => 'NSW',
:country => 'AU',
:zip => '2000'
},
:description => 'purchased items'
}
if credit_card.valid?
response = gateway.store(credit_card, options)
if response.success?
puts "Credit Card Stored. #{response.message}"
customer = response.params['CreateCustomerResult']
puts "Customer Id: #{customer}"
else
puts "Error: #{response.message}"
end
else
puts "Error, credit card is not valid. #{credit_card.errors.full_messages.join('. ')}"
end
Here is the relevant code in my order model.
serialize :params
cattr_accessor :gateway
def response=(response)
self.success = response.success?
self.message = response.message
self.params = response.params
self.billing_id = response.params['CreateCustomerResult']
rescue ActiveMerchant::ActiveMerchantError => e
self.success = false
self.message = e.message
self.params = {}
self.billing_id = nil
end
def store
response = Order.gateway.store(credit_card, options)
end
Here is my order controller create code.
def create
#member = current_member
#order_deal = Deal.find(params[:deal_id])
#order = #order_deal.orders.build(params[:order])
#order.member_id = current_member.id
#order.ip_address = request.remote_ip
#deal = #order_deal
if #order.save
if #order.store
render :action => "success"
flash[:notice] = "Successfully processed your order."
else
render :action => "new"
end
else
render :action => 'new'
end
end
So essentially I want to get the
response.params['CreateCustomerResult']
and add it to my member model under
member.billing_id = response.params['CreateCustomerResult]
How can I do this?

Error using Xpath in Rhomobile

I am trying to parse XML using rexml Xpath, but facing error as const_missing: XPath in rhomobile application. can anyone give me the solution.
Below is the sample code:
file = File.new(file_name)
begin
require 'rexml/document'
xmldoc = REXML::Document.new(file)
names = XPath.match(xmldoc, "//MP_HOST_NAME" )
in your build.yml file:
extensions:
- rexml
if using blackberry, replace rexml with rhoxml
Assuming you've done this, replace your XPath with:
REXML::XPath.match(xmldoc, "//MP_HOST_NAME" )
Here is a sample controller I knocked to test xml parsing
I can use the get_names method in the view then to get an array of names
require 'rho/rhocontroller'
require 'rexml/document'
class WebServiceTestController < Rho::RhoController
def index
##get_result = ""
Rho::AsyncHttp.get(
:url => 'http://www.somesite.com/some_names.xml',
#:authorization => {:type => :basic, :username => 'user', :password => 'none'},
:callback => (url_for :action => :httpget_callback),
:authentication => {
:type => :basic,
:username => "xxxx",
:password => "xxxx"
},
:callback_param => "" )
render :action => :wait
end
def get_res
##get_result
end
def get_error
##error_params
end
def httpget_callback
if #params["status"] != "ok"
##error_params = #params
WebView.navigate( url_for(:action => :show_error) )
else
##get_result = #params["body"]
begin
# require "rexml/document"
##doc = REXML::Document.new(##get_result)
# puts "doc : #{doc}"
rescue Exception => e
# puts "Error: #{e}"
##get_result = "Error: #{e}"
end
WebView.navigate( url_for(:action => :show_result) )
end
end
def show_error
render :action => :error, :back => '/app'
end
def show_result
render :action => :index, :back => "/app"
end
def get_doc
##doc
end
def get_names
names = []
REXML::XPath.each( get_doc, "//name_or_whatever_you_are_looking_for") do |element|
names << element.text
end
names
end
end
ensure that rhoxml is set in the build.yml file rather than rexml this works fine and it's a little faster

Resources