Landscape トップページ | < 前の日 2004-10-31 2004-11-01 次の日 2004-11-02 >

Landscape - エンジニアのメモ 2004-11-01

添付ファイル付メール送信Rubyスクリプト samail 0.4


* 添付ファイル付メール送信Rubyスクリプト samail 0.4

この記事の直リンクURL: Permlink | この記事が属するカテゴリ: [メール] [Ruby]

2004-10-09 で書いた「添付ファイル付メールを送信する Ruby スクリプト」である samail 0.3 を修正して バージョン 0.4 とした。

- samail 0.4 の修正点

・smtp タイムアウト時のエラーを rescue Exception で捕捉するようにした。
・状況表示メッセージは標準エラー出力に出力するようにした。
・--output - を指定されたときは、SMTP にメールを投げずに標準出力のみに出力するようにした。
・setup メソッド内で初期化した変数を他のメソッドで参照するのはやっぱり違和感があるので setup メソッドを削除。グローバルなんだからいいんだろうけど。

- samail 0.4 で便利になった点

標準出力にメールの中身を出力するようにしたので、ローカルのメール送信コマンドを利用することができるようになった。これにより、samail の簡易な SMTP リトライ機能ではなくローカルの MTA が提供する強力かつ信頼性の高いリトライ機能を利用できる。また、samail はリトライのみでキューイング機能を持たないが、ローカル MTA はキューイング機能を持っていればそれを利用できる。

ローカルの sendmail コマンドに samail の出力を渡す例。
$ samail -v --to "sonic64@infoseek.jp example@example.com" --from sonic64@infoseek.jp --attachment "logo.png /tmp/backup.tar.bz2" |/usr/sbin/sendmail -f sonic64@infoseek.jp -oi "sonic64@infoseek.jp example@example.com"

- samil 0.4 ソース

ライセンスは 2004-10-09 でも書いたとおり、GPL2 と BSD のデュアルライセンス。

#!/usr/local/bin/ruby

# Copyright (C) 2004 Saito Hiroaki <sonic64@infoseek.jp>
# http://sonic64.com/

require 'kconv'
require 'net/smtp'
require 'getopts'

APPLICATION_NAME = 'Landscape Mailsender'
APPLICATION_VERSION = '0.4'
BANNER_STRING = APPLICATION_NAME + ' ' + APPLICATION_VERSION
X_MAILER_WEBSITE = 'http://sonic64.com/2004-11-01.html'

def build_mail_header()
  $mail_content << 'Date: ' + Time::now.strftime("%a, %d %b %Y %X %z") + "\n"
  $mail_content << 'From: ' + $mail_from + "\n"
  $mail_content << 'To: ' + $mail_to.join(', ') + "\n"
  $mail_content << 'Subject: ' + $mail_subject + "\n"
  $mail_content << "MIME-Version: 1.0\n"
  $mail_content << 'Content-Type: multipart/mixed; boundary="' + $boundary  + "\"\n"
  $mail_content << 'X-Mailer: ' + BANNER_STRING + "\n"
  $mail_content << 'X-Mailer-WebSite: ' + X_MAILER_WEBSITE + "\n"
  $mail_content << "\n"
end


def add_attchment(file_name)
  if file_name == '' then
    return
  end

  attachment_file = File.open(file_name).readlines.join('')
  encoded_attachment = [attachment_file].pack('m')
  $mail_content <<  '--' + $boundary + "\n"
  $mail_content << "Content-Type: application/octet-stream;\n"
  $mail_content << ' name="' + File.basename(file_name) + '"' + "\n"
  $mail_content << "Content-Transfer-Encoding: base64\n"
  $mail_content << "Content-Disposition: attachment;\n"
  $mail_content << ' filename="' + File.basename(file_name) + "\"\n\n"
  $mail_content << encoded_attachment + "\n"
end


def send_mail(retry_count)
  begin
    STDERR.puts Time::now.to_s + " Try to connect " + $smtp_server if $OPT_v
    Net::SMTP.start($smtp_server) do |smtp|
      smtp.sendmail($mail_content, $mail_from, $mail_to)
    end
    STDERR.puts Time::now.to_s + ' Send OK' if $OPT_v
  rescue Exception => e
    STDERR.puts Time::now.to_s + ' smtp error: ' + e.message
    if retry_count != 0 then
      retry_count -= 1
      STDERR.puts Time::now.to_s + ' sleep: ' + $smtp_retry_interval_second.to_s + 'sec'
      sleep($smtp_retry_interval_second)
      $smtp_retry_interval_second *= 2
      retry
    else
      STDERR.puts Time::now.to_s + ' abort: Over retry count'
      raise
    end
  end
end


# main
usage_message = "usage: #$0 [-v] --to TO_EMAIL_ADDRESS [--from FROM_EMAIL_ADDRESS] [--smtp SMTP_SERVER] [--attachment ATTACHMENT_FILE] [--output]"
unless getopts('v', 'from:', 'to:', 'subject:', 'attachment:', 'smtp:', 'output:')
  abort usage_message
end
abort "#$0: specifiy --to TO_EMAIL_ADDRESS\n" + usage_message if ! $OPT_to

if $OPT_output == '-' then
  $output2stdout = true
  $smtp_server = ''
elsif $OPT_smtp then
  $output2stdout = false
  $smtp_server = $OPT_smtp
else
  $smtp_server = 'localhost'
end

$mail_from = $OPT_from ? $OPT_from : ENV['USER'] + '@' + ENV['HOSTNAME']
$mail_to = $OPT_to.split(/,\s*|\s+/)
$mail_subject = $OPT_subject ? $OPT_subject : APPLICATION_NAME + ' [' + Time::now.strftime("%a, %d %b %Y %X %z") + ']'

$mail_content = ''
$boundary = 'boundary_string_by_landscape_mailsender'
$attachment_file = $OPT_attachment ? $OPT_attachment.split(/,\s*|\s+/) : []
$smtp_retry = 8
$smtp_retry_interval_second = 30

if $OPT_v then
  STDERR.puts 'To: ' + $mail_to.join(', ')
  STDERR.puts 'From: ' + $mail_from
  STDERR.puts 'Attachment file: ' + $attachment_file.join(", ")
  STDERR.puts 'Subject: ' + $mail_subject
  if $output2stdout then
    STDERR.puts 'Output to STDOUT'
  else
    STDERR.puts 'SMTP Server: ' + $smtp_server
  end
end

build_mail_header()
$mail_content <<  '--' + $boundary + "\n"
$mail_content << "Content-Type: text/plain; charset=iso-2022-jp\n"
$mail_content << "Content-Transfer-Encoding: 7bit\n"
$mail_content << "\n"
$mail_content << "-- \n"
$mail_content << 'Powered by ' + BANNER_STRING + "\n"
$mail_content <<  X_MAILER_WEBSITE + "\n"
$mail_content << "\n"

$attachment_file.each do |file|
  add_attchment(file)
end

$mail_content <<  '--' + $boundary + "--\n"

if $output2stdout then
  puts $mail_content
else
  send_mail($smtp_retry)
end


すべての記事の見出し (全1029件)
全カテゴリの一覧と記事の数
カテゴリごとに記事をまとめ読みできます。記事の表題だけを見たい場合は、すべての記事の見出し (カテゴリ別表示) へ。

直近30日分の記事
2007-04-23 (Mon)
2007-03-07 (Wed)
2007-02-27 (Tue)
2007-01-17 (Wed)
2007-01-15 (Mon)
2007-01-14 (Sun)
2007-01-08 (Mon)
2006-12-01 (Fri)
2006-11-22 (Wed)
2006-11-20 (Mon)
2006-11-19 (Sun)
2006-09-30 (Sat)
2006-08-29 (Tue)
2006-08-04 (Fri)
2006-07-27 (Thu)
2006-07-23 (Sun)
2006-07-17 (Mon)
2006-07-10 (Mon)
2006-07-06 (Thu)
2006-07-03 (Mon)
2006-06-29 (Thu)
2006-06-28 (Wed)
2006-06-27 (Tue)
2006-06-25 (Sun)
2006-06-19 (Mon)
2006-06-18 (Sun)
2006-06-15 (Thu)
2006-06-11 (Sun)
2006-06-01 (Thu)
2006-05-30 (Tue)
プロファイル
斎藤 宏明。エンジニアです。宇都宮市に住んでいます。
リンク
RSS
スポンサードリンク
Powered by
さくらインターネット

© 斎藤 宏明 Saito Hiroaki Gmail Address
Landscape - エンジニアのメモ http://sonic64.com/
Landscape はランドスケープと読みます。
ひらがなだと らんどすけーぷ です。