--- loncom/interface/lonannounce.pm 2006/03/15 21:55:43 1.46
+++ loncom/interface/lonannounce.pm 2006/06/29 16:44:49 1.57
@@ -1,7 +1,7 @@
# The LearningOnline Network
# Announce
#
-# $Id: lonannounce.pm,v 1.46 2006/03/15 21:55:43 albertel Exp $
+# $Id: lonannounce.pm,v 1.57 2006/06/29 16:44:49 albertel Exp $
#
# Copyright Michigan State University Board of Trustees
#
@@ -50,7 +50,7 @@ sub editfield {
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');
+ my $help=&Apache::loncommon::help_open_menu('Calendar Add Announcement','Calendar_Add_Announcement',274,'Communication Tools');
my %lt=&Apache::lonlocal::texthash('post' => 'Post Announcement',
'start' => 'Starting date',
'end' => 'Ending date',
@@ -81,101 +81,112 @@ sub readcalendar {
}
}
- if ($courseid eq $env{'request.course.id'}) {
- my $can_see_hidden = $env{'request.role.adv'};
- my $navmap = Apache::lonnavmaps::navmap->new();
- 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=~/^\[(.*)\]\./) {
- my $sec=$1;
- # if we have a section don't show ones that aren't ours
- if ($env{'request.course.sec'} &&
- $env{'request.course.sec'} ne $sec) { next; }
- # if a student without a section don't show any section ones
- if (!$env{'request.role.adv'} &&
- !$env{'request.course.sec'}) { next; }
- $section=&mt('Group/Section').': '.$1;
- $middle=~s/^\[(.*)\]\.//;
+ my $can_see_hidden = $env{'request.role.adv'};
+ my $navmap;# = Apache::lonnavmaps::navmap->new();
+ 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 %data = ( 'section' => &mt('All Students'));
+ if ($middle=~/^\[(.*)\]\./) {
+ my $sec=$1;
+ # if we have a section don't show ones that aren't ours
+ if ($env{'request.course.sec'} &&
+ $env{'request.course.sec'} ne $sec) { next; }
+ # if a student without a section don't show any section ones
+ if (!$env{'request.role.adv'} &&
+ !$env{'request.course.sec'}) { next; }
+ $data{'section'}=&mt('Group/Section').': '.$1;
+ $middle=~s/^\[(.*)\]\.//;
+ }
+ $middle=~s/\.$//;
+ $data{'realm'}=&mt('All Resources');
+ if ($middle eq '___(all)') {
+ if (!$can_see_hidden && !$navmap) {
+ next;
+ }
+ } elsif ($middle=~/^(.+)\_\_\_\(all\)$/) {
+ my $map_url=$1;
+ if (!$can_see_hidden && !$navmap) {
+ next;
+ }
+ if (!$can_see_hidden) {
+ my $res = $navmap->getResourceByUrl($map_url);
+ if ($res && $res->randomout()) { next; }
+ }
+ $data{'realm'}=&mt('Folder/Map');
+ $data{'url'} = $map_url;
+ } elsif ($middle) {
+ if (!$can_see_hidden && !$navmap) {
+ next;
}
- $middle=~s/\.$//;
- my $realm=&mt('All Resources');
- if ($middle=~/^(.+)\_\_\_\(all\)$/) {
- my $map_url=$1;
- if (!$can_see_hidden && !$navmap) {
- next;
- }
- if (!$can_see_hidden) {
- my $res = $navmap->getResourceByUrl($map_url);
- if ($res && $res->randomout()) { next; }
- }
- $realm=&mt('Folder/Map').': '.&Apache::lonnet::gettitle($map_url);
- } elsif ($middle) {
- if (!$can_see_hidden && !$navmap) {
- next;
- }
- if (!$can_see_hidden) {
- my $res = $navmap->getBySymb($middle);
- if ($res && $res->randomout()) { next; }
- }
- $realm=&mt('Resource').': '.&Apache::lonnet::gettitle($middle);
+ if (!$can_see_hidden) {
+ my $res = $navmap->getBySymb($middle);
+ if ($res && $res->randomout()) { next; }
}
- my $datetype='';
- if ($name eq 'duedate') {
- $datetype=&mt('Due');
+ $data{'realm'} = &mt('Resource');
+ $data{'symb'} = $middle;
+ }
+ $data{'datetype'} = $name;
+ if ($name eq 'duedate') {
+ $data{'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';
- }
+ my $answerkey=$thiskey;
+ $answerkey=~s/duedate$/answerdate/;
+ if ($resourcedata{$thiskey}>$resourcedata{$answerkey}) {
+ $data{'datetype'} = &mt('Due and Answer Available');
}
- if ($name eq 'opendate') { $datetype=&mt('Opening'); }
- if ($name eq 'answerdate') {
+ }
+ if ($name eq 'opendate'
+ || $name eq 'contentopen' ) {
+ $data{'datetype'}=&mt('Opening');
+ }
+ if ($name eq 'contentclose') {
+ $data{'datetype'}=&mt('Closing');
+ }
+ if ($name eq 'answerdate') {
# see if accidentally answerdate is before duedate
- my $duekey=$thiskey;
- $duekey=~s/answerdate$/duedate/;
- if ($resourcedata{$duekey}>$resourcedata{$thiskey}) {
+ 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.')';
+ next;
+ }
+ $data{'datetype'}=&mt('Answer Available');
}
+ $returnhash{$courseid.'@'.$resourcedata{$thiskey}.'_'.
+ $resourcedata{$thiskey}}=\%data;
}
}
return %returnhash;
}
sub emptycell {
- return '
| ';
+ return ' | ';
}
sub normalcell {
- my ($day,$month,$year,$text)=@_;
- my $output='';
- my @items=&order($text);
+ my ($day,$month,$year,$items_ref)=@_;
+ my $output;
+ my @items=&order($items_ref);
foreach my $item (@items) {
if ($item) {
- my $internalflag=0;
- my ($courseid,$start,$end,$msg)=split(/\@/,$item,4);
- if ($msg=~/INTERNAL\:/) {
- $msg=~s/INTERNAL\://gs;
- $internalflag=1;
- }
+ my ($courseid,$start,$end,$msg)=@$item;
+ my $internalflag= (ref($msg)) ? 1 : 0;
+ $msg = &display_msg($msg);
my $fullmsg=&mt('Calendar Announcement for ').$env{'course.'.$courseid.'.description'}.
'\n'.&Apache::lonlocal::locallocaltime($start);
if ($start!=$end) {
$fullmsg.=' - '.&Apache::lonlocal::locallocaltime($end);
}
$fullmsg.=':\n'.$msg;
+ $fullmsg=~s/[\n\r]/\\n/gs;
+ $fullmsg=&HTML::Entities::encode($fullmsg,'<>&"\'');
+ $fullmsg=~s/&/\\&/g;
+ my $short_msg = substr($msg,0,20).((length($msg) > 20)?'...':'');
+ if (defined($output)) { $output.='
'; }
if ($courseid eq $env{'request.course.id'}) {
if ((&Apache::lonnet::allowed('srm',$env{'request.course.id'}))
&& (!$showedcheck{$start.'_'.$end})
@@ -186,59 +197,56 @@ sub normalcell {
$showedcheck{$start.'_'.$end}=1;
}
}
- $fullmsg=~s/[\n\r]/\\n/gs;
- $fullmsg=&HTML::Entities::encode($fullmsg,'<>&"\'');
- $fullmsg=~s/&/\\&/g;
$output.=''.
- substr($msg,0,20).'...
';
+ $short_msg.'';
}
}
- return ''.&tfont(''.&picklink($day,$day,$month,$year).' '.$output).' | ';
+ ($year eq $todayhash{'year'}))?'_current':'').
+ '" >'.&picklink($day,$day,$month,$year).'
'.$output.'';
}
sub plaincell {
- my ($text)=@_;
- my $output='';
- my @items=&order($text);
+ my ($items_ref)=@_;
+ my $output;
+ my @items=&order($items_ref);
foreach my $item (@items) {
- if ($item) {
- my ($courseid,$start,$end,$msg)=split(/\@/,$item,4);
+ if (ref($item)) {
+ my ($courseid,$start,$end,$msg)=@$item;
my $fullmsg=&mt('Calendar Announcement for ').$env{'course.'.$courseid.'.description'}.
'\n'.&Apache::lonlocal::locallocaltime($start);
if ($start!=$end) {
$fullmsg.=' - '.&Apache::lonlocal::locallocaltime($end);
}
- $msg=~s/INTERNAL\://gs;
+ $msg = &display_msg($msg);
$fullmsg.=':\n'.$msg;
$fullmsg=~s/[\n\r]/\\n/gs;
$fullmsg=&HTML::Entities::encode($fullmsg,'<>&"\'');
$fullmsg=~s/&/\\&/g;
+ my $short_msg = substr($msg,0,80).((length($msg) > 80)?'...':'');
+ if (defined($output)) { $output.='
'; }
$output.=''.
- substr($msg,0,80).'...
';
+ $short_msg.'';
}
}
return $output;
}
sub listcell {
- my ($text)=@_;
+ my ($items_ref)=@_;
my $output='';
- my @items=&order($text);
+ my @items=&order($items_ref);
foreach my $item (@items) {
- if ($item) {
- my ($courseid,$start,$end,$msg)=split(/\@/,$item,4);
- $msg=~s/INTERNAL\://gs;
- my $fullmsg=&Apache::lonlocal::locallocaltime($start);
+ if (ref($item)) {
+ my ($courseid,$start,$end,$msg)=@$item;
+ my $fullmsg=&Apache::lonlocal::locallocaltime($start);
if ($start!=$end) {
$fullmsg.=&mt(' to ').
&Apache::lonlocal::locallocaltime($end);
}
- $fullmsg.=':
'.
- $msg.'';
+ $fullmsg.=':
'.&display_msg($msg).'';
$output.=''.$fullmsg.'';
}
}
@@ -246,16 +254,15 @@ sub listcell {
}
sub order {
- my ($text)=@_;
- my @items = split(/___&&&___/,$text);
- sort {
- my (undef,$astart,$aend)=split(/\@/,$a);
- my (undef,$bstart,$bend)=split(/\@/,$b);
+ my ($items)=@_;
+ return sort {
+ my ($astart,$aend)=$a->[1,2];
+ my ($bstart,$bend)=$b->[1,2];
if ($astart != $bstart) {
return $astart <=> $bstart;
}
return $aend <=> $bend;
- } @items;
+ } @$items;
}
sub nextday {
@@ -264,11 +271,28 @@ sub nextday {
return (&Apache::loncommon::maketime(%th),$th{'month'});
}
+sub display_msg {
+ my ($msg) = @_;
+
+ # if it's not a ref, it's an instructor provided message
+ return $msg if (!ref($msg));
+
+ my $output = $msg->{'datetype'}. ': '.$msg->{'realm'};
+ if (exists($msg->{'url'})) {
+ $output .= ': '.&Apache::lonnet::gettitle($msg->{'url'});
+ }
+ if (exists($msg->{'symb'})) {
+ $output .= ': '.&Apache::lonnet::gettitle($msg->{'symb'});
+ }
+ $output .= ' ('.$msg->{'section'}.') ';
+ return $output;
+}
+
sub showday {
my ($tk,$mode,%allcal)=@_;
my %th=&Apache::loncommon::timehash($tk);
my ($nextday,$nextmonth)=&nextday(%th);
- my $outp='';
+ my @outp;
if ($mode) {
my $oneday=24*3600;
$tk-=$oneday;
@@ -277,33 +301,23 @@ sub showday {
foreach my $item (keys(%allcal)) {
my ($course,$startdate,$enddate)=($item=~/^(\w+)\@(\d+)\_(\d+)$/);
if (($startdate<$nextday) && ($enddate>=$tk)) {
- $outp.='___&&&___'.$course.'@'.$startdate.'@'.$enddate.'@'.
- $allcal{$item};
+ push(@outp,[$course,$startdate,$enddate,$allcal{$item}]);
}
}
unless ($mode) {
return ($nextday,$nextmonth,&normalcell(
- $th{'day'},$th{'month'},$th{'year'},$outp));
- } elsif ($outp) {
+ $th{'day'},$th{'month'},$th{'year'},\@outp));
+ } elsif (@outp) {
if ($mode==1) {
- return '
'.&plaincell($outp);
+ return '
'.&plaincell(\@outp);
} else {
- return '';
+ return '';
}
} else {
return '';
}
}
-sub tfont {
- my $text=shift;
- if ($env{'form.pickdate'} eq 'yes') {
- return ''.$text.'';
- } else {
- return $text;
- }
-}
-
sub picklink {
my ($text,$day,$month,$year)=@_;
if ($env{'form.pickdate'} eq 'yes') {
@@ -331,9 +345,50 @@ function dialin(day,month,year) {
ENDDIA
}
+# ----------------------------------------------------- Summarize all calendars
+sub get_all_calendars {
+ my %allcal=();
+ foreach my $course (sort(&Apache::loncommon::findallcourses())) {
+ %allcal=(%allcal,&readcalendar($course));
+ }
+ return %allcal;
+}
+
+sub output_ics_file {
+ my ($r)=@_;
+# RFC 2445 wants CRLF
+ my $crlf="\015\012";
+# Header
+ $r->print("BEGIN:VCALENDAR$crlf");
+ $r->print("VERSION:2.0$crlf");
+ $r->print("PRODID:-//LONCAPA//LONCAPA Calendar Output//EN$crlf");
+ my %allcal=&get_all_calendars();
+ foreach my $event (keys(%allcal)) {
+ my ($courseid,$startdate,$enddate)=($event=~/^(\w+)\@(\d+)\_(\d+)$/);
+ my $uid=$event;
+ $uid=~s/[\W\_]/-/gs;
+ $uid.='@loncapa';
+ my $summary=&display_msg($allcal{$event});
+ $summary=~s/\s+/ /gs;
+ $summary=$env{'course.'.$courseid.'.description'}.': '.$summary;
+ $r->print("BEGIN:VEVENT$crlf");
+ $r->print("DTSTART:".&Apache::loncommon::utc_string($startdate).$crlf);
+ $r->print("DTEND:".&Apache::loncommon::utc_string($enddate).$crlf);
+ $r->print("SUMMARY:$summary$crlf");
+ $r->print("UID:$uid$crlf");
+ $r->print("END:VEVENT$crlf");
+ }
+# Footer
+ $r->print("END:VCALENDAR$crlf");
+}
sub handler {
my $r = shift;
+ if ($r->uri=~/\.(ics|ical)$/) {
+ &Apache::loncommon::content_type($r,'text/calendar');
+ &output_ics_file($r);
+ return OK;
+ }
&Apache::loncommon::content_type($r,'text/html');
$r->send_http_header;
return OK if $r->header_only;
@@ -342,8 +397,7 @@ sub handler {
my $today=time;
%todayhash=&Apache::loncommon::timehash($today);
# ----------------------------------------------------------------- Check marks
- %showedcheck=();
- undef %showedcheck;
+ undef(%showedcheck);
# ---------------------------------------------------------- Get month and year
&Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
['month','year','pickdate','formname','element']);
@@ -366,12 +420,8 @@ sub handler {
'dlsav' => -1 ));
my $weekday=$firstday{'weekday'};
# ------------------------------------------------------------ Print the screen
- my $html=&Apache::lonxml::xmlbegin();
- $r->print(<
-The LearningOnline Network with CAPA
-
-
ENDDOCUMENT
+
if ($pickdatemode) {
# no big header in pickdate mode
- $r->print(&Apache::loncommon::bodytag("Pick a Date",'','',1).
+ $r->print(&Apache::loncommon::start_page("Pick a Date",$js,
+ {'only_body' => 1,}).
&dialscript().
'');
} else {
- $r->print(&Apache::loncommon::bodytag("Announcements and Calendar"));
+ $r->print(&Apache::loncommon::start_page("Announcements and Calendar",
+ $js));
}
# does this user have privileges to post, etc?
my $allowed=0;
@@ -487,11 +539,7 @@ SERVERANNOUNCE
&editfield($r,$today,$tomorrow,'');
}
# ----------------------------------------------------- Summarize all calendars
- my %allcal=();
- foreach my $course (&Apache::loncommon::findallcourses()) {
- %allcal=(%allcal,&readcalendar($course));
- }
-
+ my %allcal=&get_all_calendars();
# ------------------------------- 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); }
@@ -507,9 +555,15 @@ SERVERANNOUNCE
if (($year<1970) || ($year>2037)) {
$r->print('No calendar available for this date.
'.
'Current Month