class Hermes::Mail
Constants
- LEVEL
- MAILDIR
- SENDMAIL
- SPOOLDIR
- SYSDIR
Attributes
default_format[RW]
logfile[RW]
loglevel[RW]
maildir[RW]
sendmail[RW]
spooldir[RW]
spoolfile[RW]
sysdir[RW]
Public Class Methods
new(from, headers, body)
click to toggle source
Calls superclass method
# File lib/hermes/mail.rb, line 60 def initialize from, headers, body super headers, body @from = from end
Public Instance Methods
box(path = nil, default_format = nil)
click to toggle source
# File lib/hermes/transports.rb, line 33 def box path = nil, default_format = nil @cache ||= {} @cache[ path] ||= find_box path, default_format end
create()
click to toggle source
# File lib/hermes/mail.rb, line 54 def create new nil, nil, nil end
expand_maildir()
click to toggle source
# File lib/hermes/transports.rb, line 80 def expand_maildir File.expand_path @maildir||MAILDIR, "~" end
expand_sysdir()
click to toggle source
# File lib/hermes/transports.rb, line 84 def expand_sysdir File.expand_path @sysdir||SYSDIR, expand_maildir end
log(type, *message)
click to toggle source
# File lib/hermes/transports.rb, line 67 def log type, *message @logfile or return return if LEVEL[ type] > LEVEL[ @loglevel].to_i l = File.expand_path @logfile, expand_sysdir LockedFile.open l, "a" do |log| log.puts "[#{Time.new}] [#$$] [#{type}] #{message.join ' '}" end nil rescue Errno::ENOENT d = File.dirname l Dir.mkdir! d and retry end
parse(input)
click to toggle source
# File lib/hermes/mail.rb, line 46 def parse input FromReader.open input do |fr| parse_hb fr do |h,b| new fr.from, h, b end end end
pipe( cmd, *args) → status
click to toggle source
Pipe into an external program. If a block is given, the programs output will be yielded there.
# File lib/hermes/transports.rb, line 116 def pipe cmd, *args log :INF, "Piping through:", cmd, *args ri, wi = IO.pipe ro, wo = IO.pipe child = fork do wi.close ; ro.close $stdout.reopen wo ; wo.close $stdin .reopen ri ; ri.close exec cmd, *args end ri.close ; wo.close t = Thread.new wi do |wi| begin wi.write to_s ensure wi.close end end begin r = ro.read yield r if block_given? ensure ro.close end t.join Process.wait child $?.success? or log :ERR, "Pipe failed with error code %d." % $?.exitstatus $? end
receivers()
click to toggle source
# File lib/hermes/mail.rb, line 75 def receivers addresses_of :to, :cc, :bcc end
save( path, default_format = nil) → mb
click to toggle source
Save into local mailbox.
# File lib/hermes/transports.rb, line 104 def save mailbox = nil, default_format = nil b = cls.box mailbox, default_format log :INF, "Delivering to", b.path b.deliver self end
send!( smtp, *tos) → response
click to toggle source
Send by SMTP.
Be aware that #send
without bang is a standard Ruby method.
# File lib/hermes/transports.rb, line 176 def send! conn = nil, *tos if tos.empty? then tos = receivers.map { |t| t.plain } else tos.flatten! end f, m = true, "" to_s.each_line { |l| if f then f = false next if l =~ /^From / end m << l } open_smtp conn do |smtp| log :INF, "Sending to", *tos frs = headers.from.map { |f| f.plain } smtp.send_message m, frs.first, tos end rescue NoMethodError raise "Missing field: #{$!.name}." end
sendmail()
click to toggle source
# File lib/hermes/transports.rb, line 63 def sendmail @sendmail||SENDMAIL end
to_s()
click to toggle source
String representation with “From ” line. Mails reside in mbox files etc. and so have to end in a newline.
Calls superclass method
# File lib/hermes/mail.rb, line 67 def to_s set_unix_from r = "" r << @from << $/ << super r.ends_with? $/ or r << $/ r end
Private Instance Methods
addresses_of(*args)
click to toggle source
# File lib/hermes/mail.rb, line 81 def addresses_of *args l = args.map { |f| @headers.field f } AddrList.new *l end
find_box(path, default_format)
click to toggle source
# File lib/hermes/transports.rb, line 40 def find_box path, default_format b = case path when Box then path when nil then @spoolfile ||= getuser @spooldir ||= SPOOLDIR m = File.expand_path @spoolfile, @spooldir MBox.new m else m = if path =~ /\A=/ then File.join expand_maildir, $' else File.expand_path path, "~" end Box.find m, default_format||@default_format end b.exists? or b.create b end
getuser()
click to toggle source
# File lib/hermes/transports.rb, line 90 def getuser e = Etc.getpwuid Process.uid e.name rescue NameError require "etc" and retry end
net_smpt()
click to toggle source
# File lib/hermes/transports.rb, line 201 def net_smpt Net::SMTP rescue NameError require "net/smtp" and retry end
open_smtp(arg) { |arg| ... }
click to toggle source
# File lib/hermes/transports.rb, line 207 def open_smtp arg, &block case arg when String then h, p = arg.split ":" when Array then h, p = *arg when nil then h, p = "localhost", nil else if arg.respond_to? :send_message then yield arg return else h, p = arg.host, arg.port end end net_smpt.start h, p, &block end
set_unix_from()
click to toggle source
# File lib/hermes/mail.rb, line 86 def set_unix_from return if @from # Common MTA's will issue a proper "From" line; some MDA's # won't. Then, build it using the "From:" header. addr = nil l = addresses_of :from, :return_path # Prefer the non-local version if present. l.each { |a| if not addr or addr !~ /@/ then addr = a end } addr or raise ArgumentError, "No From: field present." @from = "From #{addr.plain} #{Time.now.gmtime.asctime}" end