--- loncom/interface/lonmsg.pm	2001/07/28 04:16:29	1.11
+++ loncom/interface/lonmsg.pm	2001/10/01 19:24:49	1.23
@@ -13,7 +13,8 @@
 # 10/19,10/20,10/30,
 # 02/06/01 Gerd Kortemeyer
 # 07/27 Guy Albertelli
-# 07/27 Gerd Kortemeyer
+# 07/27,07/28,07/30,08/03,08/06,08/08,08/09,08/10,8/13,8/15,
+# 10/1 Gerd Kortemeyer
 
 package Apache::lonmsg;
 
@@ -121,7 +122,6 @@ sub user_crit_msg {
     unless (($message)&&($user)&&($domain)) { $status='empty'; };
     my $homeserver=&Apache::lonnet::homeserver($user,$domain);
     if ($homeserver ne 'no_host') {
-       my $msgid;
        ($msgid,$message)=&packagemsg($subject,$message);
        $status=&Apache::lonnet::critical(
            'put:'.$domain.':'.$user.':critical:'.
@@ -143,8 +143,9 @@ sub user_crit_msg {
 # =================================================== Critical message received
 
 sub user_crit_received {
-    my $message=shift;
-    my %contents=&unpackagemsg($message);
+    my $msgid=shift;
+    my %message=&Apache::lonnet::get('critical',[$msgid]);
+    my %contents=&unpackagemsg($message{$msgid});
     my $status='rec: '.
      &user_normal_msg($contents{'sendername'},$contents{'senderdomain'},
                      'Receipt: '.$ENV{'user.name'}.' at '.$ENV{'user.domain'},
@@ -153,13 +154,15 @@ sub user_crit_received {
                      $contents{'subject'}.'" dated '.$contents{'time'}.".\n\n"
                      .'Message ID: '.$contents{'msgid'});
     $status.=' trans: '.
-     &Apache::lonnet::put('nohist_email',{$contents{'msgid'} => $message});
+     &Apache::lonnet::put(
+     'nohist_email',{$contents{'msgid'} => $message{$msgid}});
     $status.=' del: '.
      &Apache::lonnet::del('critical',[$contents{'msgid'}]);
     &Apache::lonnet::log($ENV{'user.domain'},$ENV{'user.name'},
                          $ENV{'user.home'},'Received critical message '.
                          $contents{'msgid'}.
                          ', '.$status);
+    return $status;
 }
 
 # ======================================================== Normal communication
@@ -172,7 +175,6 @@ sub user_normal_msg {
     unless (($message)&&($user)&&($domain)) { $status='empty'; };
     my $homeserver=&Apache::lonnet::homeserver($user,$domain);
     if ($homeserver ne 'no_host') {
-       my $msgid;
        ($msgid,$message)=&packagemsg($subject,$message,$citation);
        $status=&Apache::lonnet::critical(
            'put:'.$domain.':'.$user.':nohist_email:'.
@@ -198,54 +200,104 @@ sub statuschange {
             ($status{$msgid} eq 'forwarded')) {
 	&Apache::lonnet::put('email_status',{$msgid => $newstatus});
     }
+    if (($newstatus eq 'deleted') || ($newstatus eq 'new')) {
+	&Apache::lonnet::put('email_status',{$msgid => $newstatus});
+    }
 }
-# ===================================================================== Handler
 
-sub handler {
+# ======================================================= Display a course list
+
+sub discourse {
     my $r=shift;
+    my %courselist=&Apache::lonnet::dump(
+                   'classlist',
+		   $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},
+		   $ENV{'course.'.$ENV{'request.course.id'}.'.num'});
+    my $now=time;
+    $r->print(<<ENDDISHEADER);
+<input type=hidden name=sendmode value=group>
+<script>
+    function checkall() {
+	for (i=0; i<document.forms.compemail.elements.length; i++) {
+            if 
+          (document.forms.compemail.elements[i].name.indexOf('send_to_')==0) {
+	      document.forms.compemail.elements[i].checked=true;
+            }
+        }
+    }
 
-# ----------------------------------------------------------- Set document type
+    function checksec() {
+	for (i=0; i<document.forms.compemail.elements.length; i++) {
+            if 
+          (document.forms.compemail.elements[i].name.indexOf
+           ('send_to_&&&'+document.forms.compemail.chksec.value)==0) {
+	      document.forms.compemail.elements[i].checked=true;
+            }
+        }
+    }
 
-  $r->content_type('text/html');
-  $r->send_http_header;
+    function uncheckall() {
+	for (i=0; i<document.forms.compemail.elements.length; i++) {
+            if 
+          (document.forms.compemail.elements[i].name.indexOf('send_to_')==0) {
+	      document.forms.compemail.elements[i].checked=false;
+            }
+        }
+    }
+</script>
+<input type=button onClick="checkall()" value="Check for All">&nbsp;
+<input type=button onClick="checksec()" value="Check for Section/Group">
+<input type=text size=5 name=chksec>&nbsp;
+<input type=button onClick="uncheckall()" value="Check for None">
+<p>
+ENDDISHEADER
+    map {
+        my ($end,$start)=split(/\:/,$courselist{$_});
+        my $active=1;
+        if (($end) && ($now>$end)) { $active=0; }
+        if ($active) {
+           my ($sname,$sdom)=split(/\:/,$_);
+           my %reply=&Apache::lonnet::get('environment',
+              ['firstname','middlename','lastname','generation'],
+              $sdom,$sname);
+           my $section=&Apache::lonnet::usection
+	       ($sdom,$sname,$ENV{'request.course.id'});
+           $r->print(
+        '<br><input type=checkbox name="send_to_&&&'.$section.'&&&_'.$_.'"> '.
+		      $reply{'firstname'}.' '. 
+                      $reply{'middlename'}.' '.
+                      $reply{'lastname'}.' '.
+                      $reply{'generation'}.
+                      ' ('.$_.') '.$section);
+        } 
+    } sort keys %courselist;
+}
 
-  return OK if $r->header_only;
+# ==================================================== Display Critical Message
 
-# --------------------------- Get query string for limited number of parameters
+sub discrit {
+    my $r=shift;
+      $r->print('<h1><font color=red>Critical Messages</font></h1>'.
+         '<form action=/adm/email method=post>'.
+         '<input type=hidden name=confirm value=true>');
+      my %what=&Apache::lonnet::dump('critical');
+      map {
+          my %content=&unpackagemsg($what{$_});
+          $content{'message'}=~s/\n/\<br\>/g;
+	  $r->print('<hr>From: <b>'.$content{'sendername'}.'@'.
+                    $content{'senderdomain'}.'</b> ('.$content{'time'}.
+                    ')<br><blockquote>'.$content{'message'}.'</blockquote>'.
+  '<input type=submit name="rec_'.$_.'" value="Confirm Receipt">'.
+ '<input type=submit name="reprec_'.$_.'" value="Confirm Receipt and Reply">');
+      } sort keys %what;
+      $r->print(
+          '<input type=hidden name="displayedcrit" value="true"></form>');
+}
 
-    map {
-       my ($name, $value) = split(/=/,$_);
-       $value =~ tr/+/ /;
-       $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
-       if (($name eq 'display') || ($name eq 'replyto') || 
-           ($name eq 'forward') || ($name eq 'mark') ||
-           ($name eq 'sendreply') || ($name eq 'compose')) {
-           unless ($ENV{'form.'.$name}) {
-              $ENV{'form.'.$name}=$value;
-	   }
-       }
-    } (split(/&/,$ENV{'QUERY_STRING'}));
+# =============================================================== Compose reply
 
-# --------------------------------------------------------------- Render Output
-  
-  $r->print('<html><head><title>EMail and Messaging</title></head>');
-  $r->print(
-   '<body bgcolor="#FFFFFF"><img align=right src=/adm/lonIcons/lonlogos.gif>');
-  $r->print('<h1>EMail</h1>');
-  if ($ENV{'form.display'}) {
-      my $msgid=$ENV{'form.display'};
-      &statuschange($msgid,'read');
-      my %message=&Apache::lonnet::get('nohist_email',[$msgid]);
-      my %content=&unpackagemsg($message{$msgid});
-      $r->print('<b>Subject:</b> '.$content{'subject'}.
-             '<br><b>From:</b> '.$content{'sendername'}.' at '.
-                                 $content{'senderdomain'}.
-             '<br><b>Time:</b> '.$content{'time'}.'<hr>Functions: '.
-             '<a href="/adm/email?replyto='.&Apache::lonnet::escape($msgid).
-             '"><b>Reply</b></a><hr><pre>'.
-             $content{'message'}.'</pre><hr>'.$content{'citation'});
-  } elsif ($ENV{'form.replyto'}) {
-      my $msgid=$ENV{'form.replyto'};
+sub comprep {
+    my ($r,$msgid)=@_;
       my %message=&Apache::lonnet::get('nohist_email',[$msgid]);
       my %content=&unpackagemsg($message{$msgid});
       my $quotemsg='> '.$content{'message'};
@@ -262,47 +314,26 @@ sub handler {
 <form action="/adm/email" method=post>
 <input type=hidden name=sendreply value="$msgid">
 Subject: <input type=text size=50 name=subject value="$subject"><p>
-<textarea name=message cols=60 rows=10>
+<textarea name=message cols=64 rows=10 wrap=hard>
 $quotemsg
 </textarea><p>
 $dispcrit
 <input type=submit value="Send Reply">
 </form>
 ENDREPLY
-  } elsif ($ENV{'form.sendreply'}) {
-      my $msgid=$ENV{'form.sendreply'};
-      my %message=&Apache::lonnet::get('nohist_email',[$msgid]);
-      my %content=&unpackagemsg($message{$msgid});
-      &statuschange($msgid,'replied');
-      $r->print('Sending: '.&user_normal_msg($content{'sendername'},
-                                 $content{'senderdomain'},
-                                 $ENV{'form.subject'},
-                                 $ENV{'form.message'}));
-  } elsif ($ENV{'form.forward'}) {
-  } elsif ($ENV{'form.mark'}) {
-  } elsif ($ENV{'form.compose'}) {
-      my $dispcrit='';
-      if (&Apache::lonnet::allowed('srm',$ENV{'request.course.id'})) {
-         $dispcrit=
-	     '<input type=checkbox name=critmsg> Send as critical message<p>';
-      }
-      $r->print(<<"ENDCOMP");
-<form action="/adm/email" method=post>
-<input type=hidden name=sendmail value=on>
-Subject: <input type=text size=50 name=subject value=""><p>
-<textarea name=message cols=60 rows=10>
-</textarea><p>
-$dispcrit
-<input type=submit value="Send Mail">
-</form>
-ENDCOMP
-  } elsif ($ENV{'form.sendmail'}) {
-  } else {
-    $r->print('<table border=2><tr><th>&nbsp</th><th>Date</th>'.
+}
+
+# ======================================================== Display all messages
+
+sub disall {
+    my $r=shift;
+    $r->print('<h1>Display All Messages</h1>'.
+     '<table border=2><tr><th colspan=2>&nbsp</th><th>Date</th>'.
      '<th>Username</th><th>Domain</th><th>Subject</th><th>Status</th></tr>');
     map {
         my ($sendtime,$shortsubj,$fromname,$fromdomain,$status)=
 	    &Apache::lonmsg::unpackmsgid($_);
+       unless ($status eq 'deleted') {
         if ($status eq 'new') {
 	    $r->print('<tr bgcolor="#FFBB77">');
         } elsif ($status eq 'read') {
@@ -313,16 +344,262 @@ ENDCOMP
 	    $r->print('<tr bgcolor="#99BBBB">');
         }
         $r->print('<td><a href="/adm/email?display='.$_.
-                  '">Open</a></td><td>'.localtime($sendtime).'</td><td>'.
+                  '">Open</a></td><td><a href="/adm/email?markdel='.$_.
+                  '">Delete</a></td><td>'.localtime($sendtime).'</td><td>'.
                   $fromname.'</td><td>'.$fromdomain.'</td><td>'.
 		      &Apache::lonnet::unescape($shortsubj).'</td><td>'.
                       $status.'</td></tr>');
+       }
     } sort split(/\&/,&Apache::lonnet::reply('keys:'.
 					$ENV{'user.domain'}.':'.
                                         $ENV{'user.name'}.':nohist_email',
                                         $ENV{'user.home'}));
     $r->print('</table></body></html>');
+}
+
+# ============================================================== Compose output
 
+sub compout {
+    my ($r,$forwarding,$broadcast)=@_;
+      my $dispcrit='';
+    my $dissub='';
+    my $dismsg='';
+    my $func='Send New';
+      if (&Apache::lonnet::allowed('srm',$ENV{'request.course.id'})) {
+         $dispcrit=
+	     '<input type=checkbox name=critmsg> Send as critical message<p>';
+      }
+    if ($forwarding) {
+       $dispcrit.='<input type=hidden name=forwid value="'.
+	   $forwarding.'">';
+       $func='Forward';
+      my %message=&Apache::lonnet::get('nohist_email',[$forwarding]);
+      my %content=&unpackagemsg($message{$forwarding});
+
+       $dissub='Forwarding: '.$content{'subject'};
+       $dismsg='Forwarded message from '.
+	   $content{'sendername'}.' at '.$content{'senderdomain'};
+    }
+    my $defdom=$ENV{'user.domain'};
+      $r->print(
+                '<form action="/adm/email"  name="compemail" method=post'.
+                ' enctype="multipart/form-data">'.
+                '<input type=hidden name=sendmail value=on><table>');
+    unless (($broadcast eq 'group') || ($broadcast eq 'upload')) {
+       $r->print(<<"ENDREC");
+<table>
+<tr><td>Username:</td><td><input type=text size=12 name=recuname></td></tr>
+<tr><td>Domain:</td>
+<td><input type=text size=12 name=recdomain value="$defdom"></td></tr>
+ENDREC
+    }
+    unless ($broadcast eq 'upload') {
+       $r->print(<<"ENDCOMP");
+<tr><td>Additional Recipients<br><tt>username\@domain,username\@domain, ...
+</tt></td><td>
+<input type=text size=50 name=additionalrec></td></tr>
+<tr><td>Subject:</td><td><input type=text size=50 name=subject value="$dissub">
+</td></tr></table>
+<textarea name=message cols=60 rows=10 wrap=hard>$dismsg
+</textarea><p>
+$dispcrit
+<input type=submit value="$func Mail">
+ENDCOMP
+    }
+    if ($broadcast eq 'upload') {
+	$r->print(<<ENDUPLOAD);
+<input type=hidden name=sendmode value=upload>
+<h3>Generate messages from a file</h3>
+Subject: <input type=text size=50 name=subject>
+<pre>
+username1\@domain1: text
+username2\@domain2: text
+username1\@domain1: text
+</pre>
+The messages will be assembled from all lines with the respective 
+<tt>username\@domain</tt>, and appended to the general message text.<p>
+<input type=file name=upfile size=20><p>
+General message text:<p>
+<textarea name=message cols=60 rows=10 wrap=hard>$dismsg
+</textarea><p>
+$dispcrit
+<input type=submit value="Upload and send">
+ENDUPLOAD
+    }
+    if ($broadcast eq 'group') {
+       &discourse;
+    }
+    $r->print('</form>');
+}
+
+# ===================================================================== Handler
+
+sub handler {
+    my $r=shift;
+
+# ----------------------------------------------------------- Set document type
+
+  $r->content_type('text/html');
+  $r->send_http_header;
+
+  return OK if $r->header_only;
+
+# --------------------------- Get query string for limited number of parameters
+
+    map {
+       my ($name, $value) = split(/=/,$_);
+       $value =~ tr/+/ /;
+       $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C",hex($1))/eg;
+       if (($name eq 'display') || ($name eq 'replyto') || 
+           ($name eq 'forward') || ($name eq 'markread') ||
+           ($name eq 'markdel') || ($name eq 'markunread') ||
+           ($name eq 'sendreply') || ($name eq 'compose') ||
+           ($name eq 'sendmail') || ($name eq 'critical')) {
+           unless ($ENV{'form.'.$name}) {
+              $ENV{'form.'.$name}=$value;
+	   }
+       }
+    } (split(/&/,$ENV{'QUERY_STRING'}));
+
+# --------------------------------------------------------------- Render Output
+  
+  $r->print('<html><head><title>EMail and Messaging</title></head>');
+  $r->print(
+   '<body bgcolor="#FFFFFF"><img align=right src=/adm/lonIcons/lonlogos.gif>');
+  $r->print('<h1>EMail</h1>');
+  if ($ENV{'form.display'}) {
+      my $msgid=$ENV{'form.display'};
+      &statuschange($msgid,'read');
+      my %message=&Apache::lonnet::get('nohist_email',[$msgid]);
+      my %content=&unpackagemsg($message{$msgid});
+      $r->print('<b>Subject:</b> '.$content{'subject'}.
+             '<br><b>From:</b> '.$content{'sendername'}.' at '.
+                                 $content{'senderdomain'}.
+             '<br><b>Time:</b> '.$content{'time'}.'<p>'.
+             '<table border=2><tr bgcolor="#FFFFAA"><td>Functions:</td>'.
+           '<td><a href="/adm/email?replyto='.&Apache::lonnet::escape($msgid).
+             '"><b>Reply</b></a></td>'.
+           '<td><a href="/adm/email?forward='.&Apache::lonnet::escape($msgid).
+             '"><b>Forward</b></a></td>'.
+        '<td><a href="/adm/email?markunread='.&Apache::lonnet::escape($msgid).
+             '"><b>Mark Unread</b></a></td>'.
+        '<td><a href="/adm/email"><b>Display all Messages</b></a></td>'.
+             '</tr></table><p><pre>'.
+             $content{'message'}.'</pre><hr>'.$content{'citation'});
+  } elsif ($ENV{'form.replyto'}) {
+      &comprep($r,$ENV{'form.replyto'});
+  } elsif ($ENV{'form.sendreply'}) {
+      my $msgid=$ENV{'form.sendreply'};
+      my %message=&Apache::lonnet::get('nohist_email',[$msgid]);
+      my %content=&unpackagemsg($message{$msgid});
+      &statuschange($msgid,'replied');
+      if (($ENV{'form.critmsg'}) && 
+          (&Apache::lonnet::allowed('srm',$ENV{'request.course.id'}))) {
+         $r->print('Sending critical: '.
+                &user_crit_msg($content{'sendername'},
+                                 $content{'senderdomain'},
+                                 $ENV{'form.subject'},
+                                 $ENV{'form.message'}));
+      } else {
+         $r->print('Sending: '.&user_normal_msg($content{'sendername'},
+                                 $content{'senderdomain'},
+                                 $ENV{'form.subject'},
+                                 $ENV{'form.message'}));
+      }
+      if ($ENV{'form.displayedcrit'}) {
+          &discrit($r);
+      } else {
+	  &disall($r);
+      }
+  } elsif ($ENV{'form.confirm'}) {
+      map {
+          if ($_=~/^form\.rec\_(.*)$/) {
+	      $r->print('<b>Confirming Receipt:</b> '.
+                        &user_crit_received($1).'<br>');
+          }
+          if ($_=~/^form\.reprec\_(.*)$/) {
+              my $msgid=$1;
+	      $r->print('<b>Confirming Receipt:</b> '.
+                        &user_crit_received($msgid).'<br>');
+              &comprep($r,$msgid);
+          }
+      } keys %ENV;
+      &discrit($r);
+  } elsif ($ENV{'form.critical'}) {
+      &discrit($r);
+  } elsif ($ENV{'form.forward'}) {
+      &compout($r,$ENV{'form.forward'});
+  } elsif ($ENV{'form.markread'}) {
+  } elsif ($ENV{'form.markdel'}) {
+      &statuschange($ENV{'form.markdel'},'deleted');
+      &disall($r);
+  } elsif ($ENV{'form.markunread'}) {
+      &statuschange($ENV{'form.markunread'},'new');
+      &disall($r);
+  } elsif ($ENV{'form.compose'}) {
+      &compout($r,'',$ENV{'form.compose'});
+  } elsif ($ENV{'form.sendmail'}) {
+      my %content=();
+      undef %content;
+      if ($ENV{'form.forwid'}) {
+        my $msgid=$ENV{'form.forwid'};
+        my %message=&Apache::lonnet::get('nohist_email',[$msgid]);
+        %content=&unpackagemsg($message{$msgid});
+        &statuschange($msgid,'forwarded');
+        $ENV{'form.message'}.="\n\n-- Forwarded message --\n\n".
+	                       $content{'message'};
+      }
+      my %toaddr=();
+      undef %toaddr;
+      if ($ENV{'form.sendmode'} eq 'group') {
+          map {
+	      if ($_=~/^form\.send\_to\_\&\&\&[^\&]*\&\&\&\_(.+)$/) {
+		  $toaddr{$1}='';
+              }
+          } keys %ENV;
+      } elsif ($ENV{'form.sendmode'} eq 'upload') {
+          map {
+              my ($rec,$txt)=split(/\s*\:\s*/,$_);
+              if ($txt) {
+		  $rec=~s/\@/\:/;
+                  $toaddr{$rec}.=$txt."\n";
+              }
+          } split(/[\n\r\f]+/,$ENV{'form.upfile'});
+      } else {
+	  $toaddr{$ENV{'form.recuname'}.':'.$ENV{'form.recdomain'}}='';
+      }
+      if ($ENV{'form.additionalrec'}) {
+	  map {
+              my ($auname,$audom)=split(/\@/,$_);
+              $toaddr{$auname.':'.$audom}='';
+          } split(/\,/,$ENV{'form.additionalrec'});
+      }
+    map {
+      my ($recuname,$recdomain)=split(/\:/,$_);
+      my $msgtxt=$ENV{'form.message'};
+      if ($toaddr{$_}) { $msgtxt.='<hr>'.$toaddr{$_}; }    
+      if (($ENV{'form.critmsg'}) && 
+          (&Apache::lonnet::allowed('srm',$ENV{'request.course.id'}))) {
+         $r->print('Sending critical: '.
+                &user_crit_msg($recuname,$recdomain,
+                                 $ENV{'form.subject'},
+                                 $msgtxt,
+                                 $content{'citation'}));
+      } else {
+         $r->print('Sending: '.&user_normal_msg($recuname,$recdomain,
+                                 $ENV{'form.subject'},
+                                 $msgtxt,
+                                 $content{'citation'}));
+      }
+      $r->print('<br>');
+    } keys %toaddr;
+      if ($ENV{'form.displayedcrit'}) {
+          &discrit($r);
+      } else {
+	  &disall($r);
+      }
+  } else {
+      &disall($r);
   }
   $r->print('</body></html>');
   return OK;