aboutsummaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/mail_handler/backends/mail_backend.rb51
-rw-r--r--lib/mail_handler/backends/mail_extensions.rb7
-rw-r--r--lib/mail_handler/backends/tmail_backend.rb62
-rw-r--r--lib/mail_handler/backends/tmail_extensions.rb (renamed from lib/tmail_extensions.rb)26
-rw-r--r--lib/mail_handler/mail_handler.rb (renamed from lib/tnef.rb)34
-rw-r--r--lib/tasks/translation.rake4
6 files changed, 153 insertions, 31 deletions
diff --git a/lib/mail_handler/backends/mail_backend.rb b/lib/mail_handler/backends/mail_backend.rb
new file mode 100644
index 000000000..0e198adf0
--- /dev/null
+++ b/lib/mail_handler/backends/mail_backend.rb
@@ -0,0 +1,51 @@
+require 'mail'
+
+module MailHandler
+ module Backends
+ module MailBackend
+
+ def backend()
+ 'Mail'
+ end
+
+ # Note that the decode flag is not yet used
+ def mail_from_raw_email(data, decode=true)
+ Mail.new(data)
+ end
+
+ # Extracts all attachments from the given TNEF file as a Mail object
+ def mail_from_tnef(content)
+ main = Mail.new
+ tnef_attachments(content).each do |attachment|
+ main.add_file(attachment)
+ end
+ main.ready_to_send!
+ main
+ end
+
+ # Return a copy of the file name for the mail part
+ def get_part_file_name(mail_part)
+ part_file_name = mail_part.filename
+ part_file_name.nil? ? nil : part_file_name.dup
+ end
+
+ # Format
+ def address_from_name_and_email(name, email)
+ if !MySociety::Validate.is_valid_email(email)
+ raise "invalid email " + email + " passed to address_from_name_and_email"
+ end
+ if name.nil?
+ return Mail::Address.new(email)
+ end
+ address = Mail::Address.new
+ address.display_name = name
+ address.address = email
+ address.to_s
+ end
+
+ def address_from_string(string)
+ Mail::Address.new(string).address
+ end
+ end
+ end
+end \ No newline at end of file
diff --git a/lib/mail_handler/backends/mail_extensions.rb b/lib/mail_handler/backends/mail_extensions.rb
new file mode 100644
index 000000000..cbe0491ed
--- /dev/null
+++ b/lib/mail_handler/backends/mail_extensions.rb
@@ -0,0 +1,7 @@
+module Mail
+ class Message
+ attr_accessor :url_part_number
+ attr_accessor :rfc822_attachment # when a whole email message is attached as text
+ attr_accessor :within_rfc822_attachment # for parts within a message attached as text (for getting subject mainly)
+ end
+end \ No newline at end of file
diff --git a/lib/mail_handler/backends/tmail_backend.rb b/lib/mail_handler/backends/tmail_backend.rb
new file mode 100644
index 000000000..87aba73d7
--- /dev/null
+++ b/lib/mail_handler/backends/tmail_backend.rb
@@ -0,0 +1,62 @@
+module MailHandler
+ module Backends
+ module TmailBackend
+
+ def backend()
+ 'TMail'
+ end
+
+ # Turn raw data into a structured TMail::Mail object
+ # Documentation at http://i.loveruby.net/en/projects/tmail/doc/
+ def mail_from_raw_email(data, decode=true)
+ # Hack round bug in TMail's MIME decoding.
+ # Report of TMail bug:
+ # http://rubyforge.org/tracker/index.php?func=detail&aid=21810&group_id=4512&atid=17370
+ copy_of_raw_data = data.gsub(/; boundary=\s+"/im,'; boundary="')
+ mail = TMail::Mail.parse(copy_of_raw_data)
+ mail.base64_decode if decode
+ mail
+ end
+
+ # Extracts all attachments from the given TNEF file as a TMail::Mail object
+ def mail_from_tnef(content)
+ main = TMail::Mail.new
+ main.set_content_type 'multipart', 'mixed', { 'boundary' => TMail.new_boundary }
+ tnef_attachments(content).each do |attachment|
+ tmail_attachment = TMail::Mail.new
+ tmail_attachment['content-location'] = attachment[:filename]
+ tmail_attachment.body = attachment[:content]
+ main.parts << tmail_attachment
+ end
+ main
+ end
+
+ # Return a copy of the file name for the mail part
+ def get_part_file_name(mail_part)
+ part_file_name = TMail::Mail.get_part_file_name(mail_part)
+ if part_file_name.nil?
+ return nil
+ end
+ part_file_name = part_file_name.dup
+ return part_file_name
+ end
+
+ def address_from_name_and_email(name, email)
+ if !MySociety::Validate.is_valid_email(email)
+ raise "invalid email " + email + " passed to address_from_name_and_email"
+ end
+ if name.nil?
+ return TMail::Address.parse(email).to_s
+ end
+ # Botch an always quoted RFC address, then parse it
+ name = name.gsub(/(["\\])/, "\\\\\\1")
+ TMail::Address.parse('"' + name + '" <' + email + '>').to_s
+ end
+
+ def address_from_string(string)
+ TMail::Address.parse(string).address
+ end
+
+ end
+ end
+end \ No newline at end of file
diff --git a/lib/tmail_extensions.rb b/lib/mail_handler/backends/tmail_extensions.rb
index 6a533e658..9359dfeea 100644
--- a/lib/tmail_extensions.rb
+++ b/lib/mail_handler/backends/tmail_extensions.rb
@@ -15,6 +15,12 @@ require 'tmail/interface'
# These mainly used in app/models/incoming_message.rb
module TMail
class Mail
+ # Monkeypatch! Adding some extra members to store extra info in.
+
+ attr_accessor :url_part_number
+ attr_accessor :rfc822_attachment # when a whole email message is attached as text
+ attr_accessor :within_rfc822_attachment # for parts within a message attached as text (for getting subject mainly)
+
# Monkeypatch! (check to see if this becomes a standard function in
# TMail::Mail, then use that, whatever it is called)
def Mail.get_part_file_name(part)
@@ -68,22 +74,6 @@ module TMail
end
- class Address
- # Monkeypatch! Constructor which makes a TMail::Address given
- # a name and an email
- def Address.address_from_name_and_email(name, email)
- if !MySociety::Validate.is_valid_email(email)
- raise "invalid email " + email + " passed to address_from_name_and_email"
- end
- if name.nil?
- return TMail::Address.parse(email)
- end
- # Botch an always quoted RFC address, then parse it
- name = name.gsub(/(["\\])/, "\\\\\\1")
- return TMail::Address.parse('"' + name + '" <' + email + '>')
- end
- end
-
module TextUtils
# Monkeypatch! Much more aggressive list of characters to cause quoting
# than in normal TMail. e.g. Have found real cases where @ needs quoting.
@@ -95,8 +85,8 @@ module TMail
end
end
-# Monkeypatch! TMail 1.2.7.1 will parse only one address out of a list of addresses with
-# unquoted display parts https://github.com/mikel/tmail/issues#issue/9 - this monkeypatch
+# Monkeypatch! TMail 1.2.7.1 will parse only one address out of a list of addresses with
+# unquoted display parts https://github.com/mikel/tmail/issues#issue/9 - this monkeypatch
# fixes this issue.
module TMail
diff --git a/lib/tnef.rb b/lib/mail_handler/mail_handler.rb
index 1c941f8b0..24d14b5c8 100644
--- a/lib/tnef.rb
+++ b/lib/mail_handler/mail_handler.rb
@@ -1,13 +1,23 @@
+# Handles the parsing of email
require 'tmpdir'
-class TNEF
+module MailHandler
- # Extracts all attachments from the given TNEF file as a TMail::Mail object
- # The TNEF file also contains the message body, but in general this is the
+ if RUBY_VERSION.to_f >= 1.9
+ require 'backends/mail_extensions'
+ require 'backends/mail_backend'
+ include Backends::MailBackend
+ else
+ require 'backends/tmail_extensions'
+ require 'backends/tmail_backend'
+ include Backends::TmailBackend
+ end
+
+ # Returns a set of attachments from the given TNEF contents
+ # The TNEF contents also contains the message body, but in general this is the
# same as the message body in the message proper.
- def self.as_tmail(content)
- main = TMail::Mail.new
- main.set_content_type 'multipart', 'mixed', { 'boundary' => TMail.new_boundary }
+ def tnef_attachments(content)
+ attachments = []
Dir.mktmpdir do |dir|
IO.popen("#{`which tnef`.chomp} -K -C #{dir}", "w") do |f|
f.write(content)
@@ -23,10 +33,8 @@ class TNEF
Dir.new(dir).sort.each do |file| # sort for deterministic behaviour
if file != "." && file != ".."
file_content = File.open("#{dir}/#{file}", "r").read
- attachment = TMail::Mail.new
- attachment['content-location'] = file
- attachment.body = file_content
- main.parts << attachment
+ attachments << { :content => file_content,
+ :filename => file }
found += 1
end
end
@@ -34,7 +42,11 @@ class TNEF
raise IOError, "tnef produced no attachments"
end
end
- main
+ attachments
end
+ # Turn instance methods into class methods
+ extend self
+
end
+
diff --git a/lib/tasks/translation.rake b/lib/tasks/translation.rake
index f6611cc80..273c12bfa 100644
--- a/lib/tasks/translation.rake
+++ b/lib/tasks/translation.rake
@@ -4,7 +4,7 @@ namespace :translation do
include Usage
def write_email(email, email_description, output_file)
- mail_object = TMail::Mail.parse(email.to_s)
+ mail_object = MailHandler.mail_from_raw_email(email.to_s, decode=false)
output_file.write("\n")
output_file.write("Description of email: #{email_description}\n")
output_file.write("Subject line: #{mail_object.subject}\n")
@@ -86,7 +86,7 @@ namespace :translation do
'fixtures',
'files',
'incoming-request-plain.email'))
- response_mail = TMail::Mail.parse(content)
+ response_mail = MailHandler.mail_from_raw_email(content, decode=false)
response_mail.from = "authority@example.com"
stopped_responses_email = RequestMailer.create_stopped_responses(info_request,