Extract notification library from the CMS draft application

The new library is located in library/runtime/process/notification.
This allows to use it apart from the CMS.
This commit is contained in:
Olivier Ligot
2013-06-12 11:31:31 +02:00
parent fa8b3fdccc
commit 6fbe66ff7b
17 changed files with 69 additions and 31 deletions

View File

@@ -23,6 +23,7 @@
<library name="wsf" location="..\..\..\library\server\wsf\wsf-safe.ecf" readonly="false"/>
<library name="wsf_html" location="..\..\..\library\server\wsf_html\wsf_html-safe.ecf" readonly="false"/>
<library name="wsf_session" location="..\..\..\library\server\wsf\wsf_session-safe.ecf" readonly="false"/>
<library name="notification" location="..\..\..\library\runtime\process\notification\notification-safe.ecf"/>
<cluster name="src" location=".\src\" recursive="true"/>
</target>
</system>

View File

@@ -24,6 +24,7 @@
<library name="uri_template" location="..\..\..\library\text\parser\uri_template\uri_template.ecf"/>
<library name="wsf" location="..\..\..\library\server\wsf\wsf.ecf" readonly="false"/>
<library name="wsf_session" location="..\..\..\library\server\wsf\wsf_session.ecf" readonly="false"/>
<library name="notification" location="..\..\..\library\runtime\process\notification\notification.ecf"/>
<cluster name="src" location=".\src\" recursive="true">
</cluster>
</target>

View File

@@ -57,7 +57,7 @@ feature -- Access
auth_engine: CMS_AUTH_ENGINE
-- CMS Authentication engine
mailer: CMS_MAILER
mailer: NOTIFICATION_MAILER
feature {NONE} -- Initialization
@@ -115,12 +115,12 @@ feature {NONE} -- Initialization
build_mailer
local
ch_mailer: CMS_CHAIN_MAILER
ch_mailer: NOTIFICATION_CHAIN_MAILER
st_mailer: CMS_STORAGE_MAILER
do
create st_mailer.make (storage)
create ch_mailer.make (st_mailer)
ch_mailer.set_next (create {CMS_SENDMAIL_MAILER})
ch_mailer.set_next (create {NOTIFICATION_SENDMAIL_MAILER})
mailer := ch_mailer
end

View File

@@ -413,7 +413,7 @@ feature -- Content type
feature -- Notification
mailer: CMS_MAILER
mailer: NOTIFICATION_MAILER
feature -- Core Execution

View File

@@ -32,7 +32,7 @@ feature -- Access
deferred
end
mailer: CMS_MAILER
mailer: NOTIFICATION_MAILER
-- CMS email engine
deferred
end

View File

@@ -75,7 +75,7 @@ feature -- Execution
password_form_submit (fd: WSF_FORM_DATA; b: STRING)
local
e: detachable CMS_EMAIL
e: detachable NOTIFICATION_EMAIL
l_uuid: UUID
do
debug
@@ -144,7 +144,7 @@ feature -- Execution
Result := f
end
new_password_email (u: CMS_USER; a_mail_address: STRING; a_extra: READABLE_STRING_8): CMS_EMAIL
new_password_email (u: CMS_USER; a_mail_address: STRING; a_extra: READABLE_STRING_8): NOTIFICATION_EMAIL
local
b: STRING
opts: CMS_URL_API_OPTIONS

View File

@@ -73,7 +73,7 @@ feature -- Execution
b: STRING
u: detachable CMS_USER
up: detachable CMS_USER_PROFILE
e: detachable CMS_EMAIL
e: detachable NOTIFICATION_EMAIL
l_pass: detachable READABLE_STRING_32
l_uuid: UUID
do
@@ -174,7 +174,7 @@ feature -- Execution
Result := f
end
new_registration_email (a_mail_address: STRING; u: CMS_USER; a_password: detachable like {CMS_USER}.password; a_extra: READABLE_STRING_8): CMS_EMAIL
new_registration_email (a_mail_address: STRING; u: CMS_USER; a_password: detachable like {CMS_USER}.password; a_extra: READABLE_STRING_8): NOTIFICATION_EMAIL
require
has_clear_password: u.password /= Void or else a_password /= Void
local
@@ -202,7 +202,7 @@ feature -- Execution
create Result.make (service.site_email, a_mail_address, "Account details for " + u.name + " at " + service.site_name, b)
end
new_user_account_email (a_mail_address: STRING; u: CMS_USER): CMS_EMAIL
new_user_account_email (a_mail_address: STRING; u: CMS_USER): NOTIFICATION_EMAIL
local
b: STRING
opts: CMS_URL_API_OPTIONS

View File

@@ -1,58 +0,0 @@
note
description: "Summary description for {CMS_CHAIN_MAILER}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
CMS_CHAIN_MAILER
inherit
CMS_MAILER
create
make
feature {NONE} -- Initialization
make (a_mailer: like active)
do
active := a_mailer
end
feature -- Access
active: CMS_MAILER
next: detachable CMS_MAILER
feature -- Status
is_available: BOOLEAN
do
Result := active.is_available
if not Result and attached next as l_next then
Result := l_next.is_available
end
end
feature -- Change
set_next (m: like next)
do
next := m
end
feature -- Basic operation
process_email (a_email: CMS_EMAIL)
do
if active.is_available then
active.process_email (a_email)
end
if attached next as l_next and then l_next.is_available then
l_next.process_email (a_email)
end
end
end

View File

@@ -1,97 +0,0 @@
note
description : "[
Component representing an email
]"
author : "$Author$"
date : "$Date$"
revision : "$Revision$"
class
CMS_EMAIL
create
make
feature {NONE} -- Initialization
make (a_from: like from_address; a_to_address: READABLE_STRING_8; a_subject: like subject; a_body: like body)
-- Initialize `Current'.
do
initialize
from_address := a_from
subject := a_subject
body := a_body
to_addresses.extend (a_to_address)
end
initialize
do
create date.make_now_utc
create to_addresses.make (1)
end
feature -- Access
date: DATE_TIME
from_address: READABLE_STRING_8
to_addresses: ARRAYED_LIST [READABLE_STRING_8]
subject: READABLE_STRING_8
body: READABLE_STRING_8
feature -- Change
set_date (d: like date)
do
date := d
end
feature -- Conversion
message: STRING_8
do
Result := header
Result.append ("%N")
Result.append (body)
Result.append ("%N")
Result.append ("%N")
end
header: STRING_8
do
create Result.make (20)
Result.append ("From: " + from_address + "%N")
Result.append ("Date: " + date_to_rfc1123_http_date_format (date) + " GMT%N")
Result.append ("To: ")
across
to_addresses as c
loop
Result.append (c.item)
Result.append_character (';')
end
Result.append_character ('%N')
Result.append ("Subject: " + subject + "%N")
ensure
Result.ends_with ("%N")
end
feature {NONE} -- Implementation
date_to_rfc1123_http_date_format (dt: DATE_TIME): STRING_8
-- String representation of `dt' using the RFC 1123
local
d: HTTP_DATE
do
create d.make_from_date_time (dt)
Result := d.rfc1123_string
end
invariant
-- invariant_clause: True
end

View File

@@ -1,197 +0,0 @@
note
description : "Objects that ..."
author : "$Author$"
date : "$Date$"
revision : "$Revision$"
class
CMS_EXTERNAL_MAILER
inherit
CMS_MAILER
-- SHARED_EXECUTION_ENVIRONMENT
create
make
feature {NONE} -- Initialization
make (a_exe: like executable_path; args: detachable ITERABLE [READABLE_STRING_8])
-- Initialize `Current'.
do
set_parameters (a_exe, args)
end
executable_path: READABLE_STRING_8
arguments: detachable ARRAYED_LIST [STRING_8]
stdin_mode_set: BOOLEAN
-- Use `stdin' to pass email message, rather than using local file?
stdin_termination_sequence: detachable STRING
-- Termination sequence for the stdin mode
--| If any, this tells the executable all the data has been provided
--| For instance, using sendmail, you should have "%N.%N%N"
feature -- Status
is_available: BOOLEAN
local
f: RAW_FILE
do
create f.make (executable_path)
Result := f.exists
end
feature -- Change
set_parameters (cmd: like executable_path; args: detachable ITERABLE [READABLE_STRING_8])
-- Set parameters `executable_path' and associated `arguments'
local
l_args: like arguments
do
executable_path := cmd
if args = Void then
arguments := Void
else
create l_args.make (5)
across
args as c
loop
l_args.force (c.item)
end
arguments := l_args
end
end
set_stdin_mode (b: BOOLEAN; v: like stdin_termination_sequence)
-- Set the `stdin_mode_set' value
-- and provide optional termination sequence when stdin mode is selected.
do
stdin_mode_set := b
stdin_termination_sequence := v
end
feature -- Basic operation
process_email (a_email: CMS_EMAIL)
local
l_factory: PROCESS_FACTORY
args: like arguments
p: detachable PROCESS
retried: INTEGER
do
if retried = 0 then
create l_factory
if stdin_mode_set then
p := l_factory.process_launcher (executable_path, arguments, Void)
p.set_hidden (True)
p.set_separate_console (False)
p.redirect_input_to_stream
p.launch
if p.launched then
p.put_string (a_email.message)
if attached stdin_termination_sequence as v then
p.put_string (v)
end
end
else
if attached arguments as l_args then
args := l_args.twin
else
if attached {RAW_FILE} new_temporary_file (generator) as f then
f.create_read_write
f.put_string (a_email.message)
f.close
create args.make (1)
args.force (f.name)
end
end
p := l_factory.process_launcher (executable_path, args, Void)
p.set_hidden (True)
p.set_separate_console (False)
p.launch
end
if p.launched and not p.has_exited then
p.wait_for_exit_with_timeout (1_000_000)
if not p.has_exited then
p.terminate
if not p.has_exited then
p.wait_for_exit_with_timeout (1_000_000)
end
end
end
elseif retried = 1 then
if p /= Void and then p.launched and then not p.has_exited then
p.terminate
if not p.has_exited then
p.wait_for_exit_with_timeout (1_000_000)
end
end
end
rescue
retried := retried + 1
retry
end
feature {NONE} -- Implementation
new_temporary_file (a_extension: detachable STRING_8): RAW_FILE
-- Create file with temporary name.
-- With concurrent execution, noting ensures that {FILE_NAME}.make_temporary_name is unique
-- So using `a_extension' may help
local
fn: FILE_NAME
s: like {FILE_NAME}.string
f: detachable like new_temporary_file
i: INTEGER
do
-- With concurrent execution, nothing ensures that {FILE_NAME}.make_temporary_name is unique
-- So let's try to find
from
until
f /= Void or i > 1000
loop
create fn.make_temporary_name
s := fn.string
if i > 0 then
s.append_character ('-')
s.append_integer (i)
create fn.make_from_string (s)
end
if a_extension /= Void then
fn.add_extension (a_extension)
end
s := fn.string
create f.make (fn.string)
if f.exists then
i := i + 1
f := Void
end
end
if f = Void then
Result := new_temporary_file (Void)
else
Result := f
check not_temporary_file_exists: not Result.exists end
check temporary_creatable: Result.is_creatable end
end
ensure
not_result_exists: not Result.exists
result_creatable: Result.is_creatable
end
feature {NONE} -- Environment
Execution_environment: EXECUTION_ENVIRONMENT
once
create Result
end
invariant
end

View File

@@ -1,48 +0,0 @@
note
description : "[
Component responsible to send email
]"
author : "$Author$"
date : "$Date$"
revision : "$Revision$"
deferred class
CMS_MAILER
feature -- Status
is_available: BOOLEAN
-- Is mailer available to use?
deferred
end
feature -- Basic operation
process_emails (lst: ITERABLE [CMS_EMAIL])
-- Process set of emails `lst'
require
is_available
do
across
lst as c
loop
process_email (c.item)
end
end
safe_process_email (a_email: CMS_EMAIL)
-- Same as `process_email', but include the check of `is_available'
do
if is_available then
process_email (a_email)
end
end
process_email (a_email: CMS_EMAIL)
-- Process the sending of `a_email'
require
is_available
deferred
end
end

View File

@@ -1,34 +0,0 @@
note
description : "[
CMS_MAILER using sendmail as mailtool
]"
author : "$Author$"
date : "$Date$"
revision : "$Revision$"
class
CMS_SENDMAIL_MAILER
inherit
CMS_EXTERNAL_MAILER
redefine
default_create
end
create
default_create
feature {NONE} -- Initialization
default_create
do
Precursor
make ("/usr/sbin/sendmail", <<"-t">>)
if not is_available then
make ("/usr/bin/sendmail", <<"-t">>)
end
set_stdin_mode (True, "%N.%N%N")
end
end

View File

@@ -8,7 +8,7 @@ class
CMS_STORAGE_MAILER
inherit
CMS_MAILER
NOTIFICATION_MAILER
create
make
@@ -30,7 +30,7 @@ feature -- Status
feature -- Basic operation
process_email (a_email: CMS_EMAIL)
process_email (a_email: NOTIFICATION_EMAIL)
do
storage.save_email (a_email)
end

View File

@@ -259,7 +259,7 @@ feature -- Change: user_role
feature -- Email
save_email (a_email: CMS_EMAIL)
save_email (a_email: NOTIFICATION_EMAIL)
local
dn: STRING
fn: FILE_NAME

View File

@@ -130,7 +130,7 @@ feature -- Change: roles and permissions
feature -- Email
save_email (a_email: CMS_EMAIL)
save_email (a_email: NOTIFICATION_EMAIL)
deferred
end