Annotation of loncom/interface/lonnotify.pm, revision 1.11
1.1 raeburn 1: #
2: # Copyright Michigan State University Board of Trustees
3: #
4: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
5: #
6: # LON-CAPA is free software; you can redistribute it and/or modify
7: # it under the terms of the GNU General Public License as published by
8: # the Free Software Foundation; either version 2 of the License, or
9: # (at your option) any later version.
10: #
11: # LON-CAPA is distributed in the hope that it will be useful,
12: # but WITHOUT ANY WARRANTY; without even the implied warranty of
13: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14: # GNU General Public License for more details.
15: #
16: # You should have received a copy of the GNU General Public License
17: # along with LON-CAPA; if not, write to the Free Software
18: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19: #
20: # /home/httpd/html/adm/gpl.txt
21: #
22: # http://www.lon-capa.org/
23: #
24:
25: package Apache::lonnotify;
26:
27: use strict;
28: use Apache::lonnet;
29: use Apache::loncommon;
30: use Apache::lonsupportreq;
31: use LONCAPA::Enrollment;
32: use Apache::Constants qw(:common :http);
33: use Apache::lonlocal;
1.2 raeburn 34: use Mail::Send;
35: use HTML::TokeParser;
36: use HTML::Entities;
1.1 raeburn 37:
38: sub handler {
39: my ($r) = @_;
40: &Apache::loncommon::content_type($r,'text/html');
41: $r->send_http_header;
42:
43: if ($r->header_only) {
44: return OK;
45: }
1.2 raeburn 46: my $cdom = $env{'request.role.domain'};
47: unless (&Apache::lonnet::allowed('psa',$cdom)) {
1.1 raeburn 48: # Not allowed to broadcast e-mail system-wide
49: $env{'user.error.msg'}="/adm/notify:psa:0:0:Cannot broadcast e-mail systemwide";
50: return HTTP_NOT_ACCEPTABLE;
51: }
52:
1.2 raeburn 53: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
54: ['command']);
1.1 raeburn 55: my $command = $env{'form.command'};
1.8 raeburn 56: my $origin = $env{'form.origin'};
57:
1.1 raeburn 58: &Apache::lonhtmlcommon::clear_breadcrumbs();
1.2 raeburn 59: my %ltext=&Apache::lonlocal::texthash(
60: 'note' => 'Notification E-mail',
61: );
62: my $function = &Apache::loncommon::get_users_function();
1.8 raeburn 63: my $loadcode;
1.2 raeburn 64: my $tablecolor = &Apache::loncommon::designparm($function.'.tabbg');
1.8 raeburn 65: if ((defined($env{'form.origin'})) && ($command eq 'compose' || $command eq 'pick_target' || $command eq 'pick_display')) {
66: unless ($env{'form.origin'} eq '') {
67: $loadcode = 'javascript:setFormElements(document.'.$env{'form.command'}.')';
68: if (($command eq 'pick_target') && (
69: ($origin eq 'compose') || ($origin eq 'process'))) {
70: if ($env{'form.coursepick'} eq 'category') {
71: $loadcode .= ';javascript:setCourseCat(document.'.$env{'form.command'}.')';
72: }
73: }
74: }
75: }
76: my $loaditems = ' onLoad="'.$loadcode.'" ';
77: my $bodytag = &Apache::loncommon::bodytag('Broadcast e-mail to users',$function,$loaditems);
1.2 raeburn 78: my $html=&Apache::lonxml::xmlbegin();
1.1 raeburn 79: &Apache::lonhtmlcommon::add_breadcrumb
80: ({href=>'/adm/notify',
1.2 raeburn 81: text=>"Broadcast E-mail"});
1.1 raeburn 82: if ($command eq 'process') {
1.8 raeburn 83: &print_request_receipt($r,$command,$cdom,$tablecolor,$bodytag,$html,\%ltext);
1.1 raeburn 84: } elsif ($command eq 'compose') {
1.8 raeburn 85: &print_composition_form($r,$command,$cdom,$tablecolor,$bodytag,$html,\%ltext);
1.2 raeburn 86: } elsif ($command eq 'pick_target') {
1.8 raeburn 87: &print_selection_form($r,$command,$cdom,$tablecolor,$bodytag,$html,\%ltext);
1.2 raeburn 88: } elsif ($command eq 'pick_display') {
1.8 raeburn 89: &print_display_option_form($r,$command,$cdom,$tablecolor,$bodytag,$html,\%ltext);
1.2 raeburn 90: } elsif ($command eq 'display') {
1.8 raeburn 91: &print_display($r,$command,$cdom,$tablecolor,$bodytag,$html,\%ltext);
1.1 raeburn 92: } else {
1.8 raeburn 93: &print_front_page($r,'front',$cdom,$tablecolor,$bodytag,$html,\%ltext);
1.1 raeburn 94: }
95: return OK;
96: }
97:
1.2 raeburn 98: sub print_front_page {
1.8 raeburn 99: my ($r,$formname,$cdom,$tablecolor,$bodytag,$html,$ltext) = @_;
1.2 raeburn 100: my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs
101: (undef,'Broadcast e-mail to Domain','Broadcast_system_email');
102: my $jscript = qq|
103: function next_page(caller) {
104: if (caller == 'view') {
105: document.front.command.value="pick_display"
106: }
107: else {
108: document.front.command.value="pick_target"
109: }
110: document.front.submit()
111: }
112: |;
113: my %lt=&Apache::lonlocal::texthash(
114: 'note' => 'Notification E-mail',
115: );
116: my $output = <<"ENDONE";
117: $html
118: <head>
119: <title>LON-CAPA $lt{'note'}</title>
120: <script type"text/javascript">
121: $jscript
122: </script>
123: </head>
124: $bodytag
125: $breadcrumbs
126: <br />
127: ENDONE
1.8 raeburn 128: $output .= '<form name="'.$formname.'" method="post">'.
1.2 raeburn 129: '<input type="hidden" name="command" />';
130: $output .= &Apache::lonhtmlcommon::start_pick_box();
131: $output .= '<table cellspacing="8" cellpadding="8">'.
132: '<tr><td><a href="javascript:next_page('."'new'".')">'.
133: 'Send a new e-mail message to selected users from this domain</a></td></tr><tr>'.
134: '<td><a href="javascript:next_page('."'view'".')">'.
135: 'Display e-mail sent by Domain Coordinators in this domain'.
136: '</a></td></tr></table>';
137: $output .= &Apache::lonhtmlcommon::end_pick_box();
138: $output .= qq(
139: </form>
140: </body>
141: </html>);
142: $r->print($output);
143: return;
144: }
145:
146: sub print_display_option_form {
1.8 raeburn 147: my ($r,$formname,$cdom,$tablecolor,$bodytag,$html,$ltext) = @_;
1.2 raeburn 148: &Apache::lonhtmlcommon::add_breadcrumb
149: ({text=>"Display options"});
150: my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs
151: (undef,'Broadcast e-mail display options','Broadcast_system_email');
152: my $table_width = '';
153: my $col_width = '200';
154: my $cmd = 'display';
155: my $submit_text = 'Display e-mail';
156: my @roles = ('dc');
157: my $now = time;
158: my %lt=&Apache::lonlocal::texthash(
159: 'note' => 'Notification E-mail',
160: );
161: my $startdateform = &Apache::lonhtmlcommon::date_setter($formname,
162: 'startdate',
163: $now);
164: my $enddateform = &Apache::lonhtmlcommon::date_setter($formname,
165: 'enddate',
166: $now);
1.8 raeburn 167: my %elements = (
168: startdate_month => 'selectbox',
169: startdate_hour => 'selectbox',
170: enddate_month => 'selectbox',
171: enddate_hour => 'selectbox',
172: startdate_day => 'text',
173: startdate_year => 'text',
174: startdate_minute => 'text',
175: startdate_second => 'text',
176: enddate_day => 'text',
177: enddate_year => 'text',
178: enddate_minute => 'text',
179: enddate_second => 'text',
180: sender => 'checkbox',
181: );
182: my $jscript = &Apache::lonhtmlcommon::set_form_elements(\%elements);
1.2 raeburn 183: my $output = <<"ENDONE";
184: $html
185: <head>
186: <title>LON-CAPA $lt{'note'}</title>
187: <script type"text/javascript">
188: $jscript
189: </script>
190: </head>
191: $bodytag
192: $breadcrumbs
193: <br />
194: <form method="post" name="$formname">
195: ENDONE
196: $output .= &Apache::lonhtmlcommon::start_pick_box($table_width);
197: $output .= &Apache::lonhtmlcommon::row_title($col_width,$tablecolor,&mt('Date range'));
198: $output .= '<td><table><tr><td>Earliest to display: </td><td>'.
199: $startdateform.'</td></tr>';
200: $output .= '<tr><td>Latest to display: </td><td>'.$enddateform.
201: '</td></tr></table></td>';
202: $output .= &Apache::lonhtmlcommon::row_closure();
203: $output .= &Apache::lonhtmlcommon::row_title($col_width,$tablecolor,&mt('Choose sender(s)'));
1.4 raeburn 204: my %personnel = &Apache::lonnet::get_domain_roles($cdom,\@roles);
1.2 raeburn 205: $output .= '<td>';
1.4 raeburn 206: my @domcc = ();
207: foreach my $server (keys %personnel) {
208: foreach my $user (sort(keys %{$personnel{$server}})) {
209: my ($trole,$uname,$udom,$runame,$rudom,$rsec) = split(/:/,$user);
210: unless (grep/^$uname:$udom$/,@domcc) {
211: my %userinfo = &Apache::lonnet::get('environment',['lastname','firstname'],$udom,$uname);
212: $output .= '<input type="checkbox" name="sender" value="'.$uname.':'.$udom.'" /> '.$userinfo{firstname}.' '.$userinfo{lastname}.' ('.$uname.':'.$udom.')';
213: push (@domcc,$uname.':'.$udom);
214: }
1.2 raeburn 215: }
216: }
217: $output .= '</td>';
218: $output .= &Apache::lonhtmlcommon::row_closure();
219: $output .= &Apache::lonhtmlcommon::submit_row($col_width,$tablecolor,&mt('Submit'),$cmd,$submit_text);
220: $output .= &Apache::lonhtmlcommon::end_pick_box();
221: $output .= qq(
222: <input type="hidden" name="sortby" value="date" />
223: </form>
224: </body>
225: </html>);
226: $r->print($output);
227: return;
228: }
229:
230: sub print_display {
1.8 raeburn 231: my ($r,$formname,$cdom,$tablecolor,$bodytag,$html,$ltext) = @_;
1.2 raeburn 232: &Apache::lonhtmlcommon::add_breadcrumb
1.8 raeburn 233: ({href=>"javascript:goBack('pick_display')",
1.2 raeburn 234: text=>"Display options"},
235: {text=>"E-mail display"});
236: my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs
237: (undef,'Display Broadcast e-mail','Broadcast_system_email');
238: my $table_width = '';
239: my $col_width = '200';
240: my $rowColor1 = "#ffffff";
241: my $rowColor2 = "#eeeeee";
242: my $rowColor;
243: my $msgcount = 0;
244: my $start = &Apache::lonhtmlcommon::get_date_from_form('startdate');
245: my $end = &Apache::lonhtmlcommon::get_date_from_form('enddate');
246: my @senders = &Apache::loncommon::get_env_multiple('form.sender');
1.6 albertel 247: my %sentmail = &Apache::lonnet::dcmaildump($cdom,$start,$end,\@senders);
1.2 raeburn 248: my %dcmail = ();
249: my %Sortby = ();
250: my $jscript = <<"ENDSCRIPT";
251: function changeSort(caller) {
1.8 raeburn 252: document.$formname.command.value = '$formname';
1.2 raeburn 253: document.$formname.sortby.value = caller;
1.8 raeburn 254: document.$formname.submit();
255: }
256: function goBack(target) {
257: document.$formname.command.value = target;
258: document.$formname.submit();
1.2 raeburn 259: }
1.8 raeburn 260:
1.2 raeburn 261: ENDSCRIPT
262: my $output = <<"ENDONE";
263: $html
264: <head>
265: <title>LON-CAPA $$ltext{'note'}</title>
266: <script type"text/javascript">
267: $jscript
268: </script>
269: </head>
270: $bodytag
271: $breadcrumbs
272: <br />
273: <form method="post" name="$formname">
274: ENDONE
275:
1.9 raeburn 276: foreach my $msgid (keys(%sentmail)) {
1.10 raeburn 277: my %content = &Apache::lonmsg::unpackagemsg($sentmail{$msgid});
1.9 raeburn 278: $msgcount ++;
279: %{$dcmail{$msgid}} = ();
280: foreach my $item (keys(%content)) {
1.10 raeburn 281: if ($item eq 'recipient') {
282: foreach my $user (keys(%{$content{recipient}})) {
283: $dcmail{$msgid}{recipient}{$user} = $content{recipient}{$user};
1.2 raeburn 284: }
285: } else {
1.9 raeburn 286: $dcmail{$msgid}{$item} = $content{$item};
1.2 raeburn 287: }
288: }
289: }
290: $output .= &Apache::lonhtmlcommon::start_pick_box();
291: if ($msgcount > 0) {
292: my $rowNum = 0;
293: $output .= '<tr><td><table cellpadding="4" cellspacing="2" width="100%">
294: <tr bgcolor="'.$tablecolor.'" align="center">
295: <td><b><a href="javascript:changeSort('."'date'".')">Date</a></b></td>
296: <td><b><a href="javascript:changeSort('."'subject'".')">Subject</a></b></td>
297: <td><b><a href="javascript:changeSort('."'sender'".')">Sender</a></b></td>
298: <td><b><a href="javascript:changeSort('."'message'".')">Message</a></b></td>
299: <td><b><a href="javascript:changeSort('."'recipients'".')">Recipients</a></b></td>
300: </tr>';
301: if (($env{'form.sortby'} eq 'date') || ($env{'form.sortby'} eq '') || (!defined($env{'form.sortby'})) || (($env{'form.sortby'} eq 'sender') && (@senders <= 1))) {
302: foreach my $msgid (sort(keys(%dcmail))) {
303: if ($rowNum %2 == 1) {
304: $rowColor = $rowColor1;
305: } else {
306: $rowColor = $rowColor2;
307: }
308: my $recipients = '';
1.11 ! raeburn 309: my ($date,$subj,$sname,$sdom) =
! 310: &Apache::lonmsg::unpackmsgid($msgid,undef,1);
! 311: $subj = &Apache::lonnet::escape($subj);
1.2 raeburn 312: $date = &Apache::lonlocal::locallocaltime($date);
1.10 raeburn 313: foreach my $user (sort(keys(%{$dcmail{$msgid}{recipient}}))) {
314: $recipients .= $dcmail{$msgid}{recipient}{$user}.', ';
1.2 raeburn 315: }
316: $recipients =~ s/,\s$//;
1.5 raeburn 317: $output .= '<tr bgcolor="'.$rowColor.'"><td><small>'.$date.'</small></td><td><small>'.&cr_to_br($dcmail{$msgid}{subject}).'</small></td><td><small>'.$sname.':'.$sdom.'</small></td><td><small>'.&cr_to_br($dcmail{$msgid}{message}).'</small></td><td><small>'.$recipients.'</small></td></tr>'."\n";
1.2 raeburn 318: $rowNum ++;
319: }
320: } else {
321: foreach my $msgid (sort(keys(%dcmail))) {
1.11 ! raeburn 322: my ($date,$subj,$sname,$sdom) =
! 323: &Apache::lonmsg::unpackmsgid($msgid,undef,1);
! 324: $subj = &Apache::lonnet::escape($subj);
1.2 raeburn 325: if ($env{'form.sortby'} eq 'subject') {
326: push @{$Sortby{$dcmail{$msgid}{subject}}},$msgid;
327: } elsif ($env{'form.sortby'} eq 'message') {
328: push @{$Sortby{$dcmail{$msgid}{message}}},$msgid;
329: } elsif ($env{'form.sortby'} eq 'recipients') {
330: my $recipients ='';
1.10 raeburn 331: foreach my $user (sort(keys(%{$dcmail{$msgid}{recipient}}))) {
332: $recipients .= $dcmail{$msgid}{recipient}{$user}.', ';
1.2 raeburn 333: }
334: $recipients =~ s/,\s$//;
335: push @{$Sortby{$recipients}},$msgid;
336: } elsif ($env{'form.sortby'} eq 'sender') {
337: if (@senders > 1) {
338: push @{$Sortby{$sname.':'.$sdom}},$msgid;
339: }
340: }
341: }
342: foreach my $key (sort(keys(%Sortby))) {
343: foreach my $msgid (@{$Sortby{$key}}) {
344: if ($rowNum %2 == 1) {
345: $rowColor = $rowColor1;
346: } else {
347: $rowColor = $rowColor2;
348: }
349: my $recipients = '';
350: if ($env{'form.sortby'} eq 'recipients') {
351: $recipients = $key;
352: } else {
1.10 raeburn 353: foreach my $user (sort(keys(%{$dcmail{$msgid}{recipient}}))) {
354: $recipients .= $dcmail{$msgid}{recipient}{$user}.', ';
1.2 raeburn 355: }
356: $recipients =~ s/,\s$//;
357: }
1.11 ! raeburn 358: my ($date,$subj,$sname,$sdom) =
! 359: &Apache::lonmsg::unpackmsgid($msgid,undef,1);
! 360: $subj = &Apache::lonnet::escape($subj);
1.2 raeburn 361: $date = &Apache::lonlocal::locallocaltime($date);
1.5 raeburn 362: $output .= '<tr bgcolor="'.$rowColor.'"><td><small>'.$date.'</small></td><td><small>'.&cr_to_br($dcmail{$msgid}{subject}).'</small></td><td><small>'.$sname.':'.$sdom.'</small></td><td><small>'.&cr_to_br($dcmail{$msgid}{message}).'</small></td><td><small>'.$recipients.'</small></td></tr>'."\n";
1.2 raeburn 363: $rowNum ++;
364: }
365: }
366: }
367: $output .= '</table></td></tr>';
368: } else {
369: $output .= '<tr bgcolor="#ffffff"><td> </td><td><br><center><i><b><small> No mail sent matching supplied criteria </small><br><br></b></i></td><td> </td></tr>';
370: }
371: $output .= &Apache::lonhtmlcommon::end_pick_box();
1.8 raeburn 372: $output .= &Apache::lonhtmlcommon::echo_form_input(['sortby','command','origin']);
373: my $curr_sortby;
374: if (defined($env{'form.sortby'})) {
375: $curr_sortby = $env{'form.sortby'};
376: } else {
377: $curr_sortby = 'date';
378: }
379: $output .= qq(<input type="hidden" name="origin" value="$formname" />\n);
380: $output .= qq(<input type="hidden" name="command" />\n);
381: $output .= qq(<input type="hidden" name="sortby" value="$curr_sortby" />\n);
1.2 raeburn 382: $output .= qq(
383: </form>
1.10 raeburn 384: </body
1.2 raeburn 385: </html>);
386: $r->print($output);
387: return;
388: }
389:
1.1 raeburn 390: sub print_selection_form {
1.8 raeburn 391: my ($r,$formname,$cdom,$tablecolor,$bodytag,$html,$ltext) = @_;
1.1 raeburn 392: my %coursecodes = ();
393: my %codes = ();
394: my @codetitles = ();
395: my %cat_titles = ();
396: my %cat_order = ();
397: my %idlist = ();
398: my %idnums = ();
399: my %idlist_titles = ();
400: my $caller = 'global';
401: my $totcodes = 0;
402: my $format_reply;
403: my $jscript = '';
1.2 raeburn 404: my $table_width = '100%';
405: my $col_width = '200';
406: my %lt=&Apache::lonlocal::texthash(
407: 'note' => 'Notification E-mail',
408: 'buil' => 'Building valid e-mail address from username, if missing from preferences:',
409: 'kerb' => 'Kerberos: enter default for each realm used in the domain, with comma separation of entries',
410: 'infs' => 'Internal, Filesystem and Local authentication: enter single default.',
411: 'comp' => 'Compose Message'
412: );
413: &Apache::lonhtmlcommon::add_breadcrumb
414: ({text=>"Select Audience"});
415:
1.1 raeburn 416: $totcodes = &Apache::lonsupportreq::retrieve_instcodes(\%coursecodes,$cdom,$totcodes);
417: if ($totcodes > 0) {
418: $format_reply = &Apache::lonnet::auto_instcode_format($caller,$cdom,\%coursecodes,\%codes,\@codetitles,\%cat_titles,\%cat_order);
419: if ($format_reply eq 'ok') {
420: my $numtypes = @codetitles;
421: &Apache::lonsupportreq::build_code_selections(\%codes,\@codetitles,\%cat_titles,\%cat_order,\%idlist,\%idnums,\%idlist_titles);
1.2 raeburn 422: &Apache::lonsupportreq::javascript_code_selections($formname,$numtypes,\%cat_titles,\$jscript,\%idlist,\%idnums,\%idlist_titles,\@codetitles);
1.1 raeburn 423: }
424: }
425:
426: my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs
1.2 raeburn 427: (undef,'Choose e-mail audience','Broadcast_system_email');
1.3 albertel 428: my $cb_jscript = &Apache::loncommon::coursebrowser_javascript($cdom);
1.8 raeburn 429:
430: my %elements = (
431: roles => 'selectbox',
432: types => 'selectbox',
433: Year => 'selectbox',
434: coursepick => 'radio',
435: coursetotal => 'text',
436: courselist => 'text',
437: internal => 'text',
438: krb4 => 'text',
439: krb5 => 'text',
440: local => 'text',
441: unix => 'text',
442: );
443: $jscript .= &Apache::lonhtmlcommon::set_form_elements(\%elements);
444: if ($env{'form.coursepick'} eq 'category') {
445: $jscript .= qq|
446: function setCourseCat(formname) {
447: if (formname.Year.options[formname.Year.selectedIndex].value == -1) {
448: return;
449: }
450: courseSet('Year');
451: for (var j=0; j<formname.Semester.length; j++) {
452: if (formname.Semester.options[j].value == "$env{'form.Semester'}") {
453: formname.Semester.options[j].selected = true;
454: }
455: }
456: if (formname.Semester.options[formname.Semester.selectedIndex].value == -1) {
457: return;
458: }
459: courseSet('Semester');
460: for (var j=0; j<formname.Department.length; j++) {
461: if (formname.Department.options[j].value == "$env{'form.Department'}") {
462: formname.Department.options[j].selected = true;
463: }
464: }
465: if (formname.Department.options[formname.Department.selectedIndex].value == -1) {
466: return;
467: }
468: courseSet('Department');
469: for (var j=0; j<formname.Number.length; j++) {
470: if (formname.Number.options[j].value == "$env{'form.Number'}") {
471: formname.Number.options[j].selected = true;
472: }
473: }
474: }
475: |;
476: }
1.2 raeburn 477: my $output = <<"ENDONE";
1.1 raeburn 478: $html
479: <head>
1.2 raeburn 480: <title>LON-CAPA $lt{'note'}</title>
1.1 raeburn 481: <script type"text/javascript">
482: $jscript
483: </script>
1.2 raeburn 484: $cb_jscript
1.1 raeburn 485: </head>
486: $bodytag
487: $breadcrumbs
488: <br />
1.2 raeburn 489: <form method="post" name="$formname">
1.1 raeburn 490: ENDONE
1.2 raeburn 491: $output .= &Apache::lonhtmlcommon::start_pick_box($table_width);
1.8 raeburn 492: my @roles = ('ow','cc','in','ta','ep','st','cr');
1.2 raeburn 493: my %longtypes = ();
494: my %authtypes = ();
495: &form_elements(\%longtypes,\%authtypes);
496: my $descrip = $lt{'buil'}.'
497: <ul>
498: <li>'.$lt{'kerb'}.'<br />(e.g., MSU.EDU=msu.edu, MSUE.EDU=msue.msu.edu).</li>
499: <li>'.$lt{'infs'}.'</li>
500: </ul>'."\n";
501: my $submit_text = $lt{'comp'};
502: my $cmd = 'compose';
503: $output .= &Apache::lonhtmlcommon::role_select_row(\@roles,$col_width,$tablecolor,'Roles');
504: $output .= &Apache::lonhtmlcommon::course_select_row($col_width,$tablecolor,'Courses',$formname,$totcodes,\@codetitles,\%idlist,\%idlist_titles);
505: $output .= &Apache::lonhtmlcommon::status_select_row(\%longtypes,$col_width,$tablecolor,&mt('Access status'));
506: $output .= &Apache::lonhtmlcommon::email_default_row(\%authtypes,$col_width,$tablecolor,&mt('Username -> Email conversion'),$descrip);
507: $output .= &Apache::lonhtmlcommon::submit_row($col_width,$tablecolor,&mt('Submit'),$cmd,$submit_text);
508: $output .= &Apache::lonhtmlcommon::end_pick_box();
509: $output .= qq(
1.1 raeburn 510: </form>
511: </body>
1.2 raeburn 512: </html>);
513: $r->print($output);
1.1 raeburn 514: return;
515: }
516:
517: sub print_composition_form {
1.8 raeburn 518: my ($r,$formname,$cdom,$tablecolor,$bodytag,$html,$ltext) = @_;
1.1 raeburn 519: &Apache::lonhtmlcommon::add_breadcrumb
1.8 raeburn 520: ({href=>"javascript:goBack('pick_target')",
1.2 raeburn 521: text=>"Select Audience"},
522: {text=>"Compose Message"});
523: my $jscript = &Apache::loncommon::check_uncheck_jscript();
1.8 raeburn 524: $jscript .= qq|
525: function goBack(target) {
526: document.$formname.command.value = target;
527: document.$formname.submit();
528: }
529: |;
1.1 raeburn 530: my $breadcrumbs = (&Apache::lonhtmlcommon::breadcrumbs
531: (undef,'Broadcast e-mail to users','Broadcast_system_email'));
532:
1.2 raeburn 533: my %lt=&Apache::lonlocal::texthash(
534: 'note' => 'Notification E-mail',
535: 'nore' => 'No recipients identified',
536: 'emad' => 'e-mail address',
537: );
1.8 raeburn 538: my %elements = (
539: subject => 'text',
540: message => 'text',
541: sender => 'text',
542: recipient => 'checkbox',
543: );
544: $jscript .= &Apache::lonhtmlcommon::set_form_elements(\%elements);
545:
1.1 raeburn 546: $r->print(<<ENDONE);
547: $html
548: <head>
1.2 raeburn 549: <title>LON-CAPA $lt{'note'}</title>
1.7 raeburn 550: <script type="text/javascript">
1.1 raeburn 551: $jscript
552: </script>
553: </head>
554: $bodytag $breadcrumbs
555: <br />
556: ENDONE
1.2 raeburn 557: my $coursefilter = $env{'form.coursepick'};
558: my %courses = ();
559: if ($coursefilter eq 'all') {
560: %courses = &Apache::lonnet::courseiddump($cdom,'.','.','.','.','.');
561: } elsif ($coursefilter eq 'category') {
562: my $instcode = '';
563: my @cats = ('Semester','Year','Department','Number');
564: foreach my $category (@cats) {
565: if (defined($env{'form.'.$category})) {
566: unless ($env{'form.'.$category} eq '-1') {
567: $instcode .= $env{'form.'.$category};
568: }
1.1 raeburn 569: }
570: }
1.2 raeburn 571: if ($instcode eq '') {
572: $instcode = '.';
573: }
574: %courses = &Apache::lonnet::courseiddump($cdom,'.','.',$instcode,'.','.');
575: } elsif ($coursefilter eq 'specific') {
576: if ($env{'form.coursetotal'} > 1) {
577: my @course_ids = split(/&&/,$env{'form.courselist'});
578: foreach (@course_ids) {
579: $courses{$_} = '';
580: }
581: } else {
582: $courses{$env{'form.courselist'}} = '';
583: }
1.1 raeburn 584: }
1.2 raeburn 585:
586: my @types = &Apache::loncommon::get_env_multiple('form.types');
587: my @roles = &Apache::loncommon::get_env_multiple('form.roles');
588:
589: my %longtypes = ();
590: my %authtypes = ();
591: my %email_defaults = ();
592: my $table_width = '100%';
593: my $col_width = '200';
594:
595: &form_elements(\%longtypes,\%authtypes);
1.3 albertel 596: foreach my $auth (keys(%authtypes)) {
1.2 raeburn 597: if (exists($env{'form.'.$auth})) {
598: my $default = $env{'form.'.$auth};
599: $default =~ s/^,+//;
600: $default =~ s/,+$//;
601: if ($auth =~ /^krb/) {
602: %{$email_defaults{$auth}} = ();
603: if ($default =~ /,/) {
604: my @items = split(/,/,$default);
605: foreach my $item (@items) {
606: my ($realm,$value) = split(/=/,$item);
607: $email_defaults{$auth}{$realm} = $value;
608: }
609: } else {
610: my ($realm,$value) = split(/=/,$default);
611: $email_defaults{$auth}{$realm} = $value;
612: }
613: } else {
614: $email_defaults{$auth} = $default;
615: }
616: }
1.1 raeburn 617: }
1.2 raeburn 618:
619: my $sender = &get_user_info($env{'user.name'},%email_defaults);
620:
1.1 raeburn 621: my %recipients = ();
1.2 raeburn 622: my %users = ();
623: my %access = ();
1.8 raeburn 624: my @sections = ();
1.2 raeburn 625: my $totalrecip = 0;
626: my @unmatched = ();
627: foreach my $role (@roles) {
628: %{$users{$role}} = ();
629: }
630: foreach my $type (@types) {
631: $access{$type} = $type;
632: }
633: foreach my $course_id (keys(%courses)) {
634: my ($cdom,$cnum) = split(/_/,$course_id);
1.8 raeburn 635: &Apache::loncommon::get_course_users($cdom,$cnum,\%access,\@roles,\@sections,\%users);
1.2 raeburn 636: }
637: foreach my $role (keys(%users)) {
638: foreach my $user (keys(%{$users{$role}})) {
639: unless (defined($recipients{$user})) {
640: $recipients{$user} = &get_user_info($user,%email_defaults);
641: if ($recipients{$user} eq '') {
642: push @unmatched, $user;
643: } else {
644: $totalrecip ++;
645: }
646: }
647: }
1.1 raeburn 648: }
1.8 raeburn 649: my $output = '<form name="'.$formname.'" method="post">'."\n";
1.2 raeburn 650:
651: if ($totalrecip > 0) {
652: $output .= &Apache::lonhtmlcommon::start_pick_box($table_width);
653: $output .= &Apache::lonhtmlcommon::row_title($col_width,$tablecolor,&mt('Subject'));
654: $output .= ' <td><input type="text" name="subject" size="30" /></td>';
655: $output .= &Apache::lonhtmlcommon::row_closure();
656: $output .= &Apache::lonhtmlcommon::row_title($col_width,$tablecolor,&mt('Message'));
657: $output .= ' <td><textarea name="message" id="message"
658: cols="60" rows="10" wrap="hard"></textarea></td>';
659: $output .= &Apache::lonhtmlcommon::row_closure();
660: $output .= &Apache::lonhtmlcommon::row_title($col_width,$tablecolor,&mt('Recipients'));
661: $output .= '<td><input type="button" value="check all"
662: onclick="javascript:checkAll(document.compose.recipient)" />
663: <input type="button" value="uncheck all"
664: onclick="javascript:uncheckAll(document.compose.recipient)" />
665: <br /><table border="0">';
666: if (keys(%recipients) > 0) {
667: $output .= '<tr><td> </td><td><small><b>username:domain</b></small></td><td> </td><td><small><b>'.$lt{'emad'}.'</b></small></td></tr>';
668: }
669: foreach my $username (sort(keys(%recipients))) {
1.1 raeburn 670: if ($recipients{$username} =~ /\@/) {
671: my $value=&Apache::lonnet::escape($username).':'.&Apache::lonnet::escape($recipients{$username});
1.8 raeburn 672: $output .= '<tr><td><input type="checkbox" name="recipient" value="'.$value.'" /></td><td>'.$username.'</td><td> </td><td>'.$recipients{$username}.'</td></tr>';
1.1 raeburn 673: }
674: }
1.5 raeburn 675: $output .= '</table>';
676: if (@unmatched) {
677: $output .= '<br /><br />'.&mt('Could not determine e-mail addresses for the following users:').'<ul>';
678: foreach my $username (sort @unmatched) {
679: $output .= '<li>'.$username.'</li>';
680: }
681: $output .= '</ul>';
682: }
683: $output .= '</td>';
1.2 raeburn 684: $output .= &Apache::lonhtmlcommon::row_closure();
685: $output .= &Apache::lonhtmlcommon::row_title($col_width,$tablecolor,&mt('Sender e-mail address'));
686: $output .= '<td><input type="text" name="sender" value="'.$sender.'" /></td>';
687: $output .= &Apache::lonhtmlcommon::row_closure();
688: $output .= &Apache::lonhtmlcommon::submit_row($col_width,$tablecolor,&mt('Submit'),'process',&mt('Send Message'));
689: $output .= &Apache::lonhtmlcommon::end_pick_box();
1.1 raeburn 690: } else {
1.8 raeburn 691: $output .= $lt{'nore'}."\n".
692: '<input type="hidden" name="command" value="" />'."\n";
1.1 raeburn 693: }
1.8 raeburn 694: $output .= '<input type="hidden" name="origin" value="'.$formname.'" />'."\n";
695: $output .= &Apache::lonhtmlcommon::echo_form_input(['command','origin','subject','message','recipient','sender'],);
1.2 raeburn 696: $output .= '</form></body></html>';
697: $r->print($output);
1.1 raeburn 698: return;
699: }
700:
701:
702: sub print_request_receipt {
1.8 raeburn 703: my ($r,$formname,$dom,$tablecolor,$bodytag,$html,$ltext) =@_;
1.2 raeburn 704: my @recipients = &Apache::loncommon::get_env_multiple('form.recipient');
1.1 raeburn 705: my $subject = $env{'form.subject'};
706: my $message = $env{'form.message'};
1.2 raeburn 707: my $from = $env{'form.sender'};
708: my $jscript = <<ENDSCRIPT;
1.8 raeburn 709: function goBack(target) {
710: document.$formname.command.value = target;
711: document.$formname.submit();
1.2 raeburn 712: }
713: ENDSCRIPT
714: &Apache::lonhtmlcommon::add_breadcrumb
1.8 raeburn 715: ({href=>"javascript:goBack('pick_target')",
1.2 raeburn 716: text=>"Select audience"});
717: &Apache::lonhtmlcommon::add_breadcrumb
1.8 raeburn 718: ({href=>"javascript:goBack('compose')",
1.2 raeburn 719: text=>"Compose Message"});
720: &Apache::lonhtmlcommon::add_breadcrumb
1.8 raeburn 721: ({href=>"/adm/notify?command=process",
1.2 raeburn 722: text=>"Outcome"});
1.1 raeburn 723: my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs
1.2 raeburn 724: (undef,'E-mail Delivery','Broadcast_system_email');
725: my $output = <<ENDONE;
1.1 raeburn 726: $html
727: <head>
728: <title>LON-CAPA Notification E-mail</title>
1.8 raeburn 729: <script type="text/javascript">
1.1 raeburn 730: $jscript
731: </script>
732: </head>
733: $bodytag
734: $breadcrumbs
1.2 raeburn 735: <br />
1.8 raeburn 736: <form name="$formname" method="post">
1.1 raeburn 737: ENDONE
1.2 raeburn 738: $output .= &Apache::lonhtmlcommon::start_pick_box();
739: my @deliveries = ();
740: &broadcast_email(\@recipients,$subject,$from,$message,\@deliveries);
741: if (@deliveries > 0) {
1.5 raeburn 742: &store_mail($subject,$message,$dom,\@deliveries);
1.2 raeburn 743: $output .= '<tr>
744: <td>
745: <table cellpadding="4" cellspacing="2" width="100%">
746: <tr bgcolor="'.$tablecolor.'" align="center">
747: <td><b>Status</b></td>
748: <td><b>Subject</b></td>
749: <td><b>Message</b></td>
750: <td><b>Recipients</b></td>
751: </tr>
752: <tr bgcolor="#eeeeee">
753: <td valign="middle">Sent</td>
1.5 raeburn 754: <td valign="middle">'.&cr_to_br($subject).'</td>
755: <td valign="middle">'.&cr_to_br($message).'</td>
1.2 raeburn 756: <td>';
757: foreach my $person (@deliveries) {
758: my ($username,$email) = split(/:/,$person);
759: $output .= &Apache::lonnet::unescape($email).' ('.&Apache::lonnet::unescape($username).')<br />'."\n";
760: }
761: $output .= '</td>
762: </tr>
763: </table>
764: </td>
765: </tr>';
766: } else {
767: $output .= 'No mail sent - no recipients identified';
1.1 raeburn 768: }
1.2 raeburn 769: $output .= &Apache::lonhtmlcommon::end_pick_box();
770: $output .= '<br /><a href="/adm/notify">Send another message?</a>'."\n";
1.8 raeburn 771: $output .= '<input type="hidden" name="command" />'."\n".
772: '<input type="hidden" name="origin" value="'.$formname.'" />'."\n";
773: $output .= &Apache::lonhtmlcommon::echo_form_input(['command','origin']);
1.2 raeburn 774: $output .= '
775: </form>
776: </body>
777: </html>';
778: $r->print($output);
1.1 raeburn 779: return;
780: }
781:
1.2 raeburn 782: sub broadcast_email {
783: my ($recipients,$subject,$from,$message,$deliveries,$ltext)=@_;
1.8 raeburn 784: # Should implement staggered delivery for large numbers of recipients?.
1.2 raeburn 785: foreach my $user (@{$recipients}) {
786: my $msg = new Mail::Send;
787: my ($username,$to) = split(/:/,$user);
788: $username = &Apache::lonnet::unescape($username);
789: $to = &Apache::lonnet::unescape($to);
790: $msg->to($to);
791: $msg->subject($subject);
792: $msg->add('From',"$from");
793: if (my $fh = $msg->open()) {
794: print $fh $message;
795: $fh->close;
796: push(@{$deliveries},$user);
797: }
798: }
799: }
800:
801: sub get_user_info {
1.5 raeburn 802: my ($user,%email_defaults) = @_;
1.2 raeburn 803: my ($uname,$udom) = split(/:/,$user);
804: my @emailtypes = ('permanentemail','critnotification','notification');
1.3 albertel 805: my %userinfo = &Apache::lonnet::get('environment',\@emailtypes,$udom,$uname);
1.2 raeburn 806: my $email = '';
807: foreach my $type (@emailtypes) {
808: $email = $userinfo{$type};
809: if ($email =~ /\@/) {
810: last;
811: }
812: }
813: if ($email eq '') {
814: my $authinfo = &Apache::lonnet::queryauthenticate($uname,$udom);
815: my ($authtype,$autharg) = split(/:/,$authinfo);
816: if ($authtype =~ /^krb/) {
817: if (defined($email_defaults{$authtype}{$autharg})) {
818: $email = $uname.'@'.$email_defaults{$authtype}{$autharg};
819: }
820: } else {
1.5 raeburn 821: if ((defined($email_defaults{$authtype})) && ($email_defaults{$authtype} ne '')) {
1.2 raeburn 822: $email = $uname.'@'.$email_defaults{$authtype};
823: }
824: }
825: }
826: return $email;
827: }
828:
829: sub form_elements {
830: my ($longtypes,$authtypes,$ltext) = @_;
831: %{$longtypes} = (
832: active => 'Currently has access',
833: previous => 'Previously had access',
834: future => 'Will have future access',
835: );
836: %{$authtypes} = (
837: krb4 => 'Kerberos 4',
838: krb5 => 'Kerberos 5',
1.5 raeburn 839: internal => 'Internal (LON-CAPA)',
1.2 raeburn 840: unix => 'Filesystem (UNIX)',
841: local => 'Local/Customized',
842: );
843: return;
844: }
845:
846: sub store_mail {
847: my ($subject,$message,$domain,$recipients,$attachmenturl,$ltext) = @_;
1.9 raeburn 848: my $msgid;
1.10 raeburn 849: ($msgid,$message) = &Apache::lonmsg::packagemsg($subject,$message,undef,undef,
850: $attachmenturl,$recipients,undef,undef,'dcmail');
851:
1.9 raeburn 852: # Store in dc email db files on primary library server for domain.
853: my $server = $Apache::lonnet::domain_primary{$domain};
854: if (defined($server)) {
855: unless (&Apache::lonnet::dcmailput($domain,$msgid,$message,$server)
856: eq 'ok') {
857: &Apache::lonnet::logthis('Storage of dc mail failed for domain'.
858: $domain.' for server: '. $server.'. Message ID was '.$msgid);
1.4 raeburn 859: }
1.9 raeburn 860: } else {
861: &Apache::lonnet::logthis('Storage of dc mail failed for domain'.
862: $domain.' as no primary server identified. Message ID was '.$msgid);
1.2 raeburn 863: }
864: }
865:
1.5 raeburn 866: sub cr_to_br {
867: my $incoming = shift;
868: $incoming =~ s/\n/\<br \/\>/g;
869: return $incoming;
870: }
871:
1.1 raeburn 872: 1;
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>