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, 10 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
1: # The LearningOnline Network
2: # Announce
3: #
4: # $Id: lonannounce.pm,v 1.30 2004/08/17 15:38:58 www Exp $
5: #
6: # Copyright Michigan State University Board of Trustees
7: #
8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
9: #
10: # LON-CAPA is free software; you can redistribute it and/or modify
11: # it under the terms of the GNU General Public License as published by
12: # the Free Software Foundation; either version 2 of the License, or
13: # (at your option) any later version.
14: #
15: # LON-CAPA is distributed in the hope that it will be useful,
16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18: # GNU General Public License for more details.
19: #
20: # You should have received a copy of the GNU General Public License
21: # along with LON-CAPA; if not, write to the Free Software
22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23: #
24: # /home/httpd/html/adm/gpl.txt
25: #
26: # http://www.lon-capa.org/
27: #
28:
29: package Apache::lonannounce;
30:
31: use strict;
32: use Apache::Constants qw(:common);
33: use Apache::loncommon;
34: use Apache::lonhtmlcommon();
35: use Apache::lonlocal;
36: use HTML::Entities();
37:
38: my %todayhash;
39: my %showedcheck;
40:
41: sub editfield {
42: my ($r,$start,$end,$text)=@_;
43: # Deal with date forms
44: my $startdateform = &Apache::lonhtmlcommon::date_setter('anno',
45: 'startdate',
46: $start);
47: my $enddateform = &Apache::lonhtmlcommon::date_setter('anno',
48: 'enddate',
49: $end);
50: my $help=&Apache::loncommon::help_open_menu('','Calendar Add Announcement','Calendar_Add_Announcement','',274,'Communication Tools');
51: $r->print(<<ENDFORM);
52: $help
53: <form name="anno" method="post">
54: <input type="hidden" value='' name="action" >
55: <table><tr><td>Starting date:</td><td>$startdateform</td></tr>
56: <tr><td>Ending date:</td><td>$enddateform</td></tr></table>
57: <textarea name="msg" rows="4" cols="60">$text</textarea>
58: <input type="button" onClick="trysubmit()" value="Post Announcement"><hr />
59: ENDFORM
60: }
61:
62: sub readcalendar {
63: my $courseid=shift;
64: my $coursenum=$ENV{'course.'.$courseid.'.num'};
65: my $coursedom=$ENV{'course.'.$courseid.'.domain'};
66: my %thiscal=&Apache::lonnet::dump('calendar',$coursedom,$coursenum);
67: my %returnhash=();
68: foreach (keys %thiscal) {
69: unless (($_=~/^error\:/) || ($thiscal{$_}=~/^error\:/)) {
70: $returnhash{$courseid.'@'.$_}=$thiscal{$_};
71: }
72: }
73: if ($courseid eq $ENV{'request.course.id'}) {
74: my %resourcedata=
75: &Apache::lonnet::dump('resourcedata',$coursedom,$coursenum);
76: foreach my $thiskey (sort keys %resourcedata) {
77: if ($resourcedata{$thiskey.'.type'}=~/^date/) {
78: my ($course,$middle,$part,$name)=
79: ($thiskey=~/^(\w+)\.(?:(.+)\.)*([\w\s]+)\.(\w+)$/);
80: my $section=&mt('All Students');
81: if ($middle=~/^\[(.*)\]\./) {
82: $section=&mt('Group/Section').': '.$1;
83: $middle=~s/^\[(.*)\]\.//;
84: }
85: $middle=~s/\.$//;
86: my $realm=&mt('All Resources');
87: if ($middle=~/^(.+)\_\_\_\(all\)$/) {
88: $realm=&mt('Folder/Map').': '.&Apache::lonnet::gettitle($1);
89: } elsif ($middle) {
90: $realm=&mt('Resource').': '.&Apache::lonnet::gettitle($middle);
91: }
92: my $datetype='';
93: if ($name eq 'duedate') {
94: $datetype=&mt('Due');
95: # see if accidentally answerdate is before duedate
96: my $answerkey=$thiskey;
97: $answerkey=~s/duedate$/answerdate/;
98: if ($resourcedata{$thiskey}>$resourcedata{$answerkey}) {
99: $datetype='Due and Answer Available';
100: }
101: }
102: if ($name eq 'opendate') { $datetype=&mt('Opening'); }
103: if ($name eq 'answerdate') {
104: # see if accidentally answerdate is before duedate
105: my $duekey=$thiskey;
106: $duekey=~s/answerdate$/duedate/;
107: if ($resourcedata{$duekey}>$resourcedata{$thiskey}) {
108: # forget it
109: next;
110: }
111: $datetype=&mt('Answer Available');
112: }
113: $returnhash{$courseid.'@'.$resourcedata{$thiskey}.'_'.
114: $resourcedata{$thiskey}}=
115: 'INTERNAL:'.$datetype.': '.$realm.' ('.$section.')';
116: }
117: }
118: }
119: return %returnhash;
120: }
121:
122: sub emptycell {
123: return '<td bgcolor="#AAAAAA"> </td>';
124: }
125:
126: sub normalcell {
127: my ($day,$month,$year,$text)=@_;
128: my $output='';
129: foreach (split(/\_\_\_\&\&\&\_\_\_/,$text)) {
130: if ($_) {
131: my $internalflag=0;
132: my ($courseid,$start,$end,@msg)=split(/\@/,$_);
133: my $msg=join('@',@msg);
134: if ($msg=~/INTERNAL\:/) {
135: $msg=~s/INTERNAL\://gs;
136: $internalflag=1;
137: }
138: my $fullmsg=$ENV{'course.'.$courseid.'.description'}.
139: ', '.&Apache::lonlocal::locallocaltime($start);
140: if ($start!=$end) {
141: $fullmsg.=' - '.&Apache::lonlocal::locallocaltime($end);
142: }
143: $fullmsg.=': '.$msg;
144: if ($courseid eq $ENV{'request.course.id'}) {
145: if ((&Apache::lonnet::allowed('srm',$ENV{'request.course.id'}))
146: && (!$showedcheck{$start.'_'.$end})
147: && ($ENV{'form.pickdate'} ne 'yes')
148: && (!$internalflag)) {
149: $output.='<input type="checkbox" name="remove_'.$start.'_'.
150: $end.'">';
151: $showedcheck{$start.'_'.$end}=1;
152: }
153: }
154: $fullmsg=&HTML::Entities::encode($fullmsg,'<>&"\'');
155: $fullmsg=~s/&/\\&/g;
156: $output.='<a href="javascript:alert('."'$fullmsg'".')">'.
157: substr($msg,0,20).'...</a><br />';
158: }
159: }
160: return '<td valign="top"'.
161: ((($day eq $todayhash{'day'}) &&
162: ($month eq $todayhash{'month'}) &&
163: ($year eq $todayhash{'year'}))?' bgcolor="#FFFF00"':'').
164: '>'.&tfont('<b>'.&picklink($day,$day,$month,$year).'</b><br />'.$output).'</td>';
165: }
166:
167: sub plaincell {
168: my ($text)=@_;
169: my $output='';
170: foreach (split(/\_\_\_\&\&\&\_\_\_/,$text)) {
171: if ($_) {
172: my ($courseid,$start,$end,@msg)=split(/\@/,$_);
173: my $msg=join('@',@msg);
174: my $fullmsg=$ENV{'course.'.$courseid.'.description'}.
175: ', '.&Apache::lonlocal::locallocaltime($start);
176: if ($start!=$end) {
177: $fullmsg.=' - '.&Apache::lonlocal::locallocaltime($end);
178: }
179: $msg=~s/INTERNAL\://gs;
180: $fullmsg.=': '.$msg;
181: $fullmsg=&HTML::Entities::encode($fullmsg,'<>&"\'');
182: $fullmsg=~s/&/\\&/g;
183: $output.='<a href="javascript:alert('."'$fullmsg'".')">'.
184: substr($msg,0,40).'...</a><br />';
185: }
186: }
187: return $output;
188: }
189:
190: sub listcell {
191: my ($text)=@_;
192: my $output='';
193: foreach (split(/\_\_\_\&\&\&\_\_\_/,$text)) {
194: if ($_) {
195: my ($courseid,$start,$end,@msg)=split(/\@/,$_);
196: my $msg=join('@',@msg);
197: $msg=~s/INTERNAL\://gs;
198: my $fullmsg=&Apache::lonlocal::locallocaltime($start);
199: if ($start!=$end) {
200: $fullmsg.=&mt(' to ').
201: &Apache::lonlocal::locallocaltime($end);
202: }
203: $fullmsg.=':<br /><b>'.
204: $msg.'</b>';
205: $output.='<li>'.$fullmsg.'</li>';
206: }
207: }
208: return $output;
209: }
210:
211: sub nextday {
212: my %th=@_;
213: $th{'day'}++;
214: return (&Apache::loncommon::maketime(%th),$th{'month'});
215: }
216:
217: sub showday {
218: my ($tk,$mode,%allcal)=@_;
219: my %th=&Apache::loncommon::timehash($tk);
220: my ($nextday,$nextmonth)=&nextday(%th);
221: my $outp='';
222: if ($mode) {
223: my $oneday=24*3600;
224: $tk-=$oneday;
225: $nextday+=$oneday;
226: }
227: foreach (keys %allcal) {
228: my ($course,$startdate,$enddate)=($_=~/^(\w+)\@(\d+)\_(\d+)$/);
229: if (($startdate<$nextday) && ($enddate>$tk)) {
230: $outp.='___&&&___'.$course.'@'.$startdate.'@'.$enddate.'@'.
231: $allcal{$_};
232: }
233: }
234: unless ($mode) {
235: return ($nextday,$nextmonth,&normalcell(
236: $th{'day'},$th{'month'},$th{'year'},$outp));
237: } elsif ($outp) {
238: if ($mode==1) {
239: return '<br />'.&plaincell($outp);
240: } else {
241: return '<ul>'.&listcell($outp).'</ul>';
242: }
243: } else {
244: return '';
245: }
246: }
247:
248: sub tfont {
249: my $text=shift;
250: if ($ENV{'form.pickdate'} eq 'yes') {
251: return '<font size="1">'.$text.'</font>';
252: } else {
253: return $text;
254: }
255: }
256:
257: sub picklink {
258: my ($text,$day,$month,$year)=@_;
259: if ($ENV{'form.pickdate'} eq 'yes') {
260: return '<a href="javascript:dialin('.$day.','.$month.','.$year.')">'.
261: $text.'</a>';
262: } else {
263: return $text;
264: }
265: }
266:
267: sub dialscript {
268: return (<<ENDDIA);
269: <script language="Javascript">
270: function dialin(day,month,year) {
271: opener.document.$ENV{'form.formname'}.$ENV{'form.element'}\_year.value=year;
272: var slct=opener.document.$ENV{'form.formname'}.$ENV{'form.element'}\_month;
273: var i;
274: for (i=0;i<slct.length;i++) {
275: if (slct.options[i].value==month) { slct.selectedIndex=i; }
276: }
277: opener.document.$ENV{'form.formname'}.$ENV{'form.element'}\_day.value=day;
278: opener.$ENV{'form.element'}\_checkday();
279: self.close();
280: }
281: </script>
282: ENDDIA
283: }
284:
285: sub handler {
286: my $r = shift;
287: &Apache::loncommon::content_type($r,'text/html');
288: $r->send_http_header;
289: return OK if $r->header_only;
290:
291: # ---------------------------------------------------------- Get time right now
292: my $today=time;
293: %todayhash=&Apache::loncommon::timehash($today);
294: # ----------------------------------------------------------------- Check marks
295: %showedcheck=();
296: undef %showedcheck;
297: # ---------------------------------------------------------- Get month and year
298: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
299: ['month','year','pickdate','formname','element']);
300: # --------------------------------------------------- Decide what month to show
301: my $year=$todayhash{'year'};
302: if ($ENV{'form.year'}) { $year=$ENV{'form.year'}; }
303: my $month=$todayhash{'month'};
304: if ($ENV{'form.month'}) { $month=$ENV{'form.month'}; }
305:
306: # ---------------------------------------------- See if we are in pickdate mode
307: my $pickdatemode=($ENV{'form.pickdate'} eq 'yes');
308: my $pickinfo='&pickdate=yes&formname='.$ENV{'form.formname'}.
309: '&element='.$ENV{'form.element'};
310: # --------------------------------------------- Find out first day of the month
311:
312: my %firstday=&Apache::loncommon::timehash(
313: &Apache::loncommon::maketime( 'day' => 1, 'month'=> $month,
314: 'year' => $year, 'hours' => 0,
315: 'minutes' => 0, 'seconds' => 0,
316: 'dlsav' => -1 ));
317: my $weekday=$firstday{'weekday'};
318: # ------------------------------------------------------------ Print the screen
319:
320: $r->print(<<ENDDOCUMENT);
321: <html>
322: <head>
323: <title>The LearningOnline Network with CAPA</title>
324: <script>
325:
326: function trysubmit() {
327: document.anno.action.value="new";
328: document.anno.submit();
329: }
330:
331: function removesub() {
332: document.anno.action.value="del";
333: document.anno.submit();
334: }
335: </script>
336: </head>
337: ENDDOCUMENT
338: if ($pickdatemode) {
339: # no big header in pickdate mode
340: $r->print(&Apache::loncommon::bodytag("Pick a Date",'','',1).
341: &dialscript().
342: '<font size="1">');
343: } else {
344: $r->print(&Apache::loncommon::bodytag("Announcements and Calendar"));
345: }
346: # does this user have privileges to post, etc?
347: my $allowed=0;
348: if ($ENV{'request.course.id'}) {
349: $allowed=&Apache::lonnet::allowed('srm',$ENV{'request.course.id'});
350: }
351: # does this user have privileges to post to servers?
352: my $serverpost=0;
353: if ($ENV{'request.role.domain'}) {
354: $serverpost=&Apache::lonnet::allowed('psa',
355: $ENV{'request.role.domain'});
356: } else {
357: $serverpost=&Apache::lonnet::allowed('psa','/');
358: }
359: # -------------------------------- BUT: do no fancy stuff when in pickdate mode
360: if ($pickdatemode) {
361: $serverpost=0;
362: $allowed=0;
363: }
364: # ------------------------------------------------------------ Process commands
365: if ($serverpost) {
366: if ($ENV{'form.serveraction'}) {
367: foreach (keys %ENV) {
368: if ($_=~/^form\.postto\_(\w+)/) {
369: $r->print(
370: '<br />Posting '.$1.': '.&Apache::lonnet::postannounce
371: ($1,$ENV{'form.serverannnounce'}));
372: }
373: }
374: }
375: $r->print(<<SERVERANNOUNCE);
376: <form name="serveranno" method="post">
377: <h3>Post Server Announcements</h3>
378: Post announcements to the system login and roles screen<br />
379: <i>(leave blank to delete announcement)</i><br />
380: <textarea name="serverannnounce" cols="60" rows="5"></textarea><br />
381: Check machines:<br />
382: SERVERANNOUNCE
383: # list servers
384: foreach (sort keys %Apache::lonnet::hostname) {
385: if (&Apache::lonnet::allowed('psa',$Apache::lonnet::hostdom{$_})) {
386: $r->print ('<br /><input type="checkbox" name="postto_'.$_.'" /> '.
387: $_.' <tt>'.$Apache::lonnet::hostname{$_}.'</tt> '.
388: '<a href="http://'.$Apache::lonnet::hostname{$_}.
389: '/announcement.txt" target="annowin">current</a>');
390: }
391: }
392: $r->print(
393: '<br /><input type="submit" name="serveraction" value="Post"></form><hr />');
394: }
395: if ($allowed) {
396: my $coursenum=$ENV{'course.'.$ENV{'request.course.id'}.'.num'};
397: my $coursedom=$ENV{'course.'.$ENV{'request.course.id'}.'.domain'};
398: # ----------------------------------------------------- Store new submitted one
399: if ($ENV{'form.action'} eq 'new') {
400: my $startdate =
401: &Apache::lonhtmlcommon::get_date_from_form('startdate');
402: my $enddate =
403: &Apache::lonhtmlcommon::get_date_from_form('enddate');
404: unless ($startdate=~/^\d+$/) { $startdate=time; }
405: unless ($enddate=~/^\d+$/) { $enddate=$startdate+1; }
406: if ($startdate>$enddate) {
407: my $buffer=$startdate;
408: $startdate=$enddate;
409: $enddate=$buffer;
410: }
411: &Apache::lonnet::put('calendar',{
412: $startdate.'_'.$enddate =>
413: $ENV{'form.msg'} },$coursedom,$coursenum);
414: }
415: # ---------------------------------------------------------------- Remove items
416: if ($ENV{'form.action'} eq 'del') {
417: my @delwhich=();
418: foreach (keys %ENV) {
419: if ($_=~/^form\.remove\_(.+)$/) {
420: push(@delwhich,$1);
421: }
422: }
423: &Apache::lonnet::del('calendar',\@delwhich,$coursedom,$coursenum);
424: }
425: # -------------------------------------------------------- Form to post new one
426: my %tomorrowhash=%todayhash;
427: $tomorrowhash{'day'}++;
428: my $tomorrow=&Apache::loncommon::maketime(%tomorrowhash);
429:
430: &editfield($r,$today,$tomorrow,'');
431: }
432: # ----------------------------------------------------- Summarize all calendars
433: my %allcal=();
434: foreach (&Apache::loncommon::findallcourses()) {
435: %allcal=(%allcal,&readcalendar($_));
436: }
437:
438: # ------------------------------- Initialize table and forward backward buttons
439: my ($pm,$py,$fm,$fy)=($month-1,$year,$month+1,$year);
440: if ($pm<1) { ($pm,$py)=(12,$year-1); }
441: if ($fm>12){ ($fm,$fy)=(1,$year+1); }
442:
443: $r->print('<h1>'.('',&mt('January'),&mt('February'),&mt('March'),
444: &mt('April'),&mt('May'),
445: &mt('June'),&mt('July'),&mt('August'),
446: &mt('September'),&mt('October'),
447: &mt('November'),&mt('December'))[$month].' '.
448: $year.'</h1>');
449: # Reached the end of times, give up
450: if (($year<1970) || ($year>2037)) {
451: $r->print('<h3>No calendar available for this date.</h3>'.
452: '<a href="/adm/announcements?month='.$todayhash{'month'}.
453: '&year='.$todayhash{'year'}.'">Current Month</a></body></html>');
454: return OK;
455: }
456: $r->print(
457: '<a href="/adm/announcements?month='.$pm.'&year='.$py.
458: ($pickdatemode?$pickinfo:'').'">'.&mt('Previous Month').'</a> '.
459: '<a href="/adm/announcements?month='.$fm.'&year='.$fy.
460: ($pickdatemode?$pickinfo:'').'">'.&mt('Next Month').'</a>'.
461: ' <a href="/adm/announcements?month='.$todayhash{'month'}.
462: '&year='.$todayhash{'year'}.
463: ($pickdatemode?$pickinfo:'').'">'.&mt('Current Month').'</a><p>'.
464: '<table border="2" cols="7" rows="5"><tr><th>'.
465: &tfont(&mt('Sun'))
466: .'</th><th>'.
467: &tfont(&mt('Mon'))
468: .'</th><th>'.
469: &tfont(&mt('Tue'))
470: .'</th><th>'.
471: &tfont(&mt('Wed'))
472: .'</th><th>'.
473: &tfont(&mt('Thu'))
474: .'</th><th>'.
475: &tfont(&mt('Fri'))
476: .'</th><th>'.
477: &tfont(&mt('Sat'))
478: .'</th></tr>');
479:
480: my $tk=&Apache::loncommon::maketime(%firstday);
481: my $outp;
482: my $nm;
483:
484: # ---------------------------------------------------------------- Actual table
485: $r->print('<tr>');
486: for (my $i=0;$i<$weekday;$i++) { $r->print(&emptycell); }
487: for (my $i=$weekday;$i<=6;$i++) {
488: ($tk,$nm,$outp)=&showday($tk,0,%allcal);
489: $r->print($outp);
490: }
491: $r->print('</tr>');
492:
493: for (my $k=0;$k<=4;$k++) {
494: $r->print('<tr>');
495: for (my $i=0;$i<=6;$i++) {
496: ($tk,$nm,$outp)=&showday($tk,0,%allcal);
497: if ($month!=$nm) { $outp=&emptycell; }
498: $r->print($outp);
499: }
500: $r->print('</tr>');
501: }
502: # ------------------------------------------------------------------- End table
503: $r->print('</table>');
504: # ----------------------------------------------------------------- Check marks
505: %showedcheck=();
506: undef %showedcheck;
507: # --------------------------------------------------------------- Remove button
508: if ($allowed) { $r->print('<input type="button" onClick="removesub()" value="Remove Checked Entries">'.
509: &Apache::loncommon::help_open_topic('Calendar_Remove_Announcement').'</form>'); }
510: $r->print('<p>'.
511: '<a href="/adm/announcements?month='.$pm.'&year='.$py.
512: ($pickdatemode?$pickinfo:'').'">'.&mt('Previous Month').'</a> '.
513: '<a href="/adm/announcements?month='.$fm.'&year='.$fy.
514: ($pickdatemode?$pickinfo:'').'">'.&mt('Next Month').'</a>'.
515: ' <a href="/adm/announcements?month='.$todayhash{'month'}.
516: '&year='.$todayhash{'year'}.
517: ($pickdatemode?$pickinfo:'').'">'.&mt('Current Month').'</a></p>'.
518: ($pickdatemode?'</font>':'').
519: '</body></html>');
520: return OK;
521: }
522:
523: 1;
524: __END__
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>