Index: openacs-4/packages/acs-mail-lite/acs-mail-lite.info =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-mail-lite/acs-mail-lite.info,v diff -u -r1.23 -r1.24 --- openacs-4/packages/acs-mail-lite/acs-mail-lite.info 16 Nov 2006 12:48:38 -0000 1.23 +++ openacs-4/packages/acs-mail-lite/acs-mail-lite.info 17 Nov 2006 15:14:56 -0000 1.24 @@ -7,7 +7,7 @@ f t - + Eric Lorenzo Timo Hentschel @@ -16,7 +16,7 @@ This package provides a simple ns_sendmail-like interface for sending messages, but queues messages in the database to ensure reliable sending and make sending a message 'transactional'. Prefered over acs-messaging or acs-mail. 0 - + Index: openacs-4/packages/acs-mail-lite/sql/postgresql/upgrade/upgrade-1.3b7-1.3b8.sql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-mail-lite/sql/postgresql/upgrade/Attic/upgrade-1.3b7-1.3b8.sql,v diff -u --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ openacs-4/packages/acs-mail-lite/sql/postgresql/upgrade/upgrade-1.3b7-1.3b8.sql 17 Nov 2006 15:14:57 -0000 1.1 @@ -0,0 +1,38 @@ +-- 2006/11/17 cognovis/nfl +-- +-- Name: acs_mail_lite_complex_queue; Type: TABLE; Schema: public; Owner: cognovis; Tablespace: +-- + +CREATE TABLE acs_mail_lite_complex_queue ( + id serial PRIMARY KEY, + creation_date text, + locking_server text, + to_party_ids text, + cc_party_ids text, + bcc_party_ids text, + to_group_ids text, + cc_group_ids text, + bcc_group_ids text, + to_addr text, + cc_addr text, + bcc_addr text, + from_addr text, + subject text, + body text, + package_id integer, + files text, + file_ids text, + folder_ids text, + mime_type text, + object_id integer, + single_email_p boolean, + no_callback_p boolean, + extraheaders text, + alternative_part_p boolean, + use_sender_p boolean +); + +-- +-- PostgreSQL database statements - end of file +-- + Index: openacs-4/packages/acs-mail-lite/tcl/acs-mail-lite-init.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-mail-lite/tcl/acs-mail-lite-init.tcl,v diff -u -r1.7 -r1.8 --- openacs-4/packages/acs-mail-lite/tcl/acs-mail-lite-init.tcl 9 Aug 2006 13:45:07 -0000 1.7 +++ openacs-4/packages/acs-mail-lite/tcl/acs-mail-lite-init.tcl 17 Nov 2006 15:14:57 -0000 1.8 @@ -10,6 +10,8 @@ # Default interval is 1 minute. ad_schedule_proc -thread t 60 acs_mail_lite::sweeper +# Run the complex_sweeper every 180s (3min) +ad_schedule_proc -thread t 180 acs_mail_lite::complex_sweeper set queue_dir [parameter::get_from_package_key -parameter "BounceMailDir" -package_key "acs-mail-lite"] Index: openacs-4/packages/acs-mail-lite/tcl/acs-mail-lite-procs-postgresql.xql =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-mail-lite/tcl/acs-mail-lite-procs-postgresql.xql,v diff -u -r1.6 -r1.7 --- openacs-4/packages/acs-mail-lite/tcl/acs-mail-lite-procs-postgresql.xql 4 Jan 2006 09:50:19 -0000 1.6 +++ openacs-4/packages/acs-mail-lite/tcl/acs-mail-lite-procs-postgresql.xql 17 Nov 2006 15:14:57 -0000 1.7 @@ -114,5 +114,120 @@ + + + insert into acs_mail_lite_complex_queue + (creation_date, + locking_server, + to_party_ids, + cc_party_ids, + bcc_party_ids, + to_group_ids, + cc_group_ids, + bcc_group_ids, + to_addr, + cc_addr, + bcc_addr, + from_addr, + subject, + body, + package_id, + files, + file_ids, + folder_ids, + mime_type, + object_id, + single_email_p, + no_callback_p, + extraheaders, + alternative_part_p, + use_sender_p + ) + values + (:creation_date, + :locking_server, + :to_party_ids, + :cc_party_ids, + :bcc_party_ids, + :to_group_ids, + :cc_group_ids, + :bcc_group_ids, + :to_addr, + :cc_addr, + :bcc_addr, + :from_addr, + :subject, + :body, + :package_id, + :files, + :file_ids, + :folder_ids, + :mime_type, + :object_id, + (case when :single_email_p = '1' then TRUE else FALSE end), + (case when :no_callback_p = '1' then TRUE else FALSE end), + :extraheaders, + (case when :alternative_part_p = '1' then TRUE else FALSE end), + (case when :use_sender_p = '1' then TRUE else FALSE end) + ) + + + + + select + id, + creation_date, + locking_server, + to_party_ids, + cc_party_ids, + bcc_party_ids, + to_group_ids, + cc_group_ids, + bcc_group_ids, + to_addr, + cc_addr, + bcc_addr, + from_addr, + subject, + body, + package_id, + files, + file_ids, + folder_ids, + mime_type, + object_id, + (case when single_email_p = TRUE then 1 else 0 end) as single_email_p, + (case when no_callback_p = TRUE then 1 else 0 end) as no_callback_p, + extraheaders, + (case when alternative_part_p = TRUE then 1 else 0 end) as alternative_part_p, + (case when use_sender_p = TRUE then 1 else 0 end) as use_sender_p + from acs_mail_lite_complex_queue + where locking_server = '' or locking_server is NULL + + + + + + select id + from acs_mail_lite_complex_queue + where id=:id and (locking_server = '' or locking_server is NULL) + + + + + + update acs_mail_lite_complex_queue + set locking_server = :locking_server + where id=:id + + + + + + delete from acs_mail_lite_complex_queue + where id=:id + + + Index: openacs-4/packages/acs-mail-lite/tcl/acs-mail-lite-procs.tcl =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-mail-lite/tcl/acs-mail-lite-procs.tcl,v diff -u -r1.56 -r1.57 --- openacs-4/packages/acs-mail-lite/tcl/acs-mail-lite-procs.tcl 19 Oct 2006 07:18:35 -0000 1.56 +++ openacs-4/packages/acs-mail-lite/tcl/acs-mail-lite-procs.tcl 17 Nov 2006 15:14:57 -0000 1.57 @@ -13,6 +13,7 @@ package require base64 2.3.1 namespace eval acs_mail_lite { + #--------------------------------------- ad_proc -public with_finally { -code:required -finally:required @@ -66,12 +67,14 @@ } } + #--------------------------------------- ad_proc -public get_package_id {} { @returns package_id of this package } { return [apm_package_id_from_key acs-mail-lite] } + #--------------------------------------- ad_proc -public get_parameter { -name:required {-default ""} @@ -84,6 +87,7 @@ return [parameter::get -package_id [get_package_id] -parameter $name -default $default] } + #--------------------------------------- ad_proc -public address_domain {} { @returns domain address to which bounces are directed to } { @@ -94,24 +98,28 @@ return $domain } + #--------------------------------------- ad_proc -private bounce_sendmail {} { @returns path to the sendmail executable } { return [get_parameter -name "SendmailBin"] } + #--------------------------------------- ad_proc -private bounce_prefix {} { @returns bounce prefix for x-envelope-from } { return [get_parameter -name "EnvelopePrefix"] } + #--------------------------------------- ad_proc -private mail_dir {} { @returns incoming mail directory to be scanned for bounces } { return [get_parameter -name "BounceMailDir"] } + #--------------------------------------- ad_proc -public parse_email_address { -email:required } { @@ -126,6 +134,7 @@ } } + #--------------------------------------- ad_proc -public bouncing_email_p { -email:required } { @@ -136,6 +145,7 @@ return [db_string bouncing_p {} -default 0] } + #--------------------------------------- ad_proc -public bouncing_user_p { -user_id:required } { @@ -146,6 +156,7 @@ return [db_string bouncing_p {} -default 0] } + #--------------------------------------- ad_proc -private log_mail_sending { -user_id:required } { @@ -158,6 +169,7 @@ } } + #--------------------------------------- ad_proc -public bounce_address { -user_id:required -package_id:required @@ -173,6 +185,7 @@ return "[bounce_prefix]-$user_id-[ns_sha1 $message_id]-$package_id@[address_domain]" } + #--------------------------------------- ad_proc -public parse_bounce_address { -bounce_address:required } { @@ -189,6 +202,7 @@ return [list $user_id $package_id $signature] } + #--------------------------------------- ad_proc -public generate_message_id { } { Generate an id suitable as a Message-Id: header for an email. @@ -200,6 +214,7 @@ return "<[clock clicks].[ns_time].oacs@[address_domain]>" } + #--------------------------------------- ad_proc -public valid_signature { -signature:required -message_id:required @@ -216,6 +231,7 @@ return 1 } + #--------------------------------------- ad_proc -private load_mails { -queue_dir:required } { @@ -322,6 +338,7 @@ } } + #--------------------------------------- ad_proc parse_email { -file:required -array:required @@ -453,6 +470,7 @@ mime::finalize $mime -subordinates all } + #--------------------------------------- ad_proc -private -deprecated load_mail_dir { -queue_dir:required } { @@ -575,6 +593,7 @@ } } + #--------------------------------------- ad_proc -public scan_replies {} { Scheduled procedure that will scan for bounced mails } { @@ -592,6 +611,7 @@ } } + #--------------------------------------- ad_proc -private check_bounces { } { Daily proc that sends out warning mail that emails are bouncing and disables emails if necessary @@ -638,6 +658,7 @@ } } + #--------------------------------------- ad_proc -public deliver_mail { -to_addr:required -from_addr:required @@ -723,6 +744,7 @@ } } + #--------------------------------------- ad_proc -private sendmail { -from_addr:required -sendlist:required @@ -779,6 +801,7 @@ } } + #--------------------------------------- ad_proc -private smtp { -from_addr:required -sendlist:required @@ -859,6 +882,7 @@ } } + #--------------------------------------- ad_proc -private get_address_array { -addresses:required } { Checks if passed variable is already an array of emails, @@ -904,6 +928,7 @@ return [array get address_array] } + #--------------------------------------- ad_proc -public send { -send_immediately:boolean -valid_email:boolean @@ -1000,10 +1025,14 @@ } + #--------------------------------------- # complex_send # created ... by ... # modified 2006/07/25 by nfl: new param. alternative_part_p - # and creation of multipart/alternative + # and creation of multipart/alternative + # 2006/../.. new created as an frontend to the old complex_send that now is called complex_send_immediatly + # 2006/11/17 modified (nfl) + #--------------------------------------- ad_proc -public complex_send { -send_immediately:boolean -valid_email:boolean @@ -1128,14 +1157,19 @@ -use_sender_p $use_sender_p } else { # else, store it in the db and let the sweeper deliver the mail - db_dml create_queue_entry {} + set creation_date [clock format [clock seconds] -format "%Y.%m.%d %H:%M:%S"] + set locking_server "" + db_dml create_complex_queue_entry {} } } + #--------------------------------------- # complex_send # created ... by ... # modified 2006/07/25 by nfl: new param. alternative_part_p # and creation of multipart/alternative + # 2006/../.. Renamed to complex_send_immediately + #--------------------------------------- ad_proc -public complex_send_immediately { -valid_email:boolean {-to_party_ids ""} @@ -1653,7 +1687,76 @@ } } } - + + #--------------------------------------- + # 2006/11/17 Created by cognovis/nfl + # nsv_incr description: http://www.panoptic.com/wiki/aolserver/Nsv_incr + #--------------------------------------- + ad_proc -private complex_sweeper {} { + Send messages in the acs_mail_lite_complex_queue table. + } { + # Make sure that only one thread is processing the queue at a time. + if {[nsv_incr acs_mail_lite complex_send_mails_p] > 1} { + nsv_incr acs_mail_lite complex_send_mails_p -1 + return + } + + with_finally -code { + db_foreach get_complex_queued_messages {} { + # check if record is already there and free to use + set return_id [db_string get_complex_queued_message {} -default -1] + if {$return_id == $id} { + # lock this record for exclusive use + set locking_server [ad_conn user_id] + append locking_server ":" + append locking_server [ad_conn session_id] + append locking_server ":" + append locking_server [ad_conn url] + db_dml lock_queued_message {} + # send the mail + set err [catch { + acs_mail_lite::complex_send_immediately \ + -to_party_ids $to_party_ids \ + -cc_party_ids $cc_party_ids \ + -bcc_party_ids $bcc_party_ids \ + -to_group_ids $to_group_ids \ + -cc_group_ids $cc_group_ids \ + -bcc_group_ids $bcc_group_ids \ + -to_addr $to_addr \ + -cc_addr $cc_addr \ + -bcc_addr $bcc_addr \ + -from_addr $from_addr \ + -subject $subject \ + -body $body \ + -package_id $package_id \ + -files $files \ + -file_ids $file_ids \ + -folder_ids $folder_ids \ + -mime_type $mime_type \ + -object_id $object_id \ + -single_email_p $single_email_p \ + -no_callback_p $no_callback_p \ + -extraheaders $extraheaders \ + -alternative_part_p $alternative_part_p \ + -use_sender_p $use_sender_p + } errMsg] + if $err { + # release the lock + set locking_server "" + db_dml lock_queued_message {} + } else { + # mail was sent, delete the queue entry + db_dml delete_complex_queue_entry {} + } + } + } + } -finally { + nsv_incr acs_mail_lite complex_send_mails_p -1 + } + } + + + #--------------------------------------- ad_proc -private sweeper {} { Send messages in the acs_mail_lite_queue table. } { @@ -1680,6 +1783,7 @@ } } + #--------------------------------------- ad_proc -private send_immediately { -to_addr:required -from_addr:required @@ -1712,6 +1816,7 @@ } } + #--------------------------------------- ad_proc -private after_install {} { Callback to be called after package installation. Adds the service contract package-specific bounce management. @@ -1722,6 +1827,7 @@ acs_sc::contract::operation::new -contract_name AcsMailLite -operation MailBounce -input "header:string body:string" -output "" -description "Callback to handle bouncing mails" } + #--------------------------------------- ad_proc -private before_uninstall {} { Callback to be called before package uninstallation. Removes the service contract for package-specific bounce management. @@ -1732,6 +1838,7 @@ acs_sc::contract::delete -name AcsMailLite } + #--------------------------------------- ad_proc -private message_interpolate { {-values:required} {-text:required} @@ -1750,4 +1857,6 @@ return $text } + #--------------------------------------- + }