note description: "Aranea node to send emails." author: "Patrick Ruckstuhl " date: "$Date$" revision: "$Revision$" class A_NODE_MAIL inherit A_NODE redefine listen_queues, register_message_handlers, switches, aranea_startup end A_MAIL_CONSTANTS A_MAIL_SEND_MESSAGE_HANDLER rename handle_send as simple_mail end ARGUMENTS create make feature {NONE} -- Initialization aranea_startup -- Create. do Precursor create smtp_connection_lock.make create smtp_connection.make (smtp_server, local_host_name) end feature -- Status is_simulate: BOOLEAN -- Should actions only be simulated and not executed? once Result := has_option (simulate_switch) end feature -- Access name: STRING = "Aranea Mail" version: STRING = "$Revision$" feature {NONE} -- Message handlers simple_mail (a_msg: A_MAIL_SEND_MESSAGE) -- Handle a simple message to send an email. do if is_simulate then io.put_string ("Mail to:") io.put_string (a_msg.recipient.value) io.new_line else send_mail (a_msg.recipient.value, a_msg.sender.value, a_msg.subject.value, a_msg.text.value) end end feature {NONE} -- Argument handling switches: detachable ARRAYED_LIST [attached ARGUMENT_SWITCH] -- Command line switches. local l_assertion_flag: BOOLEAN once -- disable assertion-checking for precursor-assertion-check l_assertion_flag := {ISE_RUNTIME}.check_assert (False) Result := Precursor Result.extend (create {ARGUMENT_SWITCH}.make(simulate_switch, "Only simulate actions?", True, False)) -- restore previous value of assertion-checking l_assertion_flag := {ISE_RUNTIME}.check_assert (l_assertion_flag) end simulate_switch: STRING = "simulate" feature {NONE} -- Implementation listen_queues: DS_LIST [STRING] -- Listen queues once Result := Precursor Result.put_last (aranea_mail_queue) end register_message_handlers -- Register message handlers. do Precursor register_message_handler (mail_namespace, mail_send_type, agent send_message_handler_register) end send_mail (a_recipient, a_sender, a_subject, a_message: STRING) -- Send a_message to a_recipient. local l_email: EMAIL do -- create message create l_email.make l_email.add_header_entry (l_email.h_from, "%"" + mail_sender_prefix + a_sender + "%" " + mail_sender) l_email.add_header_entry (l_email.h_to, a_recipient) l_email.add_header_entry (l_email.h_subject, as_quoted_printable(a_subject)) l_email.add_header_entry ("Content-Type", "text/plain; charset=utf-8") l_email.add_header_entry ("Content-Transfer-Encoding", "8bit") l_email.set_message (a_message) -- send message smtp_connection_lock.lock smtp_connection.initiate_protocol smtp_connection.transfer (l_email) smtp_connection.close_protocol smtp_connection_lock.unlock end as_quoted_printable(a_string: STRING): STRING is -- Returns the Quoted-Printable representation of `a_string', -- see RFC 2047 (http://tools.ietf.org/html/rfc2047) local i: INTEGER c: CHARACTER code_point: STRING item_code: INTEGER line_length: INTEGER do create Result.make_from_string ("=?UTF-8?Q?") from i := 1 line_length := 10 until i > a_string.count loop c := a_string.item (i) item_code := a_string.item_code (i) -- Break lines longer than 75 chars if (line_length > 72) then Result.append("?=%R%N") Result.append(" =?UTF-8?Q?") line_length := 10 end if c = ' ' then Result.append ("=20") line_length := line_length + 2 elseif c = '_' then Result.append ("=5F") line_length := line_length + 2 elseif c = '=' then Result.append ("=3D") line_length := line_length + 2 elseif item_code >= 0x80 then -- Above 128 => unicode code_point := item_code.to_hex_string code_point.keep_tail (2) Result.append ("=" + code_point) line_length := line_length + 2 else -- It's a normal character Result.append_character (c) end -- increment i := i + 1 line_length := line_length + 1 end Result.append ("?=") end local_host_name: STRING -- Host name of the local machine, needed for smtp. local l_host: HOST_ADDRESS once create l_host.make_local Result := l_host.local_host_name end smtp_connection_lock: MUTEX -- Protection for smtp_connection. smtp_connection: SMTP_PROTOCOL -- Connection to the smtp server. smtp_server: STRING -- SMTP server to send mails. once Result := config_parser.get_default ("smtp_server", "localhost") end mail_sender_prefix: STRING -- Sender name prefix once Result := config_parser.get_default ("email_sender_prefix", "[Aranea]") + " " end mail_sender: STRING -- Sender of the mail. once Result := "<" + config_parser.get("email_sender_default") + ">" end create_msg_factory : A_MESSAGE_FACTORY -- create a new message factory do create Result.make end end