File:  [LON-CAPA] / loncom / interface / lonannounce.pm
Revision 1.30: download - view: text, annotated - select for diffs
Tue Aug 17 15:38:58 2004 UTC (19 years, 8 months ago) by www
Branches: MAIN
CVS tags: version_1_1_99_5, HEAD
Blocker bug #3308: it really does not matter if it is CURRENTLY daylight
saving time. Telling mktime that we don't know if is or is not daylight
saving time appears to work just fine.
Bug #3089: make days appear on top of cells (and <br> should be <br />)
For inclusion in 1.2

# The LearningOnline Network
# Announce
#
# $Id: lonannounce.pm,v 1.30 2004/08/17 15:38:58 www Exp $
#
# Copyright Michigan State University Board of Trustees
#
# This file is part of the LearningOnline Network with CAPA (LON-CAPA).
#
# LON-CAPA is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# LON-CAPA is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with LON-CAPA; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
#
# /home/httpd/html/adm/gpl.txt
#
# http://www.lon-capa.org/
#

package Apache::lonannounce;

use strict;
use Apache::Constants qw(:common);
use Apache::loncommon;
use Apache::lonhtmlcommon();
use Apache::lonlocal;
use HTML::Entities();

my %todayhash;
my %showedcheck;

sub editfield {
    my ($r,$start,$end,$text)=@_;
    # Deal with date forms
    my $startdateform = &Apache::lonhtmlcommon::date_setter('anno',
                                                            'startdate',
                                                            $start);
    my $enddateform = &Apache::lonhtmlcommon::date_setter('anno',
                                                          'enddate',
                                                          $end);
    my $help=&Apache::loncommon::help_open_menu('','Calendar Add Announcement','Calendar_Add_Announcement','',274,'Communication Tools');
    $r->print(<<ENDFORM);
$help
<form name="anno" method="post">
<input type="hidden" value=''          name="action"      >
<table><tr><td>Starting date:</td><td>$startdateform</td></tr>
<tr><td>Ending date:</td><td>$enddateform</td></tr></table>
<textarea name="msg" rows="4" cols="60">$text</textarea>
<input type="button" onClick="trysubmit()" value="Post Announcement"><hr />
ENDFORM
}

sub readcalendar {
    my $courseid=shift;
    my $coursenum=$ENV{'course.'.$courseid.'.num'};
    my $coursedom=$ENV{'course.'.$courseid.'.domain'};
    my %thiscal=&Apache::lonnet::dump('calendar',$coursedom,$coursenum);
    my %returnhash=();
    foreach (keys %thiscal) {
        unless (($_=~/^error\:/) || ($thiscal{$_}=~/^error\:/)) {
	   $returnhash{$courseid.'@'.$_}=$thiscal{$_};
        }
    }
    if ($courseid eq $ENV{'request.course.id'}) {
	my %resourcedata=
	    &Apache::lonnet::dump('resourcedata',$coursedom,$coursenum);
	foreach my $thiskey (sort keys %resourcedata) {
	    if ($resourcedata{$thiskey.'.type'}=~/^date/) {
		my ($course,$middle,$part,$name)=
		    ($thiskey=~/^(\w+)\.(?:(.+)\.)*([\w\s]+)\.(\w+)$/);
		my $section=&mt('All Students');
		if ($middle=~/^\[(.*)\]\./) {
		    $section=&mt('Group/Section').': '.$1;
		    $middle=~s/^\[(.*)\]\.//;
		}
		$middle=~s/\.$//;
		my $realm=&mt('All Resources');
		if ($middle=~/^(.+)\_\_\_\(all\)$/) {
		    $realm=&mt('Folder/Map').': '.&Apache::lonnet::gettitle($1);
		} elsif ($middle) {
		    $realm=&mt('Resource').': '.&Apache::lonnet::gettitle($middle);
		}
		my $datetype='';
		if ($name eq 'duedate') { 
		    $datetype=&mt('Due'); 
# see if accidentally answerdate is before duedate
		    my $answerkey=$thiskey;
		    $answerkey=~s/duedate$/answerdate/;
		    if ($resourcedata{$thiskey}>$resourcedata{$answerkey}) {
			$datetype='Due and Answer Available';
		    }
		}
		if ($name eq 'opendate') { $datetype=&mt('Opening'); }
		if ($name eq 'answerdate') {
# see if accidentally answerdate is before duedate
		    my $duekey=$thiskey;
		    $duekey=~s/answerdate$/duedate/;
		    if ($resourcedata{$duekey}>$resourcedata{$thiskey}) {
# forget it
			next;
		    } 
		    $datetype=&mt('Answer Available'); 
		}
		$returnhash{$courseid.'@'.$resourcedata{$thiskey}.'_'.
			    $resourcedata{$thiskey}}=
			    'INTERNAL:'.$datetype.': '.$realm.' ('.$section.')';
	    }
	}
    }
    return %returnhash;
}

sub emptycell {
    return '<td bgcolor="#AAAAAA">&nbsp;</td>';
}

sub normalcell {
    my ($day,$month,$year,$text)=@_;
    my $output='';
    foreach (split(/\_\_\_\&\&\&\_\_\_/,$text)) {
        if ($_) {
	    my $internalflag=0;
	    my ($courseid,$start,$end,@msg)=split(/\@/,$_);
            my $msg=join('@',@msg);
	    if ($msg=~/INTERNAL\:/) {
		$msg=~s/INTERNAL\://gs;
		$internalflag=1;
	    }
            my $fullmsg=$ENV{'course.'.$courseid.'.description'}.
		', '.&Apache::lonlocal::locallocaltime($start);
	    if ($start!=$end) {
		$fullmsg.=' - '.&Apache::lonlocal::locallocaltime($end);
	    }
	    $fullmsg.=': '.$msg;
            if ($courseid eq $ENV{'request.course.id'}) {
              if ((&Apache::lonnet::allowed('srm',$ENV{'request.course.id'}))
               && (!$showedcheck{$start.'_'.$end})
	       && ($ENV{'form.pickdate'} ne 'yes')
	       && (!$internalflag)) {
               $output.='<input type="checkbox" name="remove_'.$start.'_'.
		   $end.'">';
               $showedcheck{$start.'_'.$end}=1;
	      }
	    }
            $fullmsg=&HTML::Entities::encode($fullmsg,'<>&"\'');
            $fullmsg=~s/&/\\&/g;
            $output.='<a href="javascript:alert('."'$fullmsg'".')">'.
	       substr($msg,0,20).'...</a><br />';
       }
    }
    return '<td valign="top"'.
	((($day eq $todayhash{'day'}) &&
          ($month eq $todayhash{'month'}) &&
          ($year eq $todayhash{'year'}))?' bgcolor="#FFFF00"':'').
           '>'.&tfont('<b>'.&picklink($day,$day,$month,$year).'</b><br />'.$output).'</td>';
}

sub plaincell {
    my ($text)=@_;
    my $output='';
    foreach (split(/\_\_\_\&\&\&\_\_\_/,$text)) {
        if ($_) {
	    my ($courseid,$start,$end,@msg)=split(/\@/,$_);
            my $msg=join('@',@msg);
            my $fullmsg=$ENV{'course.'.$courseid.'.description'}.
		', '.&Apache::lonlocal::locallocaltime($start);
	    if ($start!=$end) {
		$fullmsg.=' - '.&Apache::lonlocal::locallocaltime($end);
	    }
	    $msg=~s/INTERNAL\://gs;
	    $fullmsg.=': '.$msg;
            $fullmsg=&HTML::Entities::encode($fullmsg,'<>&"\'');
            $fullmsg=~s/&/\\&/g;
            $output.='<a href="javascript:alert('."'$fullmsg'".')">'.
	       substr($msg,0,40).'...</a><br />';
       }
    }
    return $output;
}

sub listcell {
    my ($text)=@_;
    my $output='';
    foreach (split(/\_\_\_\&\&\&\_\_\_/,$text)) {
        if ($_) {
	    my ($courseid,$start,$end,@msg)=split(/\@/,$_);
            my $msg=join('@',@msg);
	    $msg=~s/INTERNAL\://gs;
            my $fullmsg=&Apache::lonlocal::locallocaltime($start);
	    if ($start!=$end) {
		$fullmsg.=&mt(' to ').
		    &Apache::lonlocal::locallocaltime($end);
	    }
            $fullmsg.=':<br /><b>'.
               $msg.'</b>';
            $output.='<li>'.$fullmsg.'</li>';
       }
    }
    return $output;
}

sub nextday {
    my %th=@_;
    $th{'day'}++;
    return (&Apache::loncommon::maketime(%th),$th{'month'});
}

sub showday {
    my ($tk,$mode,%allcal)=@_;
    my %th=&Apache::loncommon::timehash($tk);
    my ($nextday,$nextmonth)=&nextday(%th);
    my $outp='';
    if ($mode) {
	my $oneday=24*3600;
	$tk-=$oneday;
	$nextday+=$oneday;
    }
    foreach (keys %allcal) {
	my ($course,$startdate,$enddate)=($_=~/^(\w+)\@(\d+)\_(\d+)$/);
        if (($startdate<$nextday) && ($enddate>$tk))  {
	    $outp.='___&&&___'.$course.'@'.$startdate.'@'.$enddate.'@'.
            $allcal{$_};
        }
    }
    unless ($mode) {
       return ($nextday,$nextmonth,&normalcell(
               $th{'day'},$th{'month'},$th{'year'},$outp));
   } elsif ($outp) {
       if ($mode==1) {
          return '<br />'.&plaincell($outp);
      } else {
          return '<ul>'.&listcell($outp).'</ul>';
      }
   } else {
       return '';
   }
}

sub tfont {
    my $text=shift;
    if ($ENV{'form.pickdate'} eq 'yes') {
	return '<font size="1">'.$text.'</font>';
    } else {
	return $text;
    }
}

sub picklink {
    my ($text,$day,$month,$year)=@_;
    if ($ENV{'form.pickdate'} eq 'yes') {
	return '<a href="javascript:dialin('.$day.','.$month.','.$year.')">'.
	    $text.'</a>';
    } else {
	return $text;
    }
}

sub dialscript {
    return (<<ENDDIA);
<script language="Javascript">
function dialin(day,month,year) {
	opener.document.$ENV{'form.formname'}.$ENV{'form.element'}\_year.value=year;
    var slct=opener.document.$ENV{'form.formname'}.$ENV{'form.element'}\_month;
    var i;
    for (i=0;i<slct.length;i++) {
        if (slct.options[i].value==month) { slct.selectedIndex=i; }
    }
    opener.document.$ENV{'form.formname'}.$ENV{'form.element'}\_day.value=day;
    opener.$ENV{'form.element'}\_checkday();
    self.close();
}
</script>
ENDDIA
}

sub handler {
    my $r = shift;
    &Apache::loncommon::content_type($r,'text/html');
    $r->send_http_header;
    return OK if $r->header_only;

# ---------------------------------------------------------- Get time right now
    my $today=time;
    %todayhash=&Apache::loncommon::timehash($today);
# ----------------------------------------------------------------- Check marks
    %showedcheck=();
    undef %showedcheck;
# ---------------------------------------------------------- Get month and year
    &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
                             ['month','year','pickdate','formname','element']);
# --------------------------------------------------- Decide what month to show
    my $year=$todayhash{'year'};
    if ($ENV{'form.year'}) { $year=$ENV{'form.year'}; }
    my $month=$todayhash{'month'};
    if ($ENV{'form.month'}) { $month=$ENV{'form.month'}; }

# ---------------------------------------------- See if we are in pickdate mode
    my $pickdatemode=($ENV{'form.pickdate'} eq 'yes');
    my $pickinfo='&pickdate=yes&formname='.$ENV{'form.formname'}.
	'&element='.$ENV{'form.element'};
# --------------------------------------------- Find out first day of the month

    my %firstday=&Apache::loncommon::timehash(
       &Apache::loncommon::maketime( 'day' => 1, 'month'=> $month,
                                     'year' => $year, 'hours' => 0,
				     'minutes' => 0, 'seconds' => 0,
                                     'dlsav' => -1 ));
    my $weekday=$firstday{'weekday'};
# ------------------------------------------------------------ Print the screen

    $r->print(<<ENDDOCUMENT);
<html>
<head>
<title>The LearningOnline Network with CAPA</title>
<script>

    function trysubmit() {
        document.anno.action.value="new";
	document.anno.submit();
    }

    function removesub() {
        document.anno.action.value="del";
	document.anno.submit();
    }
</script>
</head>
ENDDOCUMENT
    if ($pickdatemode) {
# no big header in pickdate mode
	$r->print(&Apache::loncommon::bodytag("Pick a Date",'','',1).
		  &dialscript().
		  '<font size="1">');
    } else {
       $r->print(&Apache::loncommon::bodytag("Announcements and Calendar"));
    }
# does this user have privileges to post, etc?
    my $allowed=0;
    if ($ENV{'request.course.id'}) {
       $allowed=&Apache::lonnet::allowed('srm',$ENV{'request.course.id'});
    }
# does this user have privileges to post to servers?
    my $serverpost=0;
    if ($ENV{'request.role.domain'}) {
	$serverpost=&Apache::lonnet::allowed('psa',
					     $ENV{'request.role.domain'});
    } else {
	$serverpost=&Apache::lonnet::allowed('psa','/');
    }
# -------------------------------- BUT: do no fancy stuff when in pickdate mode
    if ($pickdatemode) { 
	$serverpost=0; 
	$allowed=0;
    }
# ------------------------------------------------------------ Process commands
    if ($serverpost) {
	if ($ENV{'form.serveraction'}) {
	    foreach (keys %ENV) {
		if ($_=~/^form\.postto\_(\w+)/) {
		    $r->print( 
			'<br />Posting '.$1.': '.&Apache::lonnet::postannounce
			($1,$ENV{'form.serverannnounce'}));
		}
	    }
	}
	$r->print(<<SERVERANNOUNCE);
<form name="serveranno" method="post">
<h3>Post Server Announcements</h3>
Post announcements to the system login and roles screen<br />
<i>(leave blank to delete announcement)</i><br />
<textarea name="serverannnounce" cols="60" rows="5"></textarea><br />
Check machines:<br />
SERVERANNOUNCE
# list servers
    foreach (sort keys %Apache::lonnet::hostname) {
	if (&Apache::lonnet::allowed('psa',$Apache::lonnet::hostdom{$_})) {
	    $r->print ('<br /><input type="checkbox" name="postto_'.$_.'" /> '.
		       $_.' <tt>'.$Apache::lonnet::hostname{$_}.'</tt> '.
		       '<a href="http://'.$Apache::lonnet::hostname{$_}.
		       '/announcement.txt" target="annowin">current</a>');
	}
    }
    $r->print(
  '<br /><input type="submit" name="serveraction" value="Post"></form><hr />');
    }
    if ($allowed) {
        my $coursenum=$ENV{'course.'.$ENV{'request.course.id'}.'.num'};
        my $coursedom=$ENV{'course.'.$ENV{'request.course.id'}.'.domain'};
# ----------------------------------------------------- Store new submitted one
        if ($ENV{'form.action'} eq 'new') {
	    my $startdate = 
		&Apache::lonhtmlcommon::get_date_from_form('startdate');
	    my $enddate   = 
		&Apache::lonhtmlcommon::get_date_from_form('enddate');
	    unless ($startdate=~/^\d+$/) { $startdate=time; }
            unless ($enddate=~/^\d+$/) { $enddate=$startdate+1; }
            if ($startdate>$enddate) {
		my $buffer=$startdate;
		$startdate=$enddate;
		$enddate=$buffer;
            }
	    &Apache::lonnet::put('calendar',{ 
		$startdate.'_'.$enddate => 
		    $ENV{'form.msg'} },$coursedom,$coursenum);
        }
# ---------------------------------------------------------------- Remove items
        if ($ENV{'form.action'} eq 'del') {
	    my @delwhich=();
            foreach (keys %ENV) {
		if ($_=~/^form\.remove\_(.+)$/) {
		    push(@delwhich,$1);
                }
            }
            &Apache::lonnet::del('calendar',\@delwhich,$coursedom,$coursenum);
        }
# -------------------------------------------------------- Form to post new one
        my %tomorrowhash=%todayhash;
        $tomorrowhash{'day'}++;
        my $tomorrow=&Apache::loncommon::maketime(%tomorrowhash);
        
        &editfield($r,$today,$tomorrow,'');
    }
# ----------------------------------------------------- Summarize all calendars
    my %allcal=();
    foreach (&Apache::loncommon::findallcourses()) {
	%allcal=(%allcal,&readcalendar($_));
    }

# ------------------------------- Initialize table and forward backward buttons
    my ($pm,$py,$fm,$fy)=($month-1,$year,$month+1,$year);
    if ($pm<1) { ($pm,$py)=(12,$year-1); }
    if ($fm>12){ ($fm,$fy)=(1,$year+1); }

    $r->print('<h1>'.('',&mt('January'),&mt('February'),&mt('March'),
		      &mt('April'),&mt('May'),
		      &mt('June'),&mt('July'),&mt('August'),
                      &mt('September'),&mt('October'),
                      &mt('November'),&mt('December'))[$month].' '.
	              $year.'</h1>');
# Reached the end of times, give up
    if (($year<1970) || ($year>2037)) {
	$r->print('<h3>No calendar available for this date.</h3>'.
 '<a href="/adm/announcements?month='.$todayhash{'month'}.
 '&year='.$todayhash{'year'}.'">Current Month</a></body></html>');
	return OK;
    }
    $r->print(
 '<a href="/adm/announcements?month='.$pm.'&year='.$py.
 ($pickdatemode?$pickinfo:'').'">'.&mt('Previous Month').'</a> '.
 '<a href="/adm/announcements?month='.$fm.'&year='.$fy.
 ($pickdatemode?$pickinfo:'').'">'.&mt('Next Month').'</a>'.
 '&nbsp;&nbsp;&nbsp;<a href="/adm/announcements?month='.$todayhash{'month'}.
 '&year='.$todayhash{'year'}.
 ($pickdatemode?$pickinfo:'').'">'.&mt('Current Month').'</a><p>'.
        '<table border="2" cols="7" rows="5"><tr><th>'.
&tfont(&mt('Sun'))
.'</th><th>'.
&tfont(&mt('Mon'))
.'</th><th>'.
&tfont(&mt('Tue'))
.'</th><th>'.
&tfont(&mt('Wed'))
.'</th><th>'.
&tfont(&mt('Thu'))
.'</th><th>'.
&tfont(&mt('Fri'))
.'</th><th>'.
&tfont(&mt('Sat'))
.'</th></tr>');

    my $tk=&Apache::loncommon::maketime(%firstday);
    my $outp;
    my $nm;

# ---------------------------------------------------------------- Actual table
    $r->print('<tr>');
    for (my $i=0;$i<$weekday;$i++) { $r->print(&emptycell); }
    for (my $i=$weekday;$i<=6;$i++) { 
        ($tk,$nm,$outp)=&showday($tk,0,%allcal);
        $r->print($outp);
    }
    $r->print('</tr>');

    for (my $k=0;$k<=4;$k++) {
        $r->print('<tr>');
        for (my $i=0;$i<=6;$i++) {
            ($tk,$nm,$outp)=&showday($tk,0,%allcal);
            if ($month!=$nm) { $outp=&emptycell; }
            $r->print($outp);
        }
        $r->print('</tr>');
    }
# ------------------------------------------------------------------- End table
    $r->print('</table>');
# ----------------------------------------------------------------- Check marks
    %showedcheck=();
    undef %showedcheck;
# --------------------------------------------------------------- Remove button
    if ($allowed) { $r->print('<input type="button" onClick="removesub()" value="Remove Checked Entries">'.
			      &Apache::loncommon::help_open_topic('Calendar_Remove_Announcement').'</form>'); }
    $r->print('<p>'.
 '<a href="/adm/announcements?month='.$pm.'&year='.$py.
 ($pickdatemode?$pickinfo:'').'">'.&mt('Previous Month').'</a> '.
 '<a href="/adm/announcements?month='.$fm.'&year='.$fy.
 ($pickdatemode?$pickinfo:'').'">'.&mt('Next Month').'</a>'.
 '&nbsp;&nbsp;&nbsp;<a href="/adm/announcements?month='.$todayhash{'month'}.
 '&year='.$todayhash{'year'}.
 ($pickdatemode?$pickinfo:'').'">'.&mt('Current Month').'</a></p>'.
 ($pickdatemode?'</font>':'').
 '</body></html>');
    return OK;
} 

1;
__END__

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>