acs-messaging-procs.tcl

Utility procs for working with messages

Location:
packages/acs-messaging/tcl/acs-messaging-procs.tcl
Created:
2000-09-01
Author:
John Prevost
CVS Identification:
$Id: acs-messaging-procs.tcl,v 1.9.2.5 2022/09/08 16:17:02 antoniop Exp $

Procedures in this file

Detailed information

acs_message_p (public)

 acs_message_p message_id

Check if an integer is a valid OpenACS message id.

Parameters:
message_id (required)

Partial Call Graph (max 5 caller/called nodes):
%3 test_acs_messaging_message_p acs_messaging_message_p (test acs-messaging) acs_message_p acs_message_p test_acs_messaging_message_p->acs_message_p db_0or1row db_0or1row (public) acs_message_p->db_0or1row ad_page_contract_filter_proc_acs_message_id ad_page_contract_filter_proc_acs_message_id (public, deprecated) ad_page_contract_filter_proc_acs_message_id->acs_message_p

Testcases:
acs_messaging_message_p

acs_messaging_first_ancestor (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).

Parameters:
message_id (required)

Partial Call Graph (max 5 caller/called nodes):
%3 db_1row db_1row (public) acs_messaging_first_ancestor acs_messaging_first_ancestor acs_messaging_first_ancestor->db_1row

Testcases:
No testcase defined.

acs_messaging_format_as_html (private)

 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"

Parameters:
mime_type (required)
MIME content-type of content
content (required)
Text to view

Partial Call Graph (max 5 caller/called nodes):
%3 test_acs_messaging_format_as_html acs_messaging_format_as_html (test acs-messaging) acs_messaging_format_as_html acs_messaging_format_as_html test_acs_messaging_format_as_html->acs_messaging_format_as_html ad_text_to_html ad_text_to_html (public) acs_messaging_format_as_html->ad_text_to_html

Testcases:
acs_messaging_format_as_html

acs_messaging_process_queue (private)

 acs_messaging_process_queue

Process the message queue, sending any reasonable messages.

Partial Call Graph (max 5 caller/called nodes):
%3 acs_mail_lite::send acs_mail_lite::send (public) db_dml db_dml (public) db_foreach db_foreach (public) acs_messaging_process_queue acs_messaging_process_queue acs_messaging_process_queue->acs_mail_lite::send acs_messaging_process_queue->db_dml acs_messaging_process_queue->db_foreach

Testcases:
No testcase defined.

acs_messaging_send_query (public)

 acs_messaging_send_query -message_id message_id -query query \
    [ -bind 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.

Switches:
-message_id (required)
-query (required)
-bind (optional)

Partial Call Graph (max 5 caller/called nodes):
%3 db_dml db_dml (public) acs_messaging_send_query acs_messaging_send_query acs_messaging_send_query->db_dml

Testcases:
No testcase defined.

acs_messaging_timezone_offset (private)

 acs_messaging_timezone_offset

Returns a best guess of the timezone offset for the machine.

Partial Call Graph (max 5 caller/called nodes):
%3

Testcases:
No testcase defined.

ad_page_contract_filter_proc_acs_message_id (public, deprecated)

 ad_page_contract_filter_proc_acs_message_id name value_varname
Deprecated. Invoking this procedure generates a warning.

Checks whether the value (assumed to be an integer) is the id of an already-existing OpenACS message. DEPRECATED: OpenACS now has a generic filter object_type.

Parameters:
name (required)
value_varname (required)
See Also:

Partial Call Graph (max 5 caller/called nodes):
%3 acs_message_p acs_message_p (public) ad_complain ad_complain (public) ad_log_deprecated ad_log_deprecated (public) ad_page_contract_filter_proc_acs_message_id ad_page_contract_filter_proc_acs_message_id ad_page_contract_filter_proc_acs_message_id->acs_message_p ad_page_contract_filter_proc_acs_message_id->ad_complain ad_page_contract_filter_proc_acs_message_id->ad_log_deprecated

Testcases:
No testcase defined.
[ hide source ] | [ make this the default ]

Content File Source

ad_library {
    Utility procs for working with messages

    @author John Prevost <jmp@arsdigita.com>
    @creation-date 2000-09-01
    @cvs-id $Id: acs-messaging-procs.tcl,v 1.9.2.5 2022/09/08 16:17:02 antoniop Exp $
}

d_proc -public acs_message_p {
    {message_id}
} {
    Check if an integer is a valid OpenACS message id.
} {
    return [db_0or1row is_message {
        select 1 from acs_messages
        where message_id = :message_id
    }]
}

ad_page_contract_filter -deprecated acs_message_id { name value } {
    Checks whether the value (assumed to be an integer) is the id
    of an already-existing OpenACS message.

    DEPRECATED: OpenACS now has a generic filter object_type.

    @see ad_page_contract_filter_proc_object_type
} {
    # 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
}

d_proc -private 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 "<pre>[ns_quotehtml $content]</pre>"
    } 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 "<i>content type undecipherable</i>"
    }
    return $result
}


d_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 {}

    return $ancestor_id
}

# apisano 2021-10-21: since its introduction 21 years ago, this proc
# has been broken. In fact, db_dml needs at least a query name to work
# properly. Furthermore, no query for Postgres is available.
# 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;
#     }
# }

d_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]]
}

d_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}]]
}

d_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: