@creation-date 2000-09-01
@cvs-id $Id$
}
ad_proc -public acs_message_p {
{message_id}
} {
Check if an integer is a valid OpenACS message id.
} {
return [string equal [db_exec_plsql acs_message_p {
begin
:1 := acs_message.message_p(:message_id);
end;
}] "t"]
}
ad_page_contract_filter acs_message_id { name value } {
Checks whether the value (assumed to be an integer) is the id
of an already-existing OpenACS message.
} {
# empty is okay (handled by notnull)
if {$value eq ""} {
return 1
}
if {![acs_message_p $value]} {
ad_complain "$name ($value) does not refer to a valid OpenACS message"
return 0
}
return 1
}
ad_proc -public acs_messaging_format_as_html {
{mime_type}
{content}
} {
Returns a string of HTML which appropriately renders the content
given its mime content-type. This function supports three content
types, "text/plain", "text/plain; format=flowed", and "text/html"
@param mime_type MIME content-type of content
@param content Text to view
} {
if {$mime_type eq "text/plain"} {
set result "[ns_quotehtml $content]
"
} elseif {$mime_type eq "text/plain; format=flowed"} {
set result [ad_text_to_html -- $content]
} elseif {$mime_type eq "text/html"} {
set result $content
} else {
set result "content type undecipherable"
}
return $result
}
ad_proc -public acs_messaging_first_ancestor {
{message_id}
} {
Takes the message_id of an acs_message and returns
the message_id of the first ancestor message (i.e. the message
that originated the thread).
} {
db_1row acs_message_first_ancestor {
select acs_message.first_ancestor(:message_id) as ancestor_id from dual
}
return $ancestor_id
}
ad_proc -public acs_messaging_send {
{-message_id:required}
{-recipient_id:required}
{-grouping_id ""}
{-wait_until ""}
} {
Schedule one message to be sent to one party.
} {
db_dml {
begin
acs_message.send (
message_id => :message_id,
recipient_id => :recipient_id,
grouping_id => :grouping_id,
wait_until => :wait_until
);
end;
}
}
ad_proc -public acs_messaging_send_query {
{-message_id:required}
{-query:required}
{-bind ""}
} {
Given an SQL query returning columns recipient_id, grouping_id,
and wait_until, arrange for all to be sent for this message.
Example:
acs_message_send_query -message_id $new_message -query {
select subscriber_id as recipient_id, forum_id as grouping_id,
bboard_util.next_period(period) as wait_until
from bboard_forum_subscribers
where forum_id = :forum_id
} -bind [list forum_id $forum_id]
Assuming bboard_util.next_period(period) returns the next date at
which a digest should be sent, the above will enter info to send
all subscriptions for a single message.
The bind argument, if given, must be a list, NOT an ns_set.
} {
# Makes sure not to insert values that are already there--silent "failure"
# because it's really a vacuous success.
db_dml insert_messaging_by_query "
insert into acs_messages_outgoing
(message_id, to_address, grouping_id, wait_until)
select :m__message_id, p.email, q.grouping_id,
nvl(q.wait_until, SYSDATE) as wait_until
from ($query) q, parties p
where not exists (select 1 from acs_messages_outgoing o
where o.message_id = :m__message_id
and p.email = o.to_address)
and p.party_id = q.recipient_id
" -bind [concat $bind [list m__message_id $message_id]]
}
ad_proc -private acs_messaging_timezone_offset {
} {
Returns a best guess of the timezone offset for the machine.
} {
return [format "%+05d" [expr {([lindex [ns_localtime] 2] - [lindex [ns_gmtime] 2]) * 100]}]
}
ad_proc -private acs_messaging_process_queue {
} {
Process the message queue, sending any reasonable messages.
} {
db_foreach acs_message_send {} {
if {![catch {
acs_mail_lite::send -send_immediately \
-to_addr $recip_email \
-from_addr $sender_email \
-subject $title \
-body $content
} errMsg]} {
# everything went well, dequeue
db_dml acs_message_remove_from_queue {}
} else {
ns_log "Error" "acs-messaging: Error processing queue: $errMsg"
}
}
}
# Local variables:
# mode: tcl
# tcl-indent-level: 4
# indent-tabs-mode: nil
# End:
acs-messaging-v5-0-2-1-0/tcl/acs-messaging-procs.xql 0000664 0000000 0000000 00000000555 12630315015 0022074 0 ustar 00root root 0000000 0000000
delete from acs_messages_outgoing
where message_id = :sending_message_id
and to_address = :recip_email
acs-messaging-v5-0-2-1-0/tcl/test/ 0000775 0000000 0000000 00000000000 12630315015 0016453 5 ustar 00root root 0000000 0000000 acs-messaging-v5-0-2-1-0/tcl/test/acs-messaging-procs.tcl 0000664 0000000 0000000 00000001617 12630315015 0023031 0 ustar 00root root 0000000 0000000 ad_library {
Automated tests.
@author Joel Aufrecht
@creation-date 2 Nov 2003
@cvs-id $Id$
}
aa_register_case acs_messaging_format_as_html {
Test acs_messaging_format_as_html proc.
} {
aa_run_with_teardown \
-rollback \
-test_code {
# initialize random values
set name [ad_generate_random_string]
set formatted_name [acs_messaging_format_as_html text/html $name]
aa_true "Name is formatted" ![string match "$name" $formatted_name]
}
}
aa_register_case acs_messaging_message_p {
Test message_p proc.
} {
aa_run_with_teardown \
-rollback \
-test_code {
set message_p [acs_message_p "0"]
aa_true "Integer is not a message_id" !$message_p
}
}
# Local variables:
# mode: tcl
# tcl-indent-level: 4
# indent-tabs-mode: nil
# End:
acs-messaging-v5-0-2-1-0/www/ 0000775 0000000 0000000 00000000000 12630315015 0015536 5 ustar 00root root 0000000 0000000 acs-messaging-v5-0-2-1-0/www/doc/ 0000775 0000000 0000000 00000000000 12630315015 0016303 5 ustar 00root root 0000000 0000000 acs-messaging-v5-0-2-1-0/www/doc/design.adp 0000664 0000000 0000000 00000006574 12630315015 0020256 0 ustar 00root root 0000000 0000000
{/doc/acs-messaging {Messaging}} {ACS Messaging Design}
ACS Messaging Design
ACS Messaging Design
ACS Messaging was born out of the design of the new bboard. One
thing we discovered when researching requirements for bboard and
discussion software in general was that there are a variety of ways
one may wish to structure and organize threads of messages e.g. in
discrete forums with tagged categories, attached to other user
objects annotated with user ratings, etc.,. Our design addressed
this by separating the store of messages from the organizational
data model and any user interfaces.ACS Messaging is this separate
layer. Built atop the content repository, it provides the storage
and retrieval of messages. We take messages to be objects that
consist of a sender (an ACS party), a text body, an optional
reference to a parent message, optional file attachments, and some
miscellaneous auditing data.With these constraining constraining
set of semantics, we can build a library of component functionality
to operate on messages. For example: code that displays a message,
forwards a message, compiles a set of messages into a digest,
displays a specific attachment, etc., This functionality can then
be reused across messaging applications such as bboard, webmail,
and general comments. We can maintain user preferences on HTML vs.
text email, inline attachments vs. URLs across the system, and have
simple procedures that do the right thing when sending email.
Another example: if we built the IMAP server functionality 3.4
webmail provides against acs-messaging, then bboard forums, pages
of comments, and webmail folders could be viewed uniformly through
your email client. The IMAP mapping isn't quite trivial, but you
can see the idea.To reiterate, if applications are storing the same
sort of data (a text-ish messages with optional attachments and
replies), they should store them the same way. Then code from
particular applications can possibly be refactored into generic
functionality.spam/general alerts/etc isn't meant to be replaced by
ACS Messaging, at least not with what is there currently. Currently
it is just a store; but we intend it to be the canonical store for
messages that need to be stored in the database. If messages are
automatically generated from other user objects, they might need to
be queue'd up or archived in the RDBMS. If so this should be done
in the acs-messaging tables. We can implement the generic incoming
email system by stashing messages in acs-messaging, then
dispatching the message id to package specific code for
processing.Currently (11/2000), ACS Messaging is very slim; it just
supports bboard. We intend to add attachments (most likely
implemented as content repository items that are children of the
message), extensible headers (just like the webmail datamodel), and
versioning as provided by the content repository.
API
ACS Messaging provides the acs_messages_all
view as
the primary mechanism for message queries.
create or replace view acs_messages_all as
select m.message_id, m.reply_to, o.context_id, r.title, r.publish_date,
r.mime_type, r.content, o.creation_user
...
ACS Messaging provides the PL/SQL function acs_message.post to add
new messages.
akk\@arsdigita.com
acs-messaging-v5-0-2-1-0/www/doc/design.html 0000664 0000000 0000000 00000007113 12630315015 0020444 0 ustar 00root root 0000000 0000000
ACS Messaging Design
ACS Messaging Design
ACS Messaging was born out of the design of the new bboard. One
thing we discovered when researching requirements for bboard and
discussion software in general was that there are a variety of
ways one may wish to structure and organize threads of messages
e.g. in discrete forums with tagged categories, attached to other
user objects annotated with user ratings, etc.,. Our design
addressed this by separating the store of messages from the
organizational data model and any user interfaces.
ACS Messaging is this separate layer. Built atop the content
repository, it provides the storage and retrieval of messages. We
take messages to be objects that consist of a sender (an ACS
party), a text body, an optional reference to a parent message,
optional file attachments, and some miscellaneous auditing data.
With these constraining constraining set of semantics, we can
build a library of component functionality to operate on messages.
For example: code that displays a message, forwards a message,
compiles a set of messages into a digest, displays a specific
attachment, etc., This functionality can then be reused across
messaging applications such as bboard, webmail, and general
comments. We can maintain user preferences on HTML vs. text email,
inline attachments vs. URLs across the system, and have simple
procedures that do the right thing when sending email. Another
example: if we built the IMAP server functionality 3.4 webmail
provides against acs-messaging, then bboard forums, pages of
comments, and webmail folders could be viewed uniformly through
your email client. The IMAP mapping isn't quite trivial, but you
can see the idea.
To reiterate, if applications are storing the same sort of data (a
text-ish messages with optional attachments and replies), they
should store them the same way. Then code from particular
applications can possibly be refactored into generic
functionality.
spam/general alerts/etc isn't meant to be replaced by ACS
Messaging, at least not with what is there currently. Currently
it is just a store; but we intend it to be the canonical store for
messages that need to be stored in the database. If messages are
automatically generated from other user objects, they might need
to be queue'd up or archived in the RDBMS. If so this should be
done in the acs-messaging tables. We can implement the generic
incoming email system by stashing messages in acs-messaging, then
dispatching the message id to package specific code for
processing.
Currently (11/2000), ACS Messaging is very slim; it just supports
bboard. We intend to add attachments (most likely implemented as
content repository items that are children of the message),
extensible headers (just like the webmail datamodel), and
versioning as provided by the content repository.
API
ACS Messaging provides the acs_messages_all
view as the
primary mechanism for message queries.
create or replace view acs_messages_all as
select m.message_id, m.reply_to, o.context_id, r.title, r.publish_date,
r.mime_type, r.content, o.creation_user
...
ACS Messaging provides the PL/SQL function acs_message.post to
add new messages.
akk@arsdigita.com