--- loncom/interface/lonmsg.pm 2007/04/22 02:25:36 1.199 +++ loncom/interface/lonmsg.pm 2008/06/06 05:24:28 1.212 @@ -1,7 +1,7 @@ # The LearningOnline Network with CAPA # Routines for messaging # -# $Id: lonmsg.pm,v 1.199 2007/04/22 02:25:36 raeburn Exp $ +# $Id: lonmsg.pm,v 1.212 2008/06/06 05:24:28 raeburn Exp $ # # Copyright Michigan State University Board of Trustees # @@ -78,7 +78,7 @@ use LONCAPA qw(:DEFAULT :match); sub packagemsg { my ($subject,$message,$citation,$baseurl,$attachmenturl, - $recuser,$recdomain,$msgid,$type,$crsmsgid,$symb,$error)=@_; + $recuser,$recdomain,$msgid,$type,$crsmsgid,$symb,$error,$recipid)=@_; $message =&HTML::Entities::encode($message,'<>&"'); $citation=&HTML::Entities::encode($citation,'<>&"'); $subject =&HTML::Entities::encode($subject,'<>&"'); @@ -88,23 +88,7 @@ sub packagemsg { #remove machine specification $attachmenturl =~ s|^http://[^/]+/|/|; $attachmenturl =&HTML::Entities::encode($attachmenturl,'<>&"'); - my $course_context; - if (defined($env{'form.replyid'})) { - my ($sendtime,$shortsubj,$fromname,$fromdomain,$count,$origcid)= - split(/\:/,&unescape($env{'form.replyid'})); - $course_context = $origcid; - } - foreach my $key (keys(%env)) { - if ($key=~/^form\.(rep)?rec\_(.*)$/) { - my ($sendtime,$shortsubj,$fromname,$fromdomain,$count,$origcid) = - split(/\:/,&unescape($2)); - $course_context = $origcid; - last; - } - } - unless(defined($course_context)) { - $course_context = $env{'request.course.id'}; - } + my $course_context = &get_course_context(); my $now=time; my $msgcount = &get_uniq(); unless(defined($msgid)) { @@ -167,7 +151,7 @@ sub packagemsg { } if (defined($symb)) { $result.= ''.$symb.''; - if (defined($course_context)) { + if ($course_context ne '') { if ($course_context eq $env{'request.course.id'}) { my $resource_title = &Apache::lonnet::gettitle($symb); if (defined($resource_title)) { @@ -176,13 +160,56 @@ sub packagemsg { } } } + if (defined($recipid)) { + $result.= ''.$recipid.''; + } + if ($env{'form.can_reply'} eq 'N') { + $result .= '1'; + } + if ($env{'form.reply_to_addr'}) { + my ($replytoname,$replytodom) = split(/:/,$env{'form.reply_to_addr'}); + if (!($replytoname eq $env{'user.name'} && $replytodom eq $env{'user.domain'})) { + if (&Apache::lonnet::homeserver($replytoname,$replytodom) ne 'no_host') { + $result .= ''.$env{'form.reply_to_addr'}.''; + } + } + } return ($msgid,$result); } +sub get_course_context { + my $course_context; + my $msgkey; + if (defined($env{'form.replyid'})) { + $msgkey = $env{'form.replyid'}; + } elsif (defined($env{'form.forwid'})) { + $msgkey = $env{'form.forwid'} + } elsif (defined($env{'form.multiforwid'})) { + $msgkey = $env{'form.multiforwid'}; + } + if ($msgkey ne '') { + my ($sendtime,$shortsubj,$fromname,$fromdomain,$count,$origcid)= + split(/\:/,&unescape($msgkey)); + $course_context = $origcid; + } + foreach my $key (keys(%env)) { + if ($key=~/^form\.(rep)?rec\_(.*)$/) { + my ($sendtime,$shortsubj,$fromname,$fromdomain,$count,$origcid) = + split(/\:/,&unescape($2)); + $course_context = $origcid; + last; + } + } + if ($course_context eq '') { + $course_context = $env{'request.course.id'}; + } + return $course_context; +} + # ================================================== Unpack message into a hash sub unpackagemsg { - my ($message,$notoken)=@_; + my ($message,$notoken,$noattachmentlink)=@_; my %content=(); my $parser=HTML::TokeParser->new(\$message); my $token; @@ -202,7 +229,7 @@ sub unpackagemsg { } } if (!exists($content{'recuser'})) { $content{'recuser'} = []; } - if ($content{'attachmenturl'}) { + if (($content{'attachmenturl'}) && (!$noattachmentlink)) { my ($fname)=($content{'attachmenturl'}=~m|/([^/]+)$|); if ($notoken) { $content{'message'}.='

'.&mt('Attachment').': '.$fname.''; @@ -280,18 +307,18 @@ sub sendnotification { my ($to,$touname,$toudom,$subj,$crit,$text,$msgid)=@_; my $sender=$env{'environment.firstname'}.' '.$env{'environment.lastname'}; unless ($sender=~/\w/) { - $sender=$env{'user.name'}.'@'.$env{'user.domain'}; + $sender=$env{'user.name'}.':'.$env{'user.domain'}; } my $critical=($crit?' critical':''); + $text=~s/\<\;/\/gs; - $text=~s/\<\/*[^\>]+\>//gs; my $url='http://'. &Apache::lonnet::hostname(&Apache::lonnet::homeserver($touname,$toudom)). '/adm/email?username='.$touname.'&domain='.$toudom; my ($sendtime,$shortsubj,$fromname,$fromdomain,$status,$fromcid, $symb,$error) = &Apache::lonmsg::unpackmsgid($msgid); - my $coursetext; + my ($coursetext,$body,$bodybegin,$bodysubj,$bodyend); if ($fromcid ne '') { $coursetext = "\n".&mt('Course').': '; if ($env{'course.'.$fromcid.'.description'} ne '') { @@ -304,14 +331,17 @@ sub sendnotification { } $coursetext .= "\n\n"; } - my $body = $coursetext. - &mt('You received a'.$critical.' message from [_1] in LON-CAPA.',$sender).' '.&mt('The subject is + my @recipients = split(/,/,$to); + $bodybegin = $coursetext. + &mt('You received a'.$critical.' message from [_1] in LON-CAPA.',$sender).' '; + $bodysubj = &mt('The subject is [_1] ',$subj)."\n". '=== '.&mt('Excerpt')." ============================================================ -$text +"; + $bodyend = " ======================================================================== ".&mt('Use @@ -319,14 +349,51 @@ $text [_1] to access the full message.',$url); - &sendemail($to,'New'.$critical.' message from '.$sender,$body); + my %userenv = &Apache::lonnet::get('environment',['notifywithhtml'],$toudom,$touname); + my $subject = &mt("'New' $critical message from ").$sender; + + my ($blocked,$blocktext); + if (!$crit) { + my %setters; + my ($startblock,$endblock) = + &Apache::loncommon::blockcheck(\%setters,'com',$touname,$toudom); + if ($startblock && $endblock) { + $blocked = 1; + my $showstart = &Apache::lonlocal::locallocaltime($startblock); + my $showend = &Apache::lonlocal::locallocaltime($endblock); + $blocktext = &mt('LON-CAPA messages sent to you between [_1] and [_2] will be inaccessible until the end of this time period, because you are a student in a course with an active communications block.',$showstart,$showend); + } + } + if ($userenv{'notifywithhtml'} ne '') { + my @htmlexcerpt = split(/,/,$userenv{'notifywithhtml'}); + foreach my $addr (@recipients) { + if ($blocked) { + $body = $bodybegin."\n".$blocktext."\n".$bodyend; + } else { + my $sendtext = $text; + if (!grep/^\Q$addr\E/,@htmlexcerpt) { + $sendtext =~ s/\<\/*[^\>]+\>//gs; + } + $body = $bodybegin.$bodysubj.$sendtext.$bodyend; + } + &sendemail($addr,$subject,$body); + } + } else { + if ($blocked) { + $body = $bodybegin."\n".$blocktext."\n".$bodyend; + } else { + $text =~ s/\<\/*[^\>]+\>//gs; + $body = $bodybegin.$bodysubj.$text.$bodyend; + } + &sendemail($to,$subject,$body); + } } # ============================================================= Check for email sub newmail { if ((time-$env{'user.mailcheck.time'})>300) { my %what=&Apache::lonnet::get('email_status',['recnewemail']); - &Apache::lonnet::appenv('user.mailcheck.time'=>time); + &Apache::lonnet::appenv({'user.mailcheck.time'=>time}); if ($what{'recnewemail'}>0) { return 1; } } return 0; @@ -430,13 +497,17 @@ sub store_instructor_comment { my $cdom = $env{'course.'.$cid.'.domain'}; my $subject= &mt('Record').' ['.$uname.':'.$udom.']'; my $result = &user_normal_msg_raw($cnum,$cdom,$subject,$msg); + if ($result eq 'ok' || $result eq 'con_delayed') { + + } return $result; } # ================================================== Critical message to a user sub user_crit_msg_raw { - my ($user,$domain,$subject,$message,$sendback,$toperm,$sentmessage)=@_; + my ($user,$domain,$subject,$message,$sendback,$toperm,$sentmessage, + $nosentstore,$recipid,$attachmenturl)=@_; # Check if allowed missing my ($status,$packed_message); my $msgid='undefined'; @@ -444,19 +515,19 @@ sub user_crit_msg_raw { my $text=$message; my $homeserver=&Apache::lonnet::homeserver($user,$domain); if ($homeserver ne 'no_host') { - ($msgid,$packed_message)=&packagemsg($subject,$message); + ($msgid,$packed_message)=&packagemsg($subject,$message,undef,undef, + $attachmenturl,undef,undef,undef,undef,undef, + undef,undef,$recipid); if ($sendback) { $packed_message.='true'; } - $status=&Apache::lonnet::critical( - 'put:'.$domain.':'.$user.':critical:'. - &escape($msgid).'='. - &escape($packed_message),$homeserver); + $status=&Apache::lonnet::cput('critical', {$msgid => $packed_message}, + $domain,$user); if (defined($sentmessage)) { $$sentmessage = $packed_message; } - if ($env{'request.course.id'} eq '') { + if (!$nosentstore) { (undef,my $packed_message_no_citation) = - &packagemsg($subject,$message,undef,undef,undef,$user,$domain, - $msgid); + &packagemsg($subject,$message,undef,undef,$attachmenturl,$user, + $domain,$msgid); if ($status eq 'ok' || $status eq 'con_delayed') { &store_sent_mail($msgid,$packed_message_no_citation); } @@ -490,9 +561,10 @@ sub user_crit_msg_raw { =pod -=item * B: Sends - a critical message $message to the $user at $domain. If $sendback is true, - a reciept will be sent to the current user when $user recieves the message. +=item * B: + Sends a critical message $message to the $user at $domain. If $sendback + is true, a receipt will be sent to the current user when $user receives + the message. Additionally it will check if the user has a Forwarding address set, and send the message to that address instead @@ -505,7 +577,8 @@ sub user_crit_msg_raw { =cut sub user_crit_msg { - my ($user,$domain,$subject,$message,$sendback,$toperm,$sentmessage)=@_; + my ($user,$domain,$subject,$message,$sendback,$toperm,$sentmessage, + $nosentstore,$recipid,$attachmenturl)=@_; my @status; my %userenv = &Apache::lonnet::get('environment',['msgforward'], $domain,$user); @@ -515,12 +588,14 @@ sub user_crit_msg { my ($forwuser,$forwdomain)=split(/\:/,$addr); push(@status, &user_crit_msg_raw($forwuser,$forwdomain,$subject,$message, - $sendback,$toperm,$sentmessage)); + $sendback,$toperm,$sentmessage,$nosentstore, + $recipid,$attachmenturl)); } } else { push(@status, &user_crit_msg_raw($user,$domain,$subject,$message,$sendback, - $toperm,$sentmessage)); + $toperm,$sentmessage,$nosentstore,$recipid, + $attachmenturl)); } if (wantarray) { return @status; @@ -534,14 +609,24 @@ sub user_crit_received { my $msgid=shift; my %message=&Apache::lonnet::get('critical',[$msgid]); my %contents=&unpackagemsg($message{$msgid},1); + my $destname = $contents{'sendername'}; + my $destdom = $contents{'senderdomain'}; + if ($contents{'replytoaddr'}) { + my ($repname,$repdom) = split(/:/,$contents{'replytoaddr'}); + if (&Apache::lonnet::homeserver($repname,$repdom) ne 'no_host') { + $destname = $repname; + $destdom = $repdom; + } + } my $status='rec: '.($contents{'sendback'}? - &user_normal_msg($contents{'sendername'},$contents{'senderdomain'}, - &mt('Receipt').': '.$env{'user.name'}.' '.&mt('at').' '.$env{'user.domain'}.', '.$contents{'subject'}, - &mt('User').' '.$env{'user.name'}.' '.&mt('at').' '.$env{'user.domain'}. - ' acknowledged receipt of message'."\n".' "'. - $contents{'subject'}.'"'."\n".&mt('dated').' '. - $contents{'time'}.".\n" - ):'no msg req'); + &user_normal_msg($destname,$destdom,&mt('Receipt').': '.$env{'user.name'}. + ' '.&mt('at').' '.$env{'user.domain'}.', '. + $contents{'subject'},&mt('User').' '.$env{'user.name'}. + ' '.&mt('at').' '.$env{'user.domain'}. + ' acknowledged receipt of message'."\n".' "'. + $contents{'subject'}.'"'."\n".&mt('dated').' '. + $contents{'time'}.".\n" + ):'no msg req'); $status.=' trans: '. &Apache::lonnet::put( 'nohist_email',{$contents{'msgid'} => $message{$msgid}}); @@ -559,7 +644,7 @@ sub user_crit_received { sub user_normal_msg_raw { my ($user,$domain,$subject,$message,$citation,$baseurl,$attachmenturl, $toperm,$currid,$newid,$sentmessage,$crsmsgid,$symb,$restitle, - $error)=@_; + $error,$nosentstore,$recipid)=@_; # Check if allowed missing my ($status,$packed_message); my $msgid='undefined'; @@ -570,23 +655,17 @@ sub user_normal_msg_raw { ($msgid,$packed_message)= &packagemsg($subject,$message,$citation,$baseurl, $attachmenturl,$user,$domain,$currid, - undef,$crsmsgid,$symb,$error); + undef,$crsmsgid,$symb,$error,$recipid); # Store in user folder - $status=&Apache::lonnet::critical( - 'put:'.$domain.':'.$user.':nohist_email:'. - &escape($msgid).'='. - &escape($packed_message),$homeserver); + $status= + &Apache::lonnet::cput('nohist_email',{$msgid => $packed_message}, + $domain,$user); # Save new message received time &Apache::lonnet::put ('email_status',{'recnewemail'=>time},$domain,$user); -# Into sent-mail folder unless a broadcast message or critical message - unless (($env{'request.course.id'}) && - (($env{'form.sendmode'} eq 'group') || - (($env{'form.critmsg'}) || ($env{'form.sendbck'})) && - (&Apache::lonnet::allowed('srm',$env{'request.course.id'}) - || &Apache::lonnet::allowed('srm',$env{'request.course.id'}. - '/'.$env{'request.course.sec'})))) { +# Into sent-mail folder if sent mail storage required + if (!$nosentstore) { (undef,my $packed_message_no_citation) = &packagemsg($subject,$message,undef,$baseurl,$attachmenturl, $user,$domain,$currid,undef,$crsmsgid,$symb,$error); @@ -594,16 +673,14 @@ sub user_normal_msg_raw { &store_sent_mail($msgid,$packed_message_no_citation); } } - if (defined($newid)) { + if (ref($newid) eq 'SCALAR') { $$newid = $msgid; } - if (defined($sentmessage)) { + if (ref($sentmessage) eq 'SCALAR') { $$sentmessage = $packed_message; } # Notifications - my %userenv = &Apache::lonnet::get('environment',['notification', - 'permanentemail'], - $domain,$user); + my %userenv = &Apache::loncommon::getemails($user,$domain); if ($userenv{'notification'}) { &sendnotification($userenv{'notification'},$user,$domain,$subject,0, $text,$msgid); @@ -626,7 +703,8 @@ sub user_normal_msg_raw { =pod =item * B: + $baseurl, $attachmenturl, $toperm, $sentmessage, $symb, $restitle, + $error,$nosentstore,$recipid)>: Sends a message to the $user at $domain, with subject $subject and message $message. Additionally it will check if the user has a Forwarding address @@ -641,7 +719,7 @@ sub user_normal_msg_raw { sub user_normal_msg { my ($user,$domain,$subject,$message,$citation,$baseurl,$attachmenturl, - $toperm,$sentmessage,$symb,$restitle,$error)=@_; + $toperm,$sentmessage,$symb,$restitle,$error,$nosentstore,$recipid)=@_; my @status; my %userenv = &Apache::lonnet::get('environment',['msgforward'], $domain,$user); @@ -652,12 +730,14 @@ sub user_normal_msg { push(@status, &user_normal_msg_raw($forwuser,$forwdomain,$subject,$message, $citation,$baseurl,$attachmenturl,$toperm, - undef,undef,$sentmessage,undef,$symb,$restitle,$error)); + undef,undef,$sentmessage,undef,$symb, + $restitle,$error,$nosentstore,$recipid)); } } else { push(@status,&user_normal_msg_raw($user,$domain,$subject,$message, $citation,$baseurl,$attachmenturl,$toperm, - undef,undef,$sentmessage,undef,$symb,$restitle,$error)); + undef,undef,$sentmessage,undef,$symb, + $restitle,$error,$nosentstore,$recipid)); } if (wantarray) { return @status; @@ -665,16 +745,61 @@ sub user_normal_msg { return join(' ',@status); } +sub process_sent_mail { + my ($msgsubj,$subj_prefix,$numsent,$stamp,$msgname,$msgdom,$msgcount,$context,$pid,$savemsg,$recusers,$recudoms,$baseurl,$attachmenturl,$symb,$error,$senderuname,$senderdom) = @_; + my $sentsubj; + if ($numsent > 1) { + $sentsubj = $subj_prefix.' ('.$numsent.' sent) '.$msgsubj; + } else { + if ($subj_prefix) { + $sentsubj = $subj_prefix.' '; + } + $sentsubj .= $msgsubj; + } + $sentsubj = &HTML::Entities::encode($sentsubj,'<>&"'); + my $sentmsgid = + &buildmsgid($stamp,$sentsubj,$msgname,$msgdom,$msgcount,$context,$pid); + (undef,my $sentmessage) = + &packagemsg($msgsubj,$savemsg,undef,$baseurl,$attachmenturl,$recusers, + $recudoms,$sentmsgid,undef,undef,$symb,$error); + my $status = &store_sent_mail($sentmsgid,$sentmessage,$senderuname, + $senderdom); + return $status; +} + sub store_sent_mail { - my ($msgid,$message) = @_; - my $status =' '.&Apache::lonnet::critical( - 'put:'.$env{'user.domain'}.':'.$env{'user.name'}. - ':nohist_email_sent:'. - &escape($msgid).'='. - &escape($message),$env{'user.home'}); + my ($msgid,$message,$senderuname,$senderdom) = @_; + if ($senderuname eq '') { + $senderuname = $env{'user.name'}; + } + if ($senderdom eq '') { + $senderdom = $env{'user.domain'}; + } + my $status =' '.&Apache::lonnet::cput('nohist_email_sent', + {$msgid => $message}, + $senderdom,$senderuname); return $status; } +sub store_recipients { + my ($subject,$sendername,$senderdom,$reciphash) = @_; + my $context = &get_course_context(); + my $now = time(); + my $msgcount = &get_uniq(); + my $recipid = + &buildmsgid($now,$subject,$sendername,$senderdom,$msgcount,$context,$$); + my %recipinfo = ( + $recipid => $reciphash, + ); + my $status = &Apache::lonnet::put('nohist_emailrecip',\%recipinfo, + $senderdom,$sendername); + if ($status eq 'ok') { + return ($recipid,$status); + } else { + return (undef,$status); + } +} + # =============================================================== Folder suffix sub foldersuffix {