Added the possibility to provide the sendmail location in NOTIFICATION_SENDMAIL_MAILER.
Added NOTIFICATION_STORAGE_MAILER which allow to store the email in a storage (could be just output, file, database ...) Added SMTP implementation, based on EiffelNet SMTP_PROTOCOL. note: it is possible to exclude this by setting ecf variable "smtp_notification_email_disabled" to "True" this way help to manage dependencies, since the Eiffel Net library would not be included neither. Fixed Date header value computation.
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="ISO-8859-1"?>
|
<?xml version="1.0" encoding="ISO-8859-1"?>
|
||||||
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-12-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-12-0 http://www.eiffel.com/developers/xml/configuration-1-12-0.xsd" name="notification_email" uuid="99D9A065-CD45-4E20-9C86-579C8AD42E5E" library_target="notification_email">
|
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-14-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-14-0 http://www.eiffel.com/developers/xml/configuration-1-14-0.xsd" name="notification_email" uuid="99D9A065-CD45-4E20-9C86-579C8AD42E5E" library_target="notification_email">
|
||||||
<target name="notification_email">
|
<target name="notification_email">
|
||||||
<root all_classes="true"/>
|
<root all_classes="true"/>
|
||||||
<file_rule>
|
<file_rule>
|
||||||
@@ -11,8 +11,20 @@
|
|||||||
</option>
|
</option>
|
||||||
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
|
||||||
<library name="http" location="..\..\..\network\protocol\http\http-safe.ecf"/>
|
<library name="http" location="..\..\..\network\protocol\http\http-safe.ecf"/>
|
||||||
|
<library name="net" location="$ISE_LIBRARY\library\net\net-safe.ecf">
|
||||||
|
<condition>
|
||||||
|
<custom name="smtp_notification_email_disabled" excluded_value="true"/>
|
||||||
|
</condition>
|
||||||
|
</library>
|
||||||
<library name="process" location="$ISE_LIBRARY\library\process\process-safe.ecf"/>
|
<library name="process" location="$ISE_LIBRARY\library\process\process-safe.ecf"/>
|
||||||
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
|
<library name="time" location="$ISE_LIBRARY\library\time\time-safe.ecf"/>
|
||||||
<cluster name="src" location=".\" recursive="true"/>
|
<cluster name="src" location=".\" >
|
||||||
|
<cluster name="storage" location="$|storage"/>
|
||||||
|
<cluster name="smtp" location="$|smtp">
|
||||||
|
<condition>
|
||||||
|
<custom name="smtp_notification_email_disabled" excluded_value="true"/>
|
||||||
|
</condition>
|
||||||
|
</cluster>
|
||||||
|
</cluster>
|
||||||
</target>
|
</target>
|
||||||
</system>
|
</system>
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ note
|
|||||||
description : "[
|
description : "[
|
||||||
Component representing an email
|
Component representing an email
|
||||||
]"
|
]"
|
||||||
author : "$Author$"
|
author : "$Author: jfiat $"
|
||||||
date : "$Date$"
|
date : "$Date: 2015-06-30 11:07:17 +0200 (mar., 30 juin 2015) $"
|
||||||
revision : "$Revision$"
|
revision : "$Revision: 97586 $"
|
||||||
|
|
||||||
class
|
class
|
||||||
NOTIFICATION_EMAIL
|
NOTIFICATION_EMAIL
|
||||||
@@ -14,15 +14,17 @@ create
|
|||||||
|
|
||||||
feature {NONE} -- Initialization
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
make (a_from: like from_address; a_to_address: READABLE_STRING_8; a_subject: like subject; a_body: like body)
|
make (a_from: like from_address; a_to_address: READABLE_STRING_8; a_subject: like subject; a_content: like content)
|
||||||
-- Initialize `Current'.
|
-- Initialize `Current'.
|
||||||
|
require
|
||||||
|
well_formed_from_address: is_valid_address (a_from)
|
||||||
|
well_formed_to_address: a_to_address.has ('@')
|
||||||
do
|
do
|
||||||
initialize
|
initialize
|
||||||
from_address := a_from
|
from_address := a_from
|
||||||
subject := a_subject
|
subject := a_subject
|
||||||
body := a_body
|
content := a_content
|
||||||
to_addresses.extend (a_to_address)
|
to_addresses.extend (a_to_address)
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
initialize
|
initialize
|
||||||
@@ -37,11 +39,36 @@ feature -- Access
|
|||||||
|
|
||||||
from_address: READABLE_STRING_8
|
from_address: READABLE_STRING_8
|
||||||
|
|
||||||
|
reply_to_address: detachable READABLE_STRING_8
|
||||||
|
|
||||||
to_addresses: ARRAYED_LIST [READABLE_STRING_8]
|
to_addresses: ARRAYED_LIST [READABLE_STRING_8]
|
||||||
|
|
||||||
|
cc_addresses: detachable ARRAYED_LIST [READABLE_STRING_8]
|
||||||
|
|
||||||
|
bcc_addresses: detachable ARRAYED_LIST [READABLE_STRING_8]
|
||||||
|
|
||||||
subject: READABLE_STRING_8
|
subject: READABLE_STRING_8
|
||||||
|
|
||||||
body: READABLE_STRING_8
|
content: READABLE_STRING_8
|
||||||
|
|
||||||
|
additional_header_lines: detachable ARRAYED_LIST [READABLE_STRING_8]
|
||||||
|
-- Additional header lines.
|
||||||
|
|
||||||
|
body: like content
|
||||||
|
obsolete
|
||||||
|
"Use `content' [June/2015]"
|
||||||
|
do
|
||||||
|
Result := body
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Status report
|
||||||
|
|
||||||
|
is_valid: BOOLEAN
|
||||||
|
-- Is current email ready to be sent?
|
||||||
|
do
|
||||||
|
Result := is_valid_address (from_address) and
|
||||||
|
across to_addresses as ic all is_valid_address (ic.item) end
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Change
|
feature -- Change
|
||||||
|
|
||||||
@@ -50,13 +77,90 @@ feature -- Change
|
|||||||
date := d
|
date := d
|
||||||
end
|
end
|
||||||
|
|
||||||
|
set_subject (s: READABLE_STRING_8)
|
||||||
|
-- Set `subject' to `s'.
|
||||||
|
do
|
||||||
|
subject := s
|
||||||
|
end
|
||||||
|
|
||||||
|
set_content (s: READABLE_STRING_8)
|
||||||
|
-- Set `content' to `s'.
|
||||||
|
do
|
||||||
|
content := s
|
||||||
|
end
|
||||||
|
|
||||||
|
set_from_address (add: READABLE_STRING_8)
|
||||||
|
require
|
||||||
|
well_formed_address: add.has ('@')
|
||||||
|
do
|
||||||
|
from_address := add
|
||||||
|
end
|
||||||
|
|
||||||
|
add_cc_address (add: READABLE_STRING_8)
|
||||||
|
require
|
||||||
|
well_formed_address: add.has ('@')
|
||||||
|
local
|
||||||
|
lst: like cc_addresses
|
||||||
|
do
|
||||||
|
lst := cc_addresses
|
||||||
|
if lst = Void then
|
||||||
|
create lst.make (1)
|
||||||
|
cc_addresses := lst
|
||||||
|
end
|
||||||
|
lst.force (add)
|
||||||
|
end
|
||||||
|
|
||||||
|
add_bcc_address (add: READABLE_STRING_8)
|
||||||
|
require
|
||||||
|
well_formed_address: add.has ('@')
|
||||||
|
local
|
||||||
|
lst: like bcc_addresses
|
||||||
|
do
|
||||||
|
lst := bcc_addresses
|
||||||
|
if lst = Void then
|
||||||
|
create lst.make (1)
|
||||||
|
bcc_addresses := lst
|
||||||
|
end
|
||||||
|
lst.force (add)
|
||||||
|
end
|
||||||
|
|
||||||
|
add_header_line (a_line: READABLE_STRING_8)
|
||||||
|
require
|
||||||
|
well_formed_header_line: a_line.has (':')
|
||||||
|
local
|
||||||
|
lst: like additional_header_lines
|
||||||
|
do
|
||||||
|
lst := additional_header_lines
|
||||||
|
if lst = Void then
|
||||||
|
create lst.make (1)
|
||||||
|
additional_header_lines := lst
|
||||||
|
end
|
||||||
|
lst.force (a_line)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Reset
|
||||||
|
|
||||||
|
reset
|
||||||
|
do
|
||||||
|
reset_addresses
|
||||||
|
additional_header_lines := Void
|
||||||
|
end
|
||||||
|
|
||||||
|
reset_addresses
|
||||||
|
-- Reset all addresses.
|
||||||
|
do
|
||||||
|
to_addresses.wipe_out
|
||||||
|
cc_addresses := Void
|
||||||
|
bcc_addresses := Void
|
||||||
|
end
|
||||||
|
|
||||||
feature -- Conversion
|
feature -- Conversion
|
||||||
|
|
||||||
message: STRING_8
|
message: STRING_8
|
||||||
do
|
do
|
||||||
Result := header
|
Result := header
|
||||||
Result.append_character ('%N')
|
Result.append_character ('%N')
|
||||||
Result.append (body)
|
Result.append (content)
|
||||||
Result.append_character ('%N')
|
Result.append_character ('%N')
|
||||||
Result.append_character ('%N')
|
Result.append_character ('%N')
|
||||||
end
|
end
|
||||||
@@ -66,13 +170,14 @@ feature -- Conversion
|
|||||||
hdate: HTTP_DATE
|
hdate: HTTP_DATE
|
||||||
do
|
do
|
||||||
create Result.make (20)
|
create Result.make (20)
|
||||||
|
if attached reply_to_address as l_reply_to then
|
||||||
|
Result.append ("Reply-To: ")
|
||||||
|
Result.append (l_reply_to)
|
||||||
|
Result.append_character ('%N')
|
||||||
|
end
|
||||||
Result.append ("From: ")
|
Result.append ("From: ")
|
||||||
Result.append (from_address)
|
Result.append (from_address)
|
||||||
Result.append_character ('%N')
|
Result.append_character ('%N')
|
||||||
Result.append ("Date: ")
|
|
||||||
create hdate.make_from_date_time (date)
|
|
||||||
hdate.append_to_rfc1123_string (Result)
|
|
||||||
Result.append (" GMT%N")
|
|
||||||
Result.append ("To: ")
|
Result.append ("To: ")
|
||||||
across
|
across
|
||||||
to_addresses as c
|
to_addresses as c
|
||||||
@@ -81,18 +186,67 @@ feature -- Conversion
|
|||||||
Result.append_character (';')
|
Result.append_character (';')
|
||||||
end
|
end
|
||||||
Result.append_character ('%N')
|
Result.append_character ('%N')
|
||||||
|
if
|
||||||
|
attached cc_addresses as l_cc and then
|
||||||
|
not l_cc.is_empty
|
||||||
|
then
|
||||||
|
Result.append ("Cc: ")
|
||||||
|
across
|
||||||
|
l_cc as c
|
||||||
|
loop
|
||||||
|
Result.append (c.item)
|
||||||
|
Result.append_character (';')
|
||||||
|
end
|
||||||
|
Result.append_character ('%N')
|
||||||
|
end
|
||||||
|
if
|
||||||
|
attached bcc_addresses as l_bcc and then
|
||||||
|
not l_bcc.is_empty
|
||||||
|
then
|
||||||
|
Result.append ("Bcc: ")
|
||||||
|
across
|
||||||
|
l_bcc as c
|
||||||
|
loop
|
||||||
|
Result.append (c.item)
|
||||||
|
Result.append_character (';')
|
||||||
|
end
|
||||||
|
Result.append_character ('%N')
|
||||||
|
end
|
||||||
Result.append ("Subject: ")
|
Result.append ("Subject: ")
|
||||||
Result.append (subject)
|
Result.append (subject)
|
||||||
Result.append_character ('%N')
|
Result.append_character ('%N')
|
||||||
|
Result.append ("Date: ")
|
||||||
|
create hdate.make_from_date_time (date)
|
||||||
|
hdate.append_to_rfc1123_string (Result)
|
||||||
|
Result.append_character ('%N')
|
||||||
|
if attached additional_header_lines as l_lines and then
|
||||||
|
not l_lines.is_empty
|
||||||
|
then
|
||||||
|
across
|
||||||
|
l_lines as ic
|
||||||
|
loop
|
||||||
|
Result.append (ic.item)
|
||||||
|
Result.append_character ('%N')
|
||||||
|
end
|
||||||
|
end
|
||||||
ensure
|
ensure
|
||||||
Result.ends_with ("%N")
|
Result.ends_with ("%N")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
feature -- Helpers
|
||||||
|
|
||||||
|
is_valid_address (add: READABLE_STRING_8): BOOLEAN
|
||||||
|
-- Is `add' a valid email address?
|
||||||
|
do
|
||||||
|
-- FIXME: improve email validation
|
||||||
|
Result := add.has ('@')
|
||||||
|
end
|
||||||
|
|
||||||
invariant
|
invariant
|
||||||
-- invariant_clause: True
|
-- invariant_clause: True
|
||||||
|
|
||||||
note
|
note
|
||||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
source: "[
|
source: "[
|
||||||
Eiffel Software
|
Eiffel Software
|
||||||
|
|||||||
@@ -11,8 +11,20 @@
|
|||||||
</option>
|
</option>
|
||||||
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
<library name="base" location="$ISE_LIBRARY\library\base\base.ecf"/>
|
||||||
<library name="http" location="..\..\..\network\protocol\http\http.ecf"/>
|
<library name="http" location="..\..\..\network\protocol\http\http.ecf"/>
|
||||||
|
<library name="net" location="$ISE_LIBRARY\library\net\net.ecf">
|
||||||
|
<condition>
|
||||||
|
<custom name="smtp_notification_email_disabled" excluded_value="true"/>
|
||||||
|
</condition>
|
||||||
|
</library>
|
||||||
<library name="process" location="$ISE_LIBRARY\library\process\process.ecf"/>
|
<library name="process" location="$ISE_LIBRARY\library\process\process.ecf"/>
|
||||||
<library name="time" location="$ISE_LIBRARY\library\time\time.ecf"/>
|
<library name="time" location="$ISE_LIBRARY\library\time\time.ecf"/>
|
||||||
<cluster name="src" location="." recursive="true"/>
|
<cluster name="src" location=".">
|
||||||
|
<cluster name="storage" location="$|storage"/>
|
||||||
|
<cluster name="smtp" location="$|smtp">
|
||||||
|
<condition>
|
||||||
|
<custom name="smtp_notification_email_disabled" excluded_value="true"/>
|
||||||
|
</condition>
|
||||||
|
</cluster>
|
||||||
|
</cluster>
|
||||||
</target>
|
</target>
|
||||||
</system>
|
</system>
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ note
|
|||||||
description: "[
|
description: "[
|
||||||
Component responsible to send email
|
Component responsible to send email
|
||||||
]"
|
]"
|
||||||
author: "$Author$"
|
author: "$Author: jfiat $"
|
||||||
date: "$Date$"
|
date: "$Date: 2015-06-30 11:07:17 +0200 (mar., 30 juin 2015) $"
|
||||||
revision: "$Revision$"
|
revision: "$Revision: 97586 $"
|
||||||
|
|
||||||
deferred class
|
deferred class
|
||||||
NOTIFICATION_MAILER
|
NOTIFICATION_MAILER
|
||||||
@@ -45,8 +45,40 @@ feature -- Basic operation
|
|||||||
deferred
|
deferred
|
||||||
end
|
end
|
||||||
|
|
||||||
|
feature -- Error
|
||||||
|
|
||||||
|
has_error: BOOLEAN
|
||||||
|
-- Previous operation reported error?
|
||||||
|
-- Use `reset_errors', to reset this state.
|
||||||
|
do
|
||||||
|
Result := attached last_errors as lst and then not lst.is_empty
|
||||||
|
end
|
||||||
|
|
||||||
|
reset_errors
|
||||||
|
-- Reset last errors.
|
||||||
|
do
|
||||||
|
last_errors := Void
|
||||||
|
end
|
||||||
|
|
||||||
|
last_errors: detachable ARRAYED_LIST [READABLE_STRING_32]
|
||||||
|
-- Last reported errors since previous `reset_errors' call.
|
||||||
|
|
||||||
|
report_error (a_msg: READABLE_STRING_GENERAL)
|
||||||
|
-- Report error message `a_msg'.
|
||||||
|
local
|
||||||
|
lst: like last_errors
|
||||||
|
do
|
||||||
|
lst := last_errors
|
||||||
|
if lst = Void then
|
||||||
|
create lst.make (1)
|
||||||
|
last_errors := lst
|
||||||
|
end
|
||||||
|
lst.force (a_msg.to_string_32)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
note
|
note
|
||||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
source: "[
|
source: "[
|
||||||
Eiffel Software
|
Eiffel Software
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
note
|
||||||
|
description: "Mailer that does nothing."
|
||||||
|
date: "$Date: 2015-06-30 15:49:56 +0200 (mar., 30 juin 2015) $"
|
||||||
|
revision: "$Revision: 97588 $"
|
||||||
|
|
||||||
|
class
|
||||||
|
NOTIFICATION_NULL_MAILER
|
||||||
|
|
||||||
|
inherit
|
||||||
|
NOTIFICATION_MAILER
|
||||||
|
|
||||||
|
feature -- Status
|
||||||
|
|
||||||
|
is_available: BOOLEAN = True
|
||||||
|
-- <Precursor>
|
||||||
|
|
||||||
|
feature -- Basic operation
|
||||||
|
|
||||||
|
process_email (a_email: NOTIFICATION_EMAIL)
|
||||||
|
-- <Precursor>
|
||||||
|
do
|
||||||
|
end
|
||||||
|
|
||||||
|
note
|
||||||
|
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||||
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
|
source: "[
|
||||||
|
Eiffel Software
|
||||||
|
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||||
|
Telephone 805-685-1006, Fax 805-685-6869
|
||||||
|
Website http://www.eiffel.com
|
||||||
|
Customer support http://support.eiffel.com
|
||||||
|
]"
|
||||||
|
end
|
||||||
@@ -2,9 +2,9 @@ note
|
|||||||
description : "[
|
description : "[
|
||||||
NOTIFICATION_MAILER using sendmail as mailtool
|
NOTIFICATION_MAILER using sendmail as mailtool
|
||||||
]"
|
]"
|
||||||
author: "$Author$"
|
author: "$Author: jfiat $"
|
||||||
date: "$Date$"
|
date: "$Date: 2015-06-30 15:49:56 +0200 (mar., 30 juin 2015) $"
|
||||||
revision: "$Revision$"
|
revision: "$Revision: 97588 $"
|
||||||
|
|
||||||
class
|
class
|
||||||
NOTIFICATION_SENDMAIL_MAILER
|
NOTIFICATION_SENDMAIL_MAILER
|
||||||
@@ -16,23 +16,29 @@ inherit
|
|||||||
end
|
end
|
||||||
|
|
||||||
create
|
create
|
||||||
default_create
|
default_create,
|
||||||
|
make_with_location
|
||||||
|
|
||||||
feature {NONE} -- Initialization
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
|
make_with_location (a_path: READABLE_STRING_GENERAL)
|
||||||
|
do
|
||||||
|
make (a_path, <<"-t">>)
|
||||||
|
set_stdin_mode (True, "%N.%N%N")
|
||||||
|
end
|
||||||
|
|
||||||
default_create
|
default_create
|
||||||
do
|
do
|
||||||
Precursor
|
Precursor
|
||||||
make ("/usr/sbin/sendmail", <<"-t">>)
|
make_with_location ("/usr/sbin/sendmail")
|
||||||
if not is_available then
|
if not is_available then
|
||||||
make ("/usr/bin/sendmail", <<"-t">>)
|
make_with_location ("/usr/bin/sendmail")
|
||||||
end
|
end
|
||||||
set_stdin_mode (True, "%N.%N%N")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
note
|
note
|
||||||
copyright: "2011-2013, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||||
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
source: "[
|
source: "[
|
||||||
Eiffel Software
|
Eiffel Software
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
note
|
||||||
|
description: "Summary description for {NOTIFICATION_STORAGE_MAILER}."
|
||||||
|
author: ""
|
||||||
|
date: "$Date: 2015-06-30 15:49:56 +0200 (mar., 30 juin 2015) $"
|
||||||
|
revision: "$Revision: 97588 $"
|
||||||
|
|
||||||
|
class
|
||||||
|
NOTIFICATION_STORAGE_MAILER
|
||||||
|
|
||||||
|
inherit
|
||||||
|
NOTIFICATION_MAILER
|
||||||
|
|
||||||
|
create
|
||||||
|
make
|
||||||
|
|
||||||
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
|
make (a_storage: NOTIFICATION_EMAIL_STORAGE)
|
||||||
|
do
|
||||||
|
storage := a_storage
|
||||||
|
end
|
||||||
|
|
||||||
|
storage: NOTIFICATION_EMAIL_STORAGE
|
||||||
|
|
||||||
|
feature -- Status report
|
||||||
|
|
||||||
|
is_available: BOOLEAN
|
||||||
|
-- <Precursor>
|
||||||
|
do
|
||||||
|
Result := storage.is_available
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Basic operation
|
||||||
|
|
||||||
|
process_email (a_email: NOTIFICATION_EMAIL)
|
||||||
|
-- <Precursor>
|
||||||
|
do
|
||||||
|
storage.put (a_email)
|
||||||
|
if storage.has_error then
|
||||||
|
report_error ("Issue storing email.")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
note
|
||||||
|
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||||
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
|
source: "[
|
||||||
|
Eiffel Software
|
||||||
|
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||||
|
Telephone 805-685-1006, Fax 805-685-6869
|
||||||
|
Website http://www.eiffel.com
|
||||||
|
Customer support http://support.eiffel.com
|
||||||
|
]"
|
||||||
|
end
|
||||||
@@ -0,0 +1,181 @@
|
|||||||
|
note
|
||||||
|
description: "[
|
||||||
|
Notification mailer based on STMP protocol.
|
||||||
|
|
||||||
|
Note: it is based on EiffelNet {SMTP_PROTOCOL} implementation, and may not be complete.
|
||||||
|
]"
|
||||||
|
author: "$Author: jfiat $"
|
||||||
|
date: "$Date: 2015-06-30 11:07:17 +0200 (mar., 30 juin 2015) $"
|
||||||
|
revision: "$Revision: 97586 $"
|
||||||
|
|
||||||
|
class
|
||||||
|
NOTIFICATION_SMTP_MAILER
|
||||||
|
|
||||||
|
inherit
|
||||||
|
NOTIFICATION_MAILER
|
||||||
|
|
||||||
|
create
|
||||||
|
make,
|
||||||
|
make_with_user
|
||||||
|
|
||||||
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
|
make (a_smtp_server: READABLE_STRING_8)
|
||||||
|
do
|
||||||
|
make_with_user (a_smtp_server, Void, Void)
|
||||||
|
end
|
||||||
|
|
||||||
|
make_with_user (a_smtp_server: READABLE_STRING_8; a_user: detachable READABLE_STRING_8; a_password: detachable READABLE_STRING_8)
|
||||||
|
-- Initialize `Current'.
|
||||||
|
local
|
||||||
|
i: INTEGER
|
||||||
|
do
|
||||||
|
i := a_smtp_server.index_of (':', 1)
|
||||||
|
if i > 0 then
|
||||||
|
smtp_host := a_smtp_server.substring (1, i - 1)
|
||||||
|
smtp_port := a_smtp_server.substring (i + 1, a_smtp_server.count).to_integer
|
||||||
|
else
|
||||||
|
smtp_host := a_smtp_server
|
||||||
|
smtp_port := 0
|
||||||
|
end
|
||||||
|
username := a_user
|
||||||
|
initialize
|
||||||
|
end
|
||||||
|
|
||||||
|
initialize
|
||||||
|
-- Initialize service.
|
||||||
|
local
|
||||||
|
l_address_factory: INET_ADDRESS_FACTORY
|
||||||
|
do
|
||||||
|
if attached username as u then
|
||||||
|
create smtp_protocol.make (smtp_host, u)
|
||||||
|
else
|
||||||
|
-- Get local host name needed in creation of SMTP_PROTOCOL.
|
||||||
|
create l_address_factory
|
||||||
|
create smtp_protocol.make (smtp_host, l_address_factory.create_localhost.host_name)
|
||||||
|
end
|
||||||
|
if smtp_port > 0 then
|
||||||
|
smtp_protocol.set_default_port (smtp_port)
|
||||||
|
end
|
||||||
|
reset_errors
|
||||||
|
end
|
||||||
|
|
||||||
|
smtp_protocol: SMTP_PROTOCOL
|
||||||
|
-- SMTP protocol.
|
||||||
|
|
||||||
|
feature -- Access
|
||||||
|
|
||||||
|
smtp_host: READABLE_STRING_8
|
||||||
|
|
||||||
|
smtp_port: INTEGER
|
||||||
|
|
||||||
|
username: detachable READABLE_STRING_8
|
||||||
|
|
||||||
|
feature -- Status
|
||||||
|
|
||||||
|
is_available: BOOLEAN
|
||||||
|
do
|
||||||
|
Result := True
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Basic operation
|
||||||
|
|
||||||
|
process_email (a_email: NOTIFICATION_EMAIL)
|
||||||
|
-- Process the sending of `a_email'
|
||||||
|
local
|
||||||
|
l_email: EMAIL
|
||||||
|
h: STRING
|
||||||
|
k,v: STRING
|
||||||
|
i: INTEGER
|
||||||
|
hdate: HTTP_DATE
|
||||||
|
do
|
||||||
|
create l_email.make_with_entry (a_email.from_address, addresses_to_header_line_value (a_email.to_addresses))
|
||||||
|
if attached a_email.reply_to_address as l_reply_to then
|
||||||
|
l_email.add_header_entry ({EMAIL_CONSTANTS}.h_reply_to, l_reply_to)
|
||||||
|
end
|
||||||
|
|
||||||
|
if attached a_email.cc_addresses as lst then
|
||||||
|
l_email.add_header_entry ({EMAIL_CONSTANTS}.h_cc, addresses_to_header_line_value (lst))
|
||||||
|
end
|
||||||
|
if attached a_email.bcc_addresses as lst then
|
||||||
|
l_email.add_header_entry ({EMAIL_CONSTANTS}.h_bcc, addresses_to_header_line_value (lst))
|
||||||
|
end
|
||||||
|
l_email.set_message (a_email.content)
|
||||||
|
l_email.add_header_entry ({EMAIL_CONSTANTS}.H_subject, a_email.subject)
|
||||||
|
|
||||||
|
create h.make_empty
|
||||||
|
create hdate.make_from_date_time (a_email.date)
|
||||||
|
hdate.append_to_rfc1123_string (h)
|
||||||
|
l_email.add_header_entry ("Date", h)
|
||||||
|
|
||||||
|
if attached a_email.additional_header_lines as lst then
|
||||||
|
across
|
||||||
|
lst as ic
|
||||||
|
loop
|
||||||
|
h := ic.item
|
||||||
|
i := h.index_of (':', 1)
|
||||||
|
if i > 0 then
|
||||||
|
k := h.head (i - 1)
|
||||||
|
v := h.substring (i + 1, h.count)
|
||||||
|
l_email.add_header_entry (k, v)
|
||||||
|
else
|
||||||
|
check is_header_line: False end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
smtp_send_email (l_email)
|
||||||
|
end
|
||||||
|
|
||||||
|
feature {NONE} -- Implementation
|
||||||
|
|
||||||
|
addresses_to_header_line_value (lst: ITERABLE [READABLE_STRING_8]): STRING
|
||||||
|
local
|
||||||
|
l_need_separator: BOOLEAN
|
||||||
|
do
|
||||||
|
create Result.make (10)
|
||||||
|
l_need_separator := False
|
||||||
|
across
|
||||||
|
lst as ic
|
||||||
|
loop
|
||||||
|
if l_need_separator then
|
||||||
|
Result.append_character (',')
|
||||||
|
Result.append_character (' ')
|
||||||
|
else
|
||||||
|
l_need_separator := True
|
||||||
|
end
|
||||||
|
Result.append (ic.item)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
smtp_send_email (a_email: EMAIL)
|
||||||
|
-- Send the email represented by `a_email'.
|
||||||
|
local
|
||||||
|
retried: BOOLEAN
|
||||||
|
do
|
||||||
|
if not retried then
|
||||||
|
smtp_protocol.initiate_protocol
|
||||||
|
smtp_protocol.transfer (a_email)
|
||||||
|
smtp_protocol.close_protocol
|
||||||
|
if smtp_protocol.error then
|
||||||
|
report_error ("smtp_protocol reported an error.")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
rescue
|
||||||
|
report_error ("smtp_protocol raised an exception.")
|
||||||
|
retried := True
|
||||||
|
retry
|
||||||
|
end
|
||||||
|
|
||||||
|
note
|
||||||
|
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||||
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
|
source: "[
|
||||||
|
Eiffel Software
|
||||||
|
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||||
|
Telephone 805-685-1006, Fax 805-685-6869
|
||||||
|
Website http://www.eiffel.com
|
||||||
|
Customer support http://support.eiffel.com
|
||||||
|
]"
|
||||||
|
end
|
||||||
|
|
||||||
@@ -0,0 +1,74 @@
|
|||||||
|
note
|
||||||
|
description: "Store email in specific file (could also be stderr, ...)."
|
||||||
|
date: "$Date: 2015-06-30 15:49:56 +0200 (mar., 30 juin 2015) $"
|
||||||
|
revision: "$Revision: 97588 $"
|
||||||
|
|
||||||
|
class
|
||||||
|
NOTIFICATION_EMAIL_FILE_STORAGE
|
||||||
|
|
||||||
|
inherit
|
||||||
|
NOTIFICATION_EMAIL_STORAGE
|
||||||
|
|
||||||
|
create
|
||||||
|
make
|
||||||
|
|
||||||
|
feature {NONE} -- Initialization
|
||||||
|
|
||||||
|
make (a_output_file: FILE)
|
||||||
|
require
|
||||||
|
a_output_file_valid: a_output_file.exists
|
||||||
|
do
|
||||||
|
output := a_output_file
|
||||||
|
end
|
||||||
|
|
||||||
|
output: FILE
|
||||||
|
|
||||||
|
feature -- Status report
|
||||||
|
|
||||||
|
is_available: BOOLEAN
|
||||||
|
-- Is associated storage available?
|
||||||
|
do
|
||||||
|
Result := output.exists and output.is_access_writable
|
||||||
|
end
|
||||||
|
|
||||||
|
has_error: BOOLEAN
|
||||||
|
-- Last operation reported an error?
|
||||||
|
|
||||||
|
feature -- Storage
|
||||||
|
|
||||||
|
put (a_email: NOTIFICATION_EMAIL)
|
||||||
|
-- Store `a_email'.
|
||||||
|
local
|
||||||
|
retried: BOOLEAN
|
||||||
|
l_close_needed: BOOLEAN
|
||||||
|
do
|
||||||
|
if not retried then
|
||||||
|
has_error := False
|
||||||
|
if not output.is_open_write then
|
||||||
|
output.open_write
|
||||||
|
l_close_needed := True
|
||||||
|
end
|
||||||
|
output.put_string ("%N----%N" + a_email.message)
|
||||||
|
if l_close_needed then
|
||||||
|
output.close
|
||||||
|
else
|
||||||
|
output.flush
|
||||||
|
end
|
||||||
|
end
|
||||||
|
rescue
|
||||||
|
retried := True
|
||||||
|
has_error := True
|
||||||
|
retry
|
||||||
|
end
|
||||||
|
|
||||||
|
;note
|
||||||
|
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||||
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
|
source: "[
|
||||||
|
Eiffel Software
|
||||||
|
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||||
|
Telephone 805-685-1006, Fax 805-685-6869
|
||||||
|
Website http://www.eiffel.com
|
||||||
|
Customer support http://support.eiffel.com
|
||||||
|
]"
|
||||||
|
end
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
note
|
||||||
|
description: "Abtract interface of email storage."
|
||||||
|
date: "$Date: 2015-06-30 15:49:56 +0200 (mar., 30 juin 2015) $"
|
||||||
|
revision: "$Revision: 97588 $"
|
||||||
|
|
||||||
|
deferred class
|
||||||
|
NOTIFICATION_EMAIL_STORAGE
|
||||||
|
|
||||||
|
feature -- Status report
|
||||||
|
|
||||||
|
is_available: BOOLEAN
|
||||||
|
-- Is associated storage available?
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
has_error: BOOLEAN
|
||||||
|
-- Last operation reported an error?
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
feature -- Storage
|
||||||
|
|
||||||
|
put (a_email: NOTIFICATION_EMAIL)
|
||||||
|
-- Store `a_email'.
|
||||||
|
deferred
|
||||||
|
end
|
||||||
|
|
||||||
|
note
|
||||||
|
copyright: "2011-2015, Jocelyn Fiat, Javier Velilla, Olivier Ligot, Eiffel Software and others"
|
||||||
|
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
|
||||||
|
source: "[
|
||||||
|
Eiffel Software
|
||||||
|
5949 Hollister Ave., Goleta, CA 93117 USA
|
||||||
|
Telephone 805-685-1006, Fax 805-685-6869
|
||||||
|
Website http://www.eiffel.com
|
||||||
|
Customer support http://support.eiffel.com
|
||||||
|
]"
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user