--- loncom/interface/lonmsg.pm 2006/03/16 22:12:17 1.178
+++ loncom/interface/lonmsg.pm 2020/06/09 21:32:32 1.245
@@ -1,7 +1,7 @@
# The LearningOnline Network with CAPA
# Routines for messaging
#
-# $Id: lonmsg.pm,v 1.178 2006/03/16 22:12:17 albertel Exp $
+# $Id: lonmsg.pm,v 1.245 2020/06/09 21:32:32 raeburn Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -26,7 +26,6 @@
# http://www.lon-capa.org/
#
-
package Apache::lonmsg;
=pod
@@ -37,61 +36,7 @@ Apache::lonmsg: supports internal messag
=head1 SYNOPSIS
-lonmsg provides routines for sending messages, receiving messages, and
-a handler to allow users to read, send, and delete messages.
-
-=head1 OVERVIEW
-
-=head2 Messaging Overview
-
-XLON-CAPA provides an internal messaging system similar to
-email, but customized for LON-CAPA's usage. LON-CAPA implements its
-own messaging system, rather then building on top of email, because of
-the features LON-CAPA messages can offer that conventional e-mail can
-not:
-
-=over 4
-
-=item * B: A message the recipient B
-acknowlegde receipt of before they are allowed to continue using the
-system, preventing a user from claiming they never got a message
-
-=item * B: LON-CAPA can reliably send reciepts informing the
-sender that it has been read; again, useful for preventing students
-from claiming they did not see a message. (While conventional e-mail
-has some reciept support, it's sporadic, e-mail client-specific, and
-generally the receiver can opt to not send one, making it useless in
-this case.)
-
-=item * B: LON-CAPA knows about the sender, such as where
-they are in a course. When a student mails an instructor asking for
-help on the problem, the instructor receives not just the student's
-question, but all submissions the student has made up to that point,
-the user's rendering of the problem, and the complete view the student
-saw of the resource, including discussion up to that point. Finally,
-the instructor is reading all of this inside of LON-CAPA, not their
-email program, so they have full access to LON-CAPA's grading
-interface, or other features they may wish to use in response to the
-student's query.
-
-=item * B: LON-CAPA can block display of e-mails that are
-sent to a student during an online exam. A course coordinator or
-instructor can set an open and close date/time for scheduled online
-exams in a course. If a user uses the LON-CAPA internal messaging
-system to display e-mails during the scheduled blocking event,
-display of all e-mail sent during the blocking period will be
-suppressed, and a message of explanation, including details of the
-currently active blocking periods will be displayed instead. A user
-who has a course coordinator or instructor role in a course will be
-unaffected by any blocking periods for the course, unless the user
-also has a student role in the course, AND has selected the student role.
-
-=back
-
-Users can ask LON-CAPA to forward messages to conventional e-mail
-addresses on their B screen, but generally, LON-CAPA messages
-are much more useful than traditional email can be made to be, even
-with HTML support.
+lonmsg provides routines for sending messages.
Right now, this document will cover just how to send a message, since
it is likely you will not need to programmatically read messages,
@@ -102,73 +47,194 @@ only used by lonmsg when creating/extrac
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 $uname and
-$udom in stored internal messages, compared
+similar. The differences are the use of $uname and
+$udom in stored internal messages, compared
with $email in stored
-Domain Coordinator e-mail for the storage of information about
+Domain Coordinator e-mail for the storage of information about
recipients of the message/e-mail.
-=head1 FUNCTIONS
+=head1 SUBROUTINES
+
+=over
+
+=pod
+
+=item packagemsg()
+
+Package
+
+=item get_course_context()
+
+=item unpackagemsg()
+
+Unpack message into a hash
+
+=item buildmsgid()
+
+Get info out of msgid
+
+=item unpackmsgid()
+
+=item sendemail()
+
+=item sendnotification()
+
+Send notification emails
+
+=item newmail()
+
+Check for email
+
+=item author_res_msg()
+
+Automated message to the author of a resource
+
+=item * B: Sends message $message to the owner
+ of the resource with the URI $filename.
+
+=item retrieve_author_res_msg()
+
+Retrieve author resource messages
+
+=item del_url_author_res_msg()
+
+Delete all author messages related to one URL
+
+=item clear_author_res_msg()
+
+Clear out all author messages in URL path
+
+=item all_url_author_res_msg()
+
+Return hash with URLs for which there is a resource message
+
+=item store_instructor_comment()
+
+Add a comment to the User Notes screen
+
+=item user_crit_msg_raw()
+
+Critical message to a user
+
+=item user_crit_msg()
+
+New routine that respects "forward" and calls old routine
+
+=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
+
+ returns
+ - in array context a list of results for each message that was sent
+ - in scalar context a space seperated list of results for each
+ message sent
+
+
+=item user_crit_received()
+
+Critical message received
+
+=item user_normal_msg_raw()
+
+Normal communication
+
+=item user_normal_msg()
+
+New routine that respects "forward" and calls old routine
+
+=item * B:
+ 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
+ set, and send the message to that address instead
+
+ returns
+ - in array context a list of results for each message that was sent
+ - in scalar context a space seperated list of results for each
+ message sent
-=over 4
+=item store_sent_mail()
+
+=item store_recipients()
+
+=item foldersuffix()
+
+=item get_user_folders()
+
+User-defined folders
+
+=item secapply()
+
+=item B:
+
+Arguments
+ $feedurl - /res/ url of resource (only need if $author is true)
+ $author,$question,$course,$policy - all true/false parameters
+ if true will attempt to find the addresses of user that should receive
+ this type of feedback (author - feedback to author of resource $feedurl,
+ $question 'Resource Content Questions', $course 'Course Content Question',
+ $policy 'Course Policy')
+ (Additionally it also checks $env for whether the corresponding form.
+ element exists, for ease of use in a html response context)
+
+ $defaultflag - (internal should be left blank) if true gather addresses
+ that aren't for a section even if I have a section
+ (used for reccursion internally, first we look for
+ addresses for our specific section then we recurse
+ and look for non section addresses)
+
+Returns
+ $typestyle - string of html text, describing what addresses were found
+ %to - a hash, which keys are addresses of users to send messages to
+ the keys will look like name:domain
+
+=back
=cut
use strict;
use Apache::lonnet;
-use vars qw($msgcount);
+use Apache::loncommon;
use HTML::TokeParser();
-use Apache::Constants qw(:common);
-use Apache::loncommon();
-use Apache::lontexconvert();
-use HTML::Entities();
-use Mail::Send;
use Apache::lonlocal;
-use Apache::loncommunicate;
-use Apache::lonfeedback;
-use Apache::lonrss();
-
-# Querystring component with sorting type
-my $sqs;
-my $startdis;
-my $interdis;
+use HTML::Entities;
+use Encode;
+use LONCAPA qw(:DEFAULT :match);
+
+{
+ my $uniq;
+ sub get_uniq {
+ $uniq++;
+ return $uniq;
+ }
+}
+
-# ===================================================================== Package
sub packagemsg {
my ($subject,$message,$citation,$baseurl,$attachmenturl,
- $recuser,$recdomain,$msgid,$type,$crsmsgid)=@_;
+ $recuser,$recdomain,$msgid,$type,$crsmsgid,$symb,$error,$recipid)=@_;
$message =&HTML::Entities::encode($message,'<>&"');
$citation=&HTML::Entities::encode($citation,'<>&"');
$subject =&HTML::Entities::encode($subject,'<>&"');
#remove machine specification
- $baseurl =~ s|^http://[^/]+/|/|;
+ $baseurl =~ s|^https?://[^/]+/|/|;
$baseurl =&HTML::Entities::encode($baseurl,'<>&"');
#remove machine specification
- $attachmenturl =~ s|^http://[^/]+/|/|;
+ $attachmenturl =~ s|^https?://[^/]+/|/|;
$attachmenturl =&HTML::Entities::encode($attachmenturl,'<>&"');
- my $course_context;
- if (defined($env{'form.replyid'})) {
- my ($sendtime,$shortsubj,$fromname,$fromdomain,$count,$origcid)=
- split(/\:/,&Apache::lonnet::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(/\:/,&Apache::lonnet::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;
- $msgcount++;
+ my $msgcount = &get_uniq();
unless(defined($msgid)) {
$msgid = &buildmsgid($now,$subject,$env{'user.name'},$env{'user.domain'},
- $msgcount,$course_context,$$);
+ $msgcount,$course_context,$symb,$error,$$);
}
my $result = ''.$env{'user.name'}.''.
''.$env{'user.domain'}.''.
@@ -195,12 +261,15 @@ sub packagemsg {
''.$env{'request.role'}.''.
''.$env{'request.filename'}.''.
''.$msgid.'';
+ if (defined($env{'form.group'})) {
+ $result .= ''.$env{'form.group'}.'';
+ }
if (ref($recuser) eq 'ARRAY') {
for (my $i=0; $i<@{$recuser}; $i++) {
if ($type eq 'dcmail') {
my ($username,$email) = split(/:/,$$recuser[$i]);
- $username = &Apache::lonnet::unescape($username);
- $email = &Apache::lonnet::unescape($email);
+ $username = &unescape($username);
+ $email = &unescape($email);
$username = &HTML::Entities::encode($username,'<>&"');
$email = &HTML::Entities::encode($email,'<>&"');
$result .= ''.
@@ -224,13 +293,66 @@ sub packagemsg {
if (defined($attachmenturl)) {
$result.= ''.$attachmenturl.'';
}
- return $msgid,$result;
+ if (defined($symb)) {
+ $result.= ''.$symb.'';
+ if ($course_context ne '') {
+ if ($course_context eq $env{'request.course.id'}) {
+ my $resource_title = &Apache::lonnet::gettitle($symb);
+ if (defined($resource_title)) {
+ $result .= ''.$resource_title.'';
+ }
+ }
+ }
+ }
+ 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;
@@ -250,7 +372,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.'';
@@ -265,21 +387,27 @@ sub unpackagemsg {
return %content;
}
-# ======================================================= Get info out of msgid
sub buildmsgid {
- my ($now,$subject,$uname,$udom,$msgcount,$course_context,$pid) = @_;
- $subject=&Apache::lonnet::escape($subject);
- return(&Apache::lonnet::escape($now.':'.$subject.':'.$uname.':'.
- $udom.':'.$msgcount.':'.$course_context.':'.$pid));
+ my ($now,$subject,$uname,$udom,$msgcount,$course_context,$symb,$error,$pid) = @_;
+ $subject=&escape($subject);
+ $symb = &escape($symb);
+ return(&escape($now.':'.$subject.':'.$uname.':'.
+ $udom.':'.$msgcount.':'.$course_context.':'.$pid.':'.$symb.':'.$error));
}
sub unpackmsgid {
- my ($msgid,$folder,$skipstatus,$status_cache)=@_;
- $msgid=&Apache::lonnet::unescape($msgid);
+ my ($msgid,$folder,$skipstatus,$status_cache,$onlycid)=@_;
+ $msgid=&unescape($msgid);
my ($sendtime,$shortsubj,$fromname,$fromdomain,$count,$fromcid,
- $processid)=split(/\:/,&Apache::lonnet::unescape($msgid));
+ $processid,$symb,$error) = split(/\:/,&unescape($msgid));
if (!defined($processid)) { $fromcid = ''; }
+ if (($onlycid) && ($onlycid ne $fromcid)) {
+ return ($sendtime,'',$fromname,$fromdomain,'',$fromcid,'',$error);
+ }
+ $shortsubj = &unescape($shortsubj);
+ $shortsubj = &HTML::Entities::decode($shortsubj);
+ $symb = &unescape($symb);
my %status=();
unless ($skipstatus) {
if (ref($status_cache)) {
@@ -291,75 +419,195 @@ sub unpackmsgid {
if ($status{$msgid}=~/^error\:/) { $status{$msgid}=''; }
unless ($status{$msgid}) { $status{$msgid}='new'; }
}
- return ($sendtime,$shortsubj,$fromname,$fromdomain,$status{$msgid},$fromcid);
+ return ($sendtime,$shortsubj,$fromname,$fromdomain,$status{$msgid},$fromcid,$symb,$error);
}
sub sendemail {
- my ($to,$subject,$body)=@_;
+ my ($to,$subject,$body,$to_uname,$to_udom,$user_lh,$attachmenturl)=@_;
+ my $senderaddress='';
+ my $replytoaddress='';
+ my $msgsent;
+ if ($env{'form.can_reply'} eq 'N') {
+ my $lonhost = $Apache::lonnet::perlvar{'lonHostID'};
+ my $hostname = &Apache::lonnet::hostname($lonhost);
+ $replytoaddress = 'do-not-reply@'.$hostname;
+ } else {
+ my %senderemails;
+ my $have_sender;
+ 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') {
+ %senderemails =
+ &Apache::loncommon::getemails($replytoname,$replytodom);
+ $have_sender = 1;
+ }
+ }
+ }
+ if (!$have_sender) {
+ %senderemails=&Apache::loncommon::getemails();
+ }
+ foreach my $type ('permanentemail','critnotification','notification') {
+ if ($senderemails{$type}) {
+ ($senderaddress) = split(/,/,$senderemails{$type});
+ last if ($senderaddress);
+ }
+ }
+ }
$body=
- "*** ".&mt('This is an automatic message generated by the LON-CAPA system.')."\n".
- "*** ".&mt('Please do not reply to this address.')."\n\n".$body;
- my $msg = new Mail::Send;
- $msg->to($to);
- $msg->subject('[LON-CAPA] '.$subject);
- if (my $fh = $msg->open()) {
- print $fh $body;
- $fh->close;
+ "*** ".&mt_user($user_lh,'This is an automatic e-mail generated by the LON-CAPA system.')."\n".
+ "*** ".($senderaddress?&mt_user($user_lh,'You can reply to this e-mail'):&mt_user($user_lh,'Please do not reply to this address.')."\n*** ".
+ &mt_user($user_lh,'A reply will not be received by the recipient!'))."\n\n".$body;
+
+ $attachmenturl = &Apache::lonnet::filelocation("",$attachmenturl);
+ my $filesize = (stat($attachmenturl))[7];
+ if ($filesize > 1048576) {
+ # Don't send if it exceeds 1 MB.
+ print '
");
- $r->print(&mt('These').' '.$numblocked.' '.&mt('messages are not viewable because '));
- }
- $r->print(
-&mt('display of LON-CAPA messages sent to you by other students between').' '.$beginblock.' '.&mt('and').' '.$finishblock.' '.&mt('is currently being blocked because of online exams').'.');
- &build_block_table($r,$startblock,$endblock,\%setters);
- }
-}
-
-
-# ======================================================== Display all messages
-
-sub disall {
- my ($r,$folder)=@_;
- $r->print(&folderlist($folder));
- if ($folder eq 'new') {
- &disnew($r);
- } elsif ($folder eq 'critical') {
- &discrit($r);
- } else {
- &disfolder($r,$folder);
- }
-}
-
-# ============================================================ Display a folder
-
-sub disfolder {
- my ($r,$folder)=@_;
- my %blocked = ();
- my %setters = ();
- my $startblock;
- my $endblock;
- my $numblocked = 0;
- &blockcheck(\%setters,\$startblock,\$endblock);
- $r->print(<
- function checkall() {
- for (i=0; i
-ENDDISHEADER
- my $fsqs='&folder='.$folder;
- my @temp=sortedmessages(\%blocked,$startblock,$endblock,\$numblocked,$folder);
- my $totalnumber=$#temp+1;
- unless ($totalnumber>0) {
- $r->print('
'.&mt('Empty Folder').'
');
- return;
- }
- unless ($interdis) {
- $interdis=20;
- }
- my $number=int($totalnumber/$interdis);
- if (($startdis<0) || ($startdis>$number)) { $startdis=$number; }
- my $firstdis=$interdis*$startdis;
- if ($firstdis>$#temp) { $firstdis=$#temp-$interdis+1; }
- my $lastdis=$firstdis+$interdis-1;
- if ($lastdis>$#temp) { $lastdis=$#temp; }
- $r->print(&scrollbuttons($startdis,$number,$firstdis,$lastdis,$totalnumber));
- $r->print('');
- if ($numblocked > 0) {
- my $beginblock = &Apache::lonlocal::locallocaltime($startblock);
- my $finishblock = &Apache::lonlocal::locallocaltime($endblock);
- $r->print('
'.
- $numblocked.' '.&mt('message(s) is/are not viewable because display of LON-CAPA messages sent to you by other students between').' '.$beginblock.' '.&mt('and').' '.$finishblock.' '.&mt('is currently being blocked because of online exams.'));
- &build_block_table($r,$startblock,$endblock,\%setters);
- }
+ my $suffix;
+ my %folderhash = &get_user_folders($folder);
+ if (ref($folderhash{$folder}) eq 'HASH') {
+ $suffix = '_'.&escape($folderhash{$folder}{'id'});
+ } else {
+ $suffix = '_'.&escape($folder);
+ }
+ return $suffix;
}
-# ============================================================== Compose output
-
-sub compout {
- my ($r,$forwarding,$replying,$broadcast,$replycrit,$folder,$dismode)=@_;
- my $suffix=&foldersuffix($folder);
-
- if ($broadcast eq 'individual') {
- &printheader($r,'/adm/email?compose=individual',
- 'Send a Message');
- } elsif ($broadcast) {
- &printheader($r,'/adm/email?compose=group',
- 'Broadcast Message');
- } elsif ($forwarding) {
- &Apache::lonhtmlcommon::add_breadcrumb
- ({href=>"/adm/email?display=".&Apache::lonnet::escape($forwarding),
- text=>"Display Message"});
- &printheader($r,'/adm/email?forward='.&Apache::lonnet::escape($forwarding),
- 'Forwarding a Message');
- } elsif ($replying) {
- &Apache::lonhtmlcommon::add_breadcrumb
- ({href=>"/adm/email?display=".&Apache::lonnet::escape($replying),
- text=>"Display Message"});
- &printheader($r,'/adm/email?replyto='.&Apache::lonnet::escape($replying),
- 'Replying to a Message');
- } elsif ($replycrit) {
- $r->print('
'.&mt('Replying to a Critical Message').'
');
- $replying=$replycrit;
- } else {
- &printheader($r,'/adm/email?compose=upload',
- 'Distribute from Uploaded File');
- }
- my $dispcrit='';
- my $dissub='';
- my $dismsg='';
- my $disbase='';
- my $func=&mt('Send New');
- my %lt=&Apache::lonlocal::texthash('us' => 'Username',
- 'do' => 'Domain',
- 'ad' => 'Additional Recipients',
- 'sb' => 'Subject',
- 'ca' => 'Cancel',
- 'ma' => 'Mail');
-
- if (&Apache::lonnet::allowed('srm',$env{'request.course.id'})
- || &Apache::lonnet::allowed('srm',$env{'request.course.id'}.
- '/'.$env{'request.course.sec'})) {
- my $crithelp = Apache::loncommon::help_open_topic("Course_Critical_Message");
- $dispcrit=
- '
');
- &disfacetoface($r,$env{'form.recuname'},$env{'form.recdomain'});
- $r->print(<
-
-
-ENDRHEAD
- $r->print(<$lt{'newr'}
-
-
-
-
-
-ENDBFORM
- }
-}
-
-# ----------------------------------------------------------- Blocking during exams
-
-sub examblock {
- my ($r,$action) = @_;
- unless ($env{'request.course.id'}) { return;}
- if (!&Apache::lonnet::allowed('srm',$env{'request.course.id'})
- && ! &Apache::lonnet::allowed('srm',$env{'request.course.id'}.
- '/'.$env{'request.course.sec'})) {
- $r->print('Not allowed');
- return;
- }
- my %lt=&Apache::lonlocal::texthash(
- 'comb' => 'Communication Blocking',
- 'cbds' => 'Communication blocking during scheduled exams',
- 'desc' => 'You can use communication blocking to prevent students enrolled in this course from displaying LON-CAPA messages sent by other students during an online exam. As blocking of communication could potentially interrupt legitimate communication between students who are also both enrolled in a different LON-CAPA course, please be careful that you select the correct start and end times for your scheduled exam when setting or modifying these parameters.',
- 'mecb' => 'Modify existing communication blocking periods',
- 'ncbc' => 'No communication blocks currently stored'
- );
-
- my %ltext = &Apache::lonlocal::texthash(
- 'dura' => 'Duration',
- 'setb' => 'Set by',
- 'even' => 'Event',
- 'actn' => 'Action',
- 'star' => 'Start',
- 'endd' => 'End'
- );
-
- &printheader($r,'/adm/email?block=display',$lt{'comb'});
- $r->print('
-END
- return;
-}
-
-sub blockcheck {
- my ($setters,$startblock,$endblock) = @_;
- # Retrieve active student roles and active course coordinator/instructor roles
- my @livecses = ();
- my @staffcses = ();
- $$startblock = 0;
- $$endblock = 0;
- foreach (keys %env) {
- if ($_ =~ m-^user\.role\.(st|cc|in)\./(.+)$-) {
- my $role = $1;
- my $cse = $2;
- $cse =~ s|/|_|;
- if ($env{$_} =~ m/^(\d*)\.(\d*)$/) {
- unless (($2 > 0 && $2 < time) || ($1 > time)) {
- if ($role eq 'st') {
- push @livecses, $cse;
- } else {
- unless (grep/^$cse$/,@staffcses) {
- push @staffcses, $cse;
- }
- }
- }
- }
- } elsif ($_ =~ m-user\.role\.cr/(\w+)/(\w+)/([^/]+)\./(.+)$- ) {
- my $rolepriv = $env{'user.role..rolesdef_'.$3};
- }
- }
- # Retrieve blocking times and identity of blocker for active courses for students.
- if (@livecses > 0) {
- foreach my $cse (@livecses) {
- my ($cdom,$crs) = split/_/,$cse;
- if ( (grep/^$cse$/,@staffcses) && ($env{'request.role'} !~ m-^st\./$cdom/$crs$-) ) {
- next;
- } else {
- %{$$setters{$cse}} = ();
- @{$$setters{$cse}{'staff'}} = ();
- @{$$setters{$cse}{'times'}} = ();
- my %records = &Apache::lonnet::dump('comm_block',$cdom,$crs);
- foreach (keys %records) {
- if ($_ =~ m/^(\d+)____(\d+)$/) {
- if ($1 <= time && $2 >= time) {
- my ($staff,$title) = split/:/,$records{$_};
- push @{$$setters{$cse}{'staff'}}, $staff;
- push @{$$setters{$cse}{'times'}}, $_;
- if ( ($$startblock == 0) || ($$startblock > $1) ) {
- $$startblock = $1;
- }
- if ( ($$endblock == 0) || ($$endblock < $2) ) {
- $$endblock = $2;
- }
- }
- }
- }
- }
- }
- }
-}
-
-sub build_block_table {
- my ($r,$startblock,$endblock,$setters) = @_;
- my $function = &Apache::loncommon::get_users_function();
- my $color = &Apache::loncommon::designparm($function.'.tabbg',
- $env{'user.domain'});
- my %lt = &Apache::lonlocal::texthash(
- 'cacb' => 'Currently active communication blocks',
- 'cour' => 'Course',
- 'dura' => 'Duration',
- 'blse' => 'Block set by'
- );
- $r->print(<<"END");
- $lt{'cacb'}:
-
-
-
-
-
-
-
-
-
$lt{'cour'}
-
$lt{'dura'}
-
$lt{'blse'}
-
-END
- foreach (keys %{$setters}) {
- my %courseinfo=&Apache::lonnet::coursedescription($_);
- for (my $i=0; $i<@{$$setters{$_}{staff}}; $i++) {
- my ($uname,$udom) = split/\@/,$$setters{$_}{staff}[$i];
- my $fullname = &Apache::loncommon::plainname($uname,$udom);
- my ($openblock,$closeblock) = split/____/,$$setters{$_}{times}[$i];
- $openblock = &Apache::lonlocal::locallocaltime($openblock);
- $closeblock= &Apache::lonlocal::locallocaltime($closeblock);
- $r->print('
'.$courseinfo{'description'}.'
'.
- '
'.$openblock.' to '.$closeblock.'
'.
- '
'.$fullname.' ('.$uname.'@'.$udom.
- ')
');
- }
- }
- $r->print('
');
-}
-
-# ----------------------------------------------------------- Display a message
-
-sub displaymessage {
- my ($r,$msgid,$folder)=@_;
- my $suffix=&foldersuffix($folder);
- my %blocked = ();
- my %setters = ();
- my $startblock = 0;
- my $endblock = 0;
- my $numblocked = 0;
-# info to generate "next" and "previous" buttons and check if message is blocked
- &blockcheck(\%setters,\$startblock,\$endblock);
- my @messages=&sortedmessages(\%blocked,$startblock,$endblock,\$numblocked,$folder);
- if ( $blocked{$msgid} eq 'ON' ) {
- &printheader($r,'/adm/email',&mt('Display a Message'));
- $r->print(&mt('You attempted to display a message that is currently blocked because you are enrolled in one or more courses for which there is an ongoing online exam.'));
- &build_block_table($r,$startblock,$endblock,\%setters);
- return;
- }
- &statuschange($msgid,'read',$folder);
- my %message=&Apache::lonnet::get('nohist_email'.$suffix,[$msgid]);
- my %content=&unpackagemsg($message{$msgid});
-
- my $counter=0;
- $r->print('
');
- my $number_of_messages = scalar(@messages); #subtract 1 for last index
-# start output
- &printheader($r,'/adm/email?display='.&Apache::lonnet::escape($msgid),'Display a Message','',$content{'baseurl'});
- my %courseinfo=&Apache::lonnet::coursedescription($content{'courseid'});
-# Functions
- $r->print('
'.&displayresource(%content).'');
- return;
-}
-
-# =========================================================== Show the citation
-
-sub displayresource {
- my %content=@_;
-#
-# If the recipient is in the same course that the message was sent from and
-# has sufficient privileges, show "all details," else show citation
-#
- if (($env{'request.course.id'} eq $content{'courseid'})
- && (&Apache::lonnet::allowed('vgr',$content{'courseid'}))) {
- my $symb=&Apache::lonnet::symbread($content{'baseurl'});
-# Could not get a symb, give up
- unless ($symb) { return $content{'citation'}; }
-# Have a symb, can render
- return '
'.&mt('Current attempts of student (if applicable)').'