Class: Hermeneutics::Mail

Inherits:
Message show all
Defined in:
lib/hermeneutics/mail.rb,
lib/hermeneutics/transports.rb

Defined Under Namespace

Classes: FromReader

Constant Summary collapse

SPOOLDIR =
"/var/mail"
MAILDIR =
"Mail"
SENDMAIL =
"/usr/sbin/sendmail"
SYSDIR =
".hermeneutics"
LEVEL =
{}

Constants inherited from Message

Hermeneutics::Message::MIME

Class Attribute Summary collapse

Attributes inherited from Message

#body, #headers

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Message

#[], #body_binary=, #body_decoded, #body_text=, #inspect, #is_multipart?, #method_missing, #transfer_encoding

Methods inherited from Mime

find, inherited

Constructor Details

#initialize(from, headers, body) ⇒ Mail

Returns a new instance of Mail.



60
61
62
63
# File 'lib/hermeneutics/mail.rb', line 60

def initialize from, headers, body
  super headers, body
  @from = from
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class Hermeneutics::Message

Class Attribute Details

.default_formatObject

Returns the value of attribute default_format.



29
30
31
# File 'lib/hermeneutics/transports.rb', line 29

def default_format
  @default_format
end

.logfileObject

Returns the value of attribute logfile.



31
32
33
# File 'lib/hermeneutics/transports.rb', line 31

def logfile
  @logfile
end

.loglevelObject

Returns the value of attribute loglevel.



31
32
33
# File 'lib/hermeneutics/transports.rb', line 31

def loglevel
  @loglevel
end

.maildirObject

Returns the value of attribute maildir.



29
30
31
# File 'lib/hermeneutics/transports.rb', line 29

def maildir
  @maildir
end

.sendmailObject

Returns the value of attribute sendmail.



30
31
32
# File 'lib/hermeneutics/transports.rb', line 30

def sendmail
  @sendmail
end

.spooldirObject

Returns the value of attribute spooldir.



29
30
31
# File 'lib/hermeneutics/transports.rb', line 29

def spooldir
  @spooldir
end

.spoolfileObject

Returns the value of attribute spoolfile.



29
30
31
# File 'lib/hermeneutics/transports.rb', line 29

def spoolfile
  @spoolfile
end

.sysdirObject

Returns the value of attribute sysdir.



29
30
31
# File 'lib/hermeneutics/transports.rb', line 29

def sysdir
  @sysdir
end

Class Method Details

.box(path = nil, default_format = nil) ⇒ Object



33
34
35
36
# File 'lib/hermeneutics/transports.rb', line 33

def box path = nil, default_format = nil
  @cache ||= {}
  @cache[ path] ||= find_box path, default_format
end

.createObject



54
55
56
# File 'lib/hermeneutics/mail.rb', line 54

def create
  new nil, nil, nil
end

.expand_maildirObject



80
81
82
# File 'lib/hermeneutics/transports.rb', line 80

def expand_maildir
  File.expand_path @maildir||MAILDIR, "~"
end

.expand_sysdirObject



84
85
86
# File 'lib/hermeneutics/transports.rb', line 84

def expand_sysdir
  File.expand_path @sysdir||SYSDIR, expand_maildir
end

.log(type, *message) ⇒ Object



67
68
69
70
71
72
73
74
75
76
77
78
# File 'lib/hermeneutics/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) ⇒ Object



46
47
48
49
50
51
52
# File 'lib/hermeneutics/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

Instance Method Details

#pipe(cmd, *args) ⇒ Object

:call-seq:

obj.pipe( cmd, *args)           -> status

Pipe into an external program. If a block is given, the programs output will be yielded there.



116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
# File 'lib/hermeneutics/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

#receiversObject



75
76
77
# File 'lib/hermeneutics/mail.rb', line 75

def receivers
  addresses_of :to, :cc, :bcc
end

#save(mailbox = nil, default_format = nil) ⇒ Object

:call-seq:

obj.save( path, default_format = nil)           -> mb

Save into local mailbox.



104
105
106
107
108
# File 'lib/hermeneutics/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!(conn = nil, *tos) ⇒ Object

:call-seq:

obj.send!( smtp, *tos)                -> response

Send by SMTP.

Be aware that #send without bang is a standard Ruby method.



176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/hermeneutics/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(*tos) ⇒ Object

:call-seq:

obj.sendmail( *tos)                -> status

Send by sendmail; leave the tos list empty to use Sendmail’s -t option.



153
154
155
156
157
158
159
160
161
162
163
164
165
166
# File 'lib/hermeneutics/transports.rb', line 153

def sendmail *tos
  if tos.empty? then
    pipe cls.sendmail, "-t"
  else
    tos.flatten!
    tos.map! { |t|
      case t
        when Addr then t.plain
        else           t.delete %q-,;"'<>(){}[]$&*?-   # security
      end
    }
    pipe cls.sendmail, *tos
  end
end

#to_sObject

String representation with “From ” line. Mails reside in mbox files etc. and so have to end in a newline.



67
68
69
70
71
72
73
# File 'lib/hermeneutics/mail.rb', line 67

def to_s
  set_unix_from
  r = ""
  r << @from << $/ << super
  r.ends_with? $/ or r << $/
  r
end