Friday, December 7, 2007
How to Format Ruby Code in a Blog Post
My previous post was the first time I had ever presented ruby code in a post. This article saved me the hassle of figuring it out how to make it look pretty (I stuck the css directly into my blogger template). Thanks Wolfmann.
Sending GMail from a Standalone Ruby Script
As part of my rails application, I need to send emails from a stand alone ruby script. For example, the back end of my rails application is a (currently) small postgres database. The easiest way to back it up is to send a database dump to myself via gmail.
There are several tutorials on how to send gmail directly from a rails app. Presented here is a method for doing it from a standalone script. This method assumes rails is installed, but the script itself runs outside of any rails application. In my case in the wee hours of the morning as a cron job.
Usage of this script would be something like:
The script can also handle attachments, albeit in an unusual way. Instead of giving it a file, you give it the data directly, along with a filename, mime_type, and transfer encoding:
It should be easy enough to modify the script to handle files as attachments directly, but I didn't have such a need.
Here is the complete listing. My thanks to Stephun Chu, as most of this is cribbed from his aforementioned post.
Edit: Fixed syntax error - Thanks Nolan!
There are several tutorials on how to send gmail directly from a rails app. Presented here is a method for doing it from a standalone script. This method assumes rails is installed, but the script itself runs outside of any rails application. In my case in the wee hours of the morning as a cron job.
Usage of this script would be something like:
require 'send_gmail'
hsh={:to=>'name@domain.com', :subject=>'subject', :body=>'body'}
SendGMail.send_gmail(hsh)
The script can also handle attachments, albeit in an unusual way. Instead of giving it a file, you give it the data directly, along with a filename, mime_type, and transfer encoding:
raw_attachment={:mime_type=>'application/x-gzip', :body=>make_body, :transfer_encoding=>'base64', :filename=>'backup.tar.gz' }
hsh[:raw_attachment]=raw_attachment
It should be easy enough to modify the script to handle files as attachments directly, but I didn't have such a need.
Here is the complete listing. My thanks to Stephun Chu, as most of this is cribbed from his aforementioned post.
Edit: Fixed syntax error - Thanks Nolan!
send_gmail.rb
#!/usr/bin/env ruby
require 'rubygems'
gem 'actionmailer'
require 'action_mailer'
require 'openssl'
require 'net/smtp'
module SendGMail
@user_name='username@domain.com'
@domain='domain.com'
@password='password'
def SendGMail.send_gmail(hsh)
raw_attachments=hsh.fetch(:raw_attachements, [])
if hsh.has_key?(:raw_attachment)
raw_attachments.push(hsh[:raw_attachment])
end
mail=TMail::Mail.new
mail.to=hsh[:to]
mail.date=Time.now
mail.from=@user_name
mail.subject=hsh[:subject]
main=mail
main=TMail::Mail.new
main.body = hsh[:body]
puts main.body
main.set_content_type('text/plain', nil, 'charset'=>'utf-8')
mail.parts.push(main)
for raw_attachment in raw_attachments
part = TMail::Mail.new
transfer_encoding=raw_attachment[:transfer_encoding]
body=raw_attachment[:body]
case (transfer_encoding || "").downcase
when "base64" then
part.body = TMail::Base64.folding_encode(body)
when "quoted-printable"
part.body = [body].pack("M*")
else
part.body = body
end
part.transfer_encoding = transfer_encoding
part.set_content_type(raw_attachment[:mime_type], nil, 'name' => raw_attachment[:filename])
part.set_content_disposition("attachment", "filename"=>raw_attachment[:filename])
mail.parts.push(part)
end
mail.set_content_type('multipart', 'mixed')
ActionMailer::Base.deliver(mail)
end
ActionMailer::Base.smtp_settings = {
:address => 'smtp.gmail.com',
:domain => @domain,
:authentication => :plain,
:port => 587,
:user_name => @user_name,
:password => @password
}
Net::SMTP.class_eval do
private
def do_start(helodomain, user, secret, authtype)
raise IOError, 'SMTP session already started' if @started
check_auth_args user, secret, authtype if user or secret
sock = timeout(@open_timeout) { TCPSocket.open(@address, @port) }
@socket = Net::InternetMessageIO.new(sock)
@socket.read_timeout = 60 #@read_timeout
@socket.debug_output = STDERR #@debug_output
check_response(critical { recv_response() })
do_helo(helodomain)
raise 'openssl library not installed' unless defined?(OpenSSL)
starttls
ssl = OpenSSL::SSL::SSLSocket.new(sock)
ssl.sync_close = true
ssl.connect
@socket = Net::InternetMessageIO.new(ssl)
@socket.read_timeout = 60 #@read_timeout
@socket.debug_output = STDERR #@debug_output
do_helo(helodomain)
authenticate user, secret, authtype if user
@started = true
ensure
unless @started
# authentication failed, cancel connection.
@socket.close if not @started and @socket and not @socket.closed?
@socket = nil
end
end
def do_helo(helodomain)
begin
if @esmtp
ehlo helodomain
else
helo helodomain
end
rescue Net::ProtocolError
if @esmtp
@esmtp = false
@error_occured = false
retry
end
raise
end
end
def starttls
getok('STARTTLS')
end
def quit
begin
getok('QUIT')
rescue EOFError, OpenSSL::SSL::SSLError
end
end
end
end
Thursday, November 15, 2007
Syntax Coloring for Dynamic Stylesheets
I often need to dynamically generate stylesheets. Thankfully this path is well worn and solutions are readily available for Ruby on Rails. I chose the ERb/CSS based solution presented here:
Dirt Simple .rcss templates
Simpler than dirt: RESTful Dynamic CSS
If you're in the market, I'd also recommend looking at Sass (Syntactically Awesome StyleSheets). I'll explain my choice in favor of ERb/CSS in a future post.
One of the issues with the ERb/CSS solution is that editors are not aware of the syntax. To remedy this, I have created a plugin for ActiveState's Komodo IDE .
The plugins are here (with the usual disclaimer):
css-erb-highlight-only-1.0.0-ko.xpi
css-erb-highlight-and-check-1.0.0-ko.xpi
rcss-highlight-only-1.0.0-ko.xpi
rcss-highlight-and_check-1.0.0-ko.xpi
The "highlight-and-check" versions provide syntax highlighting, syntax checking, and auto indentation. However due to a shortcoming in ActiveState's tools, the syntax checking is imperfect and you will see syntax errors where there are none. I will remedy this as soon at the tools allow.
It should go without saying that the "highlight-only" versions only provide syntax highlighting, and the "css-erb" and "rcss" versions provide the functionality for the ".css.erb" and ".rcss" extensions respectively.
In a future post, I hope detail how these extensions were created.
I'm using Komodo IDE 4.2 on Mac OS X, but I believe the extensions will work in all Komodo 4 products. Please let me know if they don't.
Dirt Simple .rcss templates
Simpler than dirt: RESTful Dynamic CSS
If you're in the market, I'd also recommend looking at Sass (Syntactically Awesome StyleSheets). I'll explain my choice in favor of ERb/CSS in a future post.
One of the issues with the ERb/CSS solution is that editors are not aware of the syntax. To remedy this, I have created a plugin for ActiveState's Komodo IDE .
The plugins are here (with the usual disclaimer):
css-erb-highlight-only-1.0.0-ko.xpi
css-erb-highlight-and-check-1.0.0-ko.xpi
rcss-highlight-only-1.0.0-ko.xpi
rcss-highlight-and_check-1.0.0-ko.xpi
The "highlight-and-check" versions provide syntax highlighting, syntax checking, and auto indentation. However due to a shortcoming in ActiveState's tools, the syntax checking is imperfect and you will see syntax errors where there are none. I will remedy this as soon at the tools allow.
It should go without saying that the "highlight-only" versions only provide syntax highlighting, and the "css-erb" and "rcss" versions provide the functionality for the ".css.erb" and ".rcss" extensions respectively.
In a future post, I hope detail how these extensions were created.
I'm using Komodo IDE 4.2 on Mac OS X, but I believe the extensions will work in all Komodo 4 products. Please let me know if they don't.
Subscribe to:
Posts (Atom)