--- loncom/interface/lonmsg.pm	2005/12/05 22:16:52	1.161
+++ loncom/interface/lonmsg.pm	2006/01/05 20:10:54	1.169
@@ -1,7 +1,7 @@
 # The LearningOnline Network with CAPA
 # Routines for messaging
 #
-# $Id: lonmsg.pm,v 1.161 2005/12/05 22:16:52 albertel Exp $
+# $Id: lonmsg.pm,v 1.169 2006/01/05 20:10:54 albertel Exp $
 #
 # Copyright Michigan State University Board of Trustees
 #
@@ -97,6 +97,17 @@ Right now, this document will cover just
 it is likely you will not need to programmatically read messages,
 since lonmsg already implements that functionality.
 
+The routines used to package messages and unpackage messages are not
+only used by lonmsg when creating/extracting messages for LON-CAPA's
+internal messaging system, but also by lonnotify.pm which is available
+for use by Domain Coordinators to broadcast standard e-mail to specified
+users in their domain.  The XML packaging used in the two cases is very
+similar.  The differences are the use of <recuser>$uname</recuser> and 
+<recdomain>$udom</recdomain> in stored internal messages, compared 
+with <recipient username="$uname:$udom">$email</recipient> in stored
+Domain Coordinator e-mail for the storage of information about 
+recipients of the message/e-mail.
+
 =head1 FUNCTIONS
 
 =over 4
@@ -126,7 +137,7 @@ my $interdis;
 
 sub packagemsg {
     my ($subject,$message,$citation,$baseurl,$attachmenturl,
-	$recuser,$recdomain,$msgid)=@_;
+	$recuser,$recdomain,$msgid,$type)=@_;
     $message =&HTML::Entities::encode($message,'<>&"');
     $citation=&HTML::Entities::encode($citation,'<>&"');
     $subject =&HTML::Entities::encode($subject,'<>&"');
@@ -178,8 +189,18 @@ sub packagemsg {
            '<msgid>'.$msgid.'</msgid>';
     if (ref($recuser) eq 'ARRAY') {
         for (my $i=0; $i<@{$recuser}; $i++) {
-            $result .= '<recuser>'.$$recuser[$i].'</recuser>'.
-                       '<recdomain>'.$$recdomain[$i].'</recdomain>';
+            if ($type eq 'dcmail') {
+                my ($username,$email) = split(/:/,$$recuser[$i]);
+                $username = &Apache::lonnet::unescape($username);
+                $email = &Apache::lonnet::unescape($email);
+                $username = &HTML::Entities::encode($username,'<>&"');
+                $email = &HTML::Entities::encode($email,'<>&"');
+                $result .= '<recipient username="'.$username.'">'.
+                                            $email.'</recipient>';
+            } else {
+                $result .= '<recuser>'.$$recuser[$i].'</recuser>'.
+                           '<recdomain>'.$$recdomain[$i].'</recdomain>';
+            }
         }
     } else {
         $result .= '<recuser>'.$recuser.'</recuser>'.
@@ -211,11 +232,16 @@ sub unpackagemsg {
            my $value=$parser->get_text('/'.$entry);
            if (($entry eq 'recuser') || ($entry eq 'recdomain')) {
                push(@{$content{$entry}},$value);
+           } elsif ($entry eq 'recipient') {
+               my $username = $token->[2]{'username'};
+               $username = &HTML::Entities::decode($username,'<>&"');
+               $content{$entry}{$username} = $value;
            } else {
                $content{$entry}=$value;
            }
        }
     }
+    if (!exists($content{'recuser'})) { $content{'recuser'} = []; }
     if ($content{'attachmenturl'}) {
        my ($fname)=($content{'attachmenturl'}=~m|/([^/]+)$|);
        if ($notoken) {
@@ -241,14 +267,22 @@ sub buildmsgid {
 }
 
 sub unpackmsgid {
-    my ($msgid,$folder)=@_;
+    my ($msgid,$folder,$skipstatus,$status_cache)=@_;
     $msgid=&Apache::lonnet::unescape($msgid);
-    my $suffix=&foldersuffix($folder);
-    my ($sendtime,$shortsubj,$fromname,$fromdomain,$count,$fromcid)=split(/\:/,
-                          &Apache::lonnet::unescape($msgid));
-    my %status=&Apache::lonnet::get('email_status'.$suffix,[$msgid]);
-    if ($status{$msgid}=~/^error\:/) { $status{$msgid}=''; }
-    unless ($status{$msgid}) { $status{$msgid}='new'; }
+    my ($sendtime,$shortsubj,$fromname,$fromdomain,$count,$fromcid,
+                     $processid)=split(/\:/,&Apache::lonnet::unescape($msgid));
+    if (!defined($processid)) { $fromcid = ''; }
+    my %status=();
+    unless ($skipstatus) {
+	if (ref($status_cache)) {
+	    $status{$msgid} = $status_cache->{$msgid};
+	} else {
+	    my $suffix=&foldersuffix($folder);
+	    %status=&Apache::lonnet::get('email_status'.$suffix,[$msgid]);
+	}
+	if ($status{$msgid}=~/^error\:/) { $status{$msgid}=''; }
+        unless ($status{$msgid}) { $status{$msgid}='new'; }
+    }
     return ($sendtime,$shortsubj,$fromname,$fromdomain,$status{$msgid},$fromcid);
 }
 
@@ -828,11 +862,15 @@ sub sortedmessages {
     my @messages = &Apache::lonnet::getkeys('nohist_email'.$suffix);
     #unpack the varibles and repack into temp for sorting
     my @temp;
+    my %descriptions;
+    my %status_cache = 
+	&Apache::lonnet::get('email_status'.&foldersuffix($folder),\@messages);
     foreach (@messages) {
 	my $msgid=&Apache::lonnet::escape($_);
 	my ($sendtime,$shortsubj,$fromname,$fromdomain,$status,$fromcid)=
-	    &Apache::lonmsg::unpackmsgid($msgid,$folder);
-        my $description = &get_course_desc($fromcid);
+	    &Apache::lonmsg::unpackmsgid($msgid,$folder,undef,
+					 \%status_cache);
+        my $description = &get_course_desc($fromcid,\%descriptions);
 	my @temp1 = ($sendtime,$shortsubj,$fromname,$fromdomain,$status,
 		     $msgid,$description);
         # Check whether message was sent during blocking period.
@@ -886,15 +924,24 @@ sub sortedmessages {
 }
 
 sub get_course_desc {
-    my ($fromcid) = @_;
-    my $description; 
-    if (defined($env{'course.'.$fromcid.'.description'})) {
-       $description = $env{'course.'.$fromcid.'.description'};
+    my ($fromcid,$descriptions) = @_;
+    my $description;
+    if (!$fromcid) {
+        return $description;
     } else {
-       my %courseinfo=&Apache::lonnet::coursedescription($fromcid);
-        $description = $courseinfo{'description'};
+        if (defined($$descriptions{$fromcid})) {
+            $description = $$descriptions{$fromcid};
+        } else {
+            if (defined($env{'course.'.$fromcid.'.description'})) {
+                $description = $env{'course.'.$fromcid.'.description'};
+            } else {
+                my %courseinfo=&Apache::lonnet::coursedescription($fromcid);                $description = $courseinfo{'description'};
+                $description = $courseinfo{'description'};
+            }
+            $$descriptions{$fromcid} = $description;
+        }
+        return $description;
     }
-    return $description;
 }
 
 # ======================================================== Display new messages
@@ -911,10 +958,7 @@ sub disnew {
 				       'op' => 'Open',
 				       'do' => 'Domain'
 				       );
-    my @msgids = sort split(/\&/,&Apache::lonnet::reply
-                            ('keys:'.$env{'user.domain'}.':'.
-                             $env{'user.name'}.':nohist_email',
-                             $env{'user.home'}));
+    my @msgids = sort(&Apache::lonnet::getkeys('nohist_email'));
     my @newmsgs;
     my %setters = ();
     my $startblock = 0;
@@ -923,11 +967,15 @@ sub disnew {
     my $numblocked = 0;
     # Check for blocking of display because of scheduled online exams.
     &blockcheck(\%setters,\$startblock,\$endblock);
+    my %status_cache = 
+	&Apache::lonnet::get('email_status',\@msgids);
+    my %descriptions;
     foreach (@msgids) {
+	my $msgid=&Apache::lonnet::escape($_);
         my ($sendtime,$shortsubj,$fromname,$fromdom,$status,$fromcid)=
-	    &Apache::lonmsg::unpackmsgid($_);
+	    &Apache::lonmsg::unpackmsgid($msgid,undef,undef,\%status_cache);
         if (defined($sendtime) && $sendtime!~/error/) {
-            my $description = &get_course_desc($fromcid);
+            my $description = &get_course_desc($fromcid,\%descriptions);
             my $numsendtime = $sendtime;
             $sendtime = &Apache::lonlocal::locallocaltime($sendtime);
             if ($status eq 'new') {
@@ -936,7 +984,7 @@ sub disnew {
                     $numblocked ++;
                 } else {
                     push @newmsgs, { 
-                        msgid    => $_,
+                        msgid    => $msgid,
                         sendtime => $sendtime,
                         shortsub => &Apache::lonnet::unescape($shortsubj),
                         from     => $fromname,