--- loncom/interface/lonnotify.pm 2005/08/02 05:03:10 1.1 +++ loncom/interface/lonnotify.pm 2006/04/10 21:40:08 1.16 @@ -31,6 +31,9 @@ use Apache::lonsupportreq; use LONCAPA::Enrollment; use Apache::Constants qw(:common :http); use Apache::lonlocal; +use Mail::Send; +use HTML::TokeParser; +use HTML::Entities; sub handler { my ($r) = @_; @@ -40,31 +43,337 @@ sub handler { if ($r->header_only) { return OK; } -# my $codedom = $env{'request.role.domain'}; - my $cdom = 'northwood5'; - unless (&Apache::lonnet::allowed('psa',$env{'request.role.domain'})) { + my $cdom = $env{'request.role.domain'}; + unless (&Apache::lonnet::allowed('psa',$cdom)) { # Not allowed to broadcast e-mail system-wide $env{'user.error.msg'}="/adm/notify:psa:0:0:Cannot broadcast e-mail systemwide"; return HTTP_NOT_ACCEPTABLE; } + &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'}, + ['command']); my $command = $env{'form.command'}; + my $origin = $env{'form.origin'}; + &Apache::lonhtmlcommon::clear_breadcrumbs(); + + my $function = &Apache::loncommon::get_users_function(); + my $tablecolor = &Apache::loncommon::designparm($function.'.tabbg'); + &Apache::lonhtmlcommon::add_breadcrumb ({href=>'/adm/notify', - text=>"Broadcast e-mail"}); + text=>"Broadcast E-mail"}); if ($command eq 'process') { - &print_request_receipt($r,$cdom); + &print_request_receipt($r,$command,$cdom,$tablecolor); } elsif ($command eq 'compose') { - &print_composition_form($r,$cdom); + &print_composition_form($r,$command,$cdom,$tablecolor); + } elsif ($command eq 'pick_target') { + &print_selection_form($r,$command,$cdom,$tablecolor); + } elsif ($command eq 'pick_display') { + &print_display_option_form($r,$command,$cdom,$tablecolor); + } elsif ($command eq 'display') { + &print_display($r,$command,$cdom,$tablecolor); } else { - &print_selection_form($r,$cdom); + &print_front_page($r,'front',$cdom,$tablecolor); } return OK; } +sub add_script { + my ($js) = @_; + return ''; +} + +sub start_page { + my ($jscript,$bread_title,$formname) = @_; + + my $loadcode; + if ((defined($env{'form.origin'})) + && ($env{'form.command'} eq 'compose' + || $env{'form.command'} eq 'pick_target' + || $env{'form.command'} eq 'pick_display')) { + if ($env{'form.origin'} ne '') { + $loadcode = 'javascript:setFormElements(document.'.$env{'form.command'}.')'; + if (($env{'form.command'} eq 'pick_target') + && (($env{'form.origin'} eq 'compose') + || ($env{'form.origin'} eq 'process'))) { + if ($env{'form.coursepick'} eq 'category') { + $loadcode .= ';javascript:setCourseCat(document.'.$env{'form.command'}.')'; + } + } + } + } + + my $start_page = + &Apache::loncommon::start_page('Broadcast e-mail to users', $jscript, + {'add_entries' => + {'onload' => $loadcode,},}); + my $breadcrumbs = + &Apache::lonhtmlcommon::breadcrumbs(undef,$bread_title, + 'Broadcast_system_email'); + my $output = <<"ENDONE"; +$start_page +$breadcrumbs +
+
+ENDONE + + return $output; +} + +sub end_page { + return '
'.&Apache::loncommon::end_page(); +} + +sub print_front_page { + my ($r,$formname,$cdom,$tablecolor) = @_; + + my $jscript = qq| +function next_page(caller) { + if (caller == 'view') { + document.front.command.value="pick_display" + } + else { + document.front.command.value="pick_target" + } + document.front.submit() +} + |; + + my $output = &start_page(&add_script($jscript), + 'Broadcast e-mail to Domain', $formname); + + $output .= ''; + $output .= &Apache::lonhtmlcommon::start_pick_box(); + $output .= ''. + ''. + '
'. + 'Send a new e-mail message to selected users from this domain
'. + 'Display e-mail sent by Domain Coordinators in this domain'. + '
'; + $output .= &Apache::lonhtmlcommon::end_pick_box(); + $output .= &end_page(); + + $r->print($output); + return; +} + +sub print_display_option_form { + my ($r,$formname,$cdom,$tablecolor) = @_; + &Apache::lonhtmlcommon::add_breadcrumb({text=>"Display options"}); + + my $table_width = ''; + my $col_width = '200'; + my $cmd = 'display'; + my $submit_text = 'Display e-mail'; + my @roles = ('dc'); + my $now = time; + + my $startdateform = &Apache::lonhtmlcommon::date_setter($formname, + 'startdate', + $now); + my $enddateform = &Apache::lonhtmlcommon::date_setter($formname, + 'enddate', + $now); + my %elements = ( + startdate_month => 'selectbox', + startdate_hour => 'selectbox', + enddate_month => 'selectbox', + enddate_hour => 'selectbox', + startdate_day => 'text', + startdate_year => 'text', + startdate_minute => 'text', + startdate_second => 'text', + enddate_day => 'text', + enddate_year => 'text', + enddate_minute => 'text', + enddate_second => 'text', + sender => 'checkbox', + ); + my $jscript = &Apache::lonhtmlcommon::set_form_elements(\%elements); + + my $output = &start_page(&add_script($jscript), + 'Broadcast e-mail display options', $formname); + + $output .= &Apache::lonhtmlcommon::start_pick_box($table_width); + $output .= &Apache::lonhtmlcommon::row_title($col_width,$tablecolor,&mt('Date range')); + $output .= ''; + $output .= '
Earliest to display: '. + $startdateform.'
Latest to display: '.$enddateform. + '
'; + $output .= &Apache::lonhtmlcommon::row_closure(); + $output .= &Apache::lonhtmlcommon::row_title($col_width,$tablecolor,&mt('Choose sender(s)')); + my %personnel = &Apache::lonnet::get_domain_roles($cdom,\@roles); + $output .= ''; + my @domcc = (); + foreach my $server (keys %personnel) { + foreach my $user (sort(keys %{$personnel{$server}})) { + my ($trole,$uname,$udom,$runame,$rudom,$rsec) = split(/:/,$user); + unless (grep/^$uname:$udom$/,@domcc) { + my %userinfo = &Apache::lonnet::get('environment',['lastname','firstname'],$udom,$uname); + $output .= ' '.$userinfo{firstname}.' '.$userinfo{lastname}.'  ('.$uname.':'.$udom.')'; + push (@domcc,$uname.':'.$udom); + } + } + } + $output .= ''; + $output .= &Apache::lonhtmlcommon::row_closure(); + $output .= &Apache::lonhtmlcommon::submit_row($col_width,$tablecolor,&mt('Submit'),$cmd,$submit_text); + $output .= &Apache::lonhtmlcommon::end_pick_box(); + $output .= qq(\n). + &end_page(); + $r->print($output); + return; +} + +sub print_display { + my ($r,$formname,$cdom,$tablecolor) = @_; + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"javascript:goBack('pick_display')", + text=>"Display options"}, + {text=>"E-mail display"}); + + my $table_width = ''; + my $col_width = '200'; + my $rowColor1 = "#ffffff"; + my $rowColor2 = "#eeeeee"; + my $rowColor; + my $msgcount = 0; + my $start = &Apache::lonhtmlcommon::get_date_from_form('startdate'); + my $end = &Apache::lonhtmlcommon::get_date_from_form('enddate'); + my @senders = &Apache::loncommon::get_env_multiple('form.sender'); + my %sentmail = &Apache::lonnet::dcmaildump($cdom,$start,$end,\@senders); + my %dcmail = (); + my %Sortby = (); + my $jscript = <<"ENDSCRIPT"; +function changeSort(caller) { + document.$formname.command.value = '$formname'; + document.$formname.sortby.value = caller; + document.$formname.submit(); +} +function goBack(target) { + document.$formname.command.value = target; + document.$formname.submit(); +} + +ENDSCRIPT + + my $output = &start_page(&add_script($jscript), + 'Display Broadcast e-mail', $formname); + + foreach my $msgid (keys(%sentmail)) { + my %content = &Apache::lonmsg::unpackagemsg($sentmail{$msgid}); + $msgcount ++; + %{$dcmail{$msgid}} = (); + foreach my $item (keys(%content)) { + if ($item eq 'recipient') { + foreach my $user (keys(%{$content{recipient}})) { + $dcmail{$msgid}{recipient}{$user} = $content{recipient}{$user}; + } + } else { + $dcmail{$msgid}{$item} = $content{$item}; + } + } + } + $output .= &Apache::lonhtmlcommon::start_pick_box(); + if ($msgcount > 0) { + my $rowNum = 0; + $output .= ' + + + + + + + '; + if (($env{'form.sortby'} eq 'date') || ($env{'form.sortby'} eq '') || (!defined($env{'form.sortby'})) || (($env{'form.sortby'} eq 'sender') && (@senders <= 1))) { + foreach my $msgid (sort(keys(%dcmail))) { + if ($rowNum %2 == 1) { + $rowColor = $rowColor1; + } else { + $rowColor = $rowColor2; + } + my $recipients = ''; + my ($date,$subj,$sname,$sdom) = + &Apache::lonmsg::unpackmsgid($msgid,undef,1); + $subj = &Apache::lonnet::escape($subj); + $date = &Apache::lonlocal::locallocaltime($date); + foreach my $user (sort(keys(%{$dcmail{$msgid}{recipient}}))) { + $recipients .= $dcmail{$msgid}{recipient}{$user}.', '; + } + $recipients =~ s/,\s$//; + $output .= ''."\n"; + $rowNum ++; + } + } else { + foreach my $msgid (sort(keys(%dcmail))) { + my ($date,$subj,$sname,$sdom) = + &Apache::lonmsg::unpackmsgid($msgid,undef,1); + $subj = &Apache::lonnet::escape($subj); + if ($env{'form.sortby'} eq 'subject') { + push @{$Sortby{$dcmail{$msgid}{subject}}},$msgid; + } elsif ($env{'form.sortby'} eq 'message') { + push @{$Sortby{$dcmail{$msgid}{message}}},$msgid; + } elsif ($env{'form.sortby'} eq 'recipients') { + my $recipients =''; + foreach my $user (sort(keys(%{$dcmail{$msgid}{recipient}}))) { + $recipients .= $dcmail{$msgid}{recipient}{$user}.', '; + } + $recipients =~ s/,\s$//; + push @{$Sortby{$recipients}},$msgid; + } elsif ($env{'form.sortby'} eq 'sender') { + if (@senders > 1) { + push @{$Sortby{$sname.':'.$sdom}},$msgid; + } + } + } + foreach my $key (sort(keys(%Sortby))) { + foreach my $msgid (@{$Sortby{$key}}) { + if ($rowNum %2 == 1) { + $rowColor = $rowColor1; + } else { + $rowColor = $rowColor2; + } + my $recipients = ''; + if ($env{'form.sortby'} eq 'recipients') { + $recipients = $key; + } else { + foreach my $user (sort(keys(%{$dcmail{$msgid}{recipient}}))) { + $recipients .= $dcmail{$msgid}{recipient}{$user}.', '; + } + $recipients =~ s/,\s$//; + } + my ($date,$subj,$sname,$sdom) = + &Apache::lonmsg::unpackmsgid($msgid,undef,1); + $subj = &Apache::lonnet::escape($subj); + $date = &Apache::lonlocal::locallocaltime($date); + $output .= ''."\n"; + $rowNum ++; + } + } + } + $output .= '
DateSubjectSenderMessageRecipients
'.$date.''.&cr_to_br($dcmail{$msgid}{subject}).''.$sname.':'.$sdom.''.&cr_to_br($dcmail{$msgid}{message}).''.$recipients.'
'.$date.''.&cr_to_br($dcmail{$msgid}{subject}).''.$sname.':'.$sdom.''.&cr_to_br($dcmail{$msgid}{message}).''.$recipients.'
'; + } else { + $output .= ' 
  No mail sent matching supplied criteria  

 '; + } + $output .= &Apache::lonhtmlcommon::end_pick_box(); + $output .= &Apache::lonhtmlcommon::echo_form_input(['sortby','command','origin']); + my $curr_sortby; + if (defined($env{'form.sortby'})) { + $curr_sortby = $env{'form.sortby'}; + } else { + $curr_sortby = 'date'; + } + $output .= qq(\n); + $output .= qq(\n); + $output .= qq(\n); + $output .= &end_page(); + $r->print($output); + return; +} + sub print_selection_form { - my ($r,$cdom) = @_; + my ($r,$formname,$cdom,$tablecolor) = @_; my %coursecodes = (); my %codes = (); my @codetitles = (); @@ -77,421 +386,434 @@ sub print_selection_form { my $totcodes = 0; my $format_reply; my $jscript = ''; - my $loaditems = qq| -function initialize_codes() { - return; -} - |; + my $table_width = '100%'; + my $col_width = '200'; + my %lt=&Apache::lonlocal::texthash( + 'buil' => 'Building valid e-mail address from username, if missing from preferences:', + 'kerb' => 'Kerberos: enter default for each realm used in the domain, with comma separation of entries', + 'infs' => 'Internal, Filesystem and Local authentication: enter single default.', + 'comp' => 'Compose Message' + ); + &Apache::lonhtmlcommon::add_breadcrumb + ({text=>"Select Audience"}); + $totcodes = &Apache::lonsupportreq::retrieve_instcodes(\%coursecodes,$cdom,$totcodes); if ($totcodes > 0) { $format_reply = &Apache::lonnet::auto_instcode_format($caller,$cdom,\%coursecodes,\%codes,\@codetitles,\%cat_titles,\%cat_order); if ($format_reply eq 'ok') { my $numtypes = @codetitles; &Apache::lonsupportreq::build_code_selections(\%codes,\@codetitles,\%cat_titles,\%cat_order,\%idlist,\%idnums,\%idlist_titles); - &Apache::lonsupportreq::javascript_code_selections($numtypes,\%cat_titles,\$jscript,\%idlist,\%idnums,\%idlist_titles,\@codetitles); - $loaditems = ''; + &Apache::lonsupportreq::javascript_code_selections($formname,$numtypes,\%cat_titles,\$jscript,\%idlist,\%idnums,\%idlist_titles,\@codetitles); } } - my $function = &Apache::loncommon::get_users_function(); - my $tablecolor = &Apache::loncommon::designparm($function.'.tabbg'); - my $bodytag = &Apache::loncommon::bodytag('Broadcast e-mail to users'); - my $html=&Apache::lonxml::xmlbegin(); - my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs - (undef,'Broadcast e-mail to users','Broadcast_system_email'); - $r->print(< - LON-CAPA Notification E-mail - - -$bodytag -$breadcrumbs -
-
- - - - -
- - - - -
- - - - -
- - - - - - - - - - - - - -
- - - - -
Roles: -
-
- - - - -
-
-
- - - - -
Courses: -
-
- - - -
-ENDTWO - if ($totcodes > 0) { - my $numtitles = @codetitles; - if ($numtitles == 0) { - $r->print('No institutional course code categories found.
Can not select courses to receive e-mail.'); - } else { - $r->print(''); - for (my $i=1; $i<$numtitles; $i++) { - $r->print('' - ); - } - $r->print('
'.$codetitles[0].'
'."\n". - '
'.$codetitles[$i].'
'."\n". - ''."\n". - '
'); - } - } - $r->print(< -
-
- - - - -
Submit: -
-
-
- -   -

-
-
-
-
-
- - -END + my $cb_jscript = &Apache::loncommon::coursebrowser_javascript($cdom); + + my %elements = ( + roles => 'selectbox', + types => 'selectbox', + Year => 'selectbox', + coursepick => 'radio', + coursetotal => 'text', + courselist => 'text', + internal => 'text', + krb4 => 'text', + krb5 => 'text', + local => 'text', + unix => 'text', + ); + $jscript .= &Apache::lonhtmlcommon::set_form_elements(\%elements); + if ($env{'form.coursepick'} eq 'category') { + $jscript .= qq| +function setCourseCat(formname) { + if (formname.Year.options[formname.Year.selectedIndex].value == -1) { + return; + } + courseSet('Year'); + for (var j=0; j +
  • '.$lt{'kerb'}.'
    (e.g., MSU.EDU=msu.edu, MSUE.EDU=msue.msu.edu).
  • +
  • '.$lt{'infs'}.'
  • +'."\n"; + my $submit_text = $lt{'comp'}; + my $cmd = 'compose'; + $output .= &Apache::lonhtmlcommon::role_select_row(\@roles,$col_width,$tablecolor,'Roles'); + $output .= &Apache::lonhtmlcommon::course_select_row($col_width,$tablecolor,'Courses',$formname,$totcodes,\@codetitles,\%idlist,\%idlist_titles); + $output .= &Apache::lonhtmlcommon::status_select_row(\%longtypes,$col_width,$tablecolor,&mt('Access status')); + $output .= &Apache::lonhtmlcommon::email_default_row(\%authtypes,$col_width,$tablecolor,&mt('Username -> Email conversion'),$descrip); + $output .= &Apache::lonhtmlcommon::submit_row($col_width,$tablecolor,&mt('Submit'),$cmd,$submit_text); + $output .= &Apache::lonhtmlcommon::end_pick_box(); + $output .= &end_page(); + $r->print($output); return; } sub print_composition_form { - my ($r,$cdom) = @_; - my $function = &Apache::loncommon::get_users_function(); - my $tablecolor = &Apache::loncommon::designparm($function.'.tabbg'); - my $bodytag = &Apache::loncommon::bodytag('Broadcast e-mail to users'); - my $html=&Apache::lonxml::xmlbegin(); + my ($r,$formname,$cdom,$tablecolor) = @_; &Apache::lonhtmlcommon::add_breadcrumb - ({href=>'/adm/notify?command=compose', - text=>"Compose Message"}); - my $jscript = <<"END"; -function checkAll(field) { - if (field.length > 0) { - for (i = 0; i < field.length; i++) { - field[i].checked = true ; - } - } else { - field.checked = true - } + ({href=>"javascript:goBack('pick_target')", + text=>"Select Audience"}, + {text=>"Compose Message"}); + my $jscript = &Apache::loncommon::check_uncheck_jscript(); + $jscript .= qq| +function goBack(target) { + document.$formname.command.value = target; + document.$formname.submit(); } - -function uncheckAll(field) { - if (field.length > 0) { - for (i = 0; i < field.length; i++) { - field[i].checked = false ; - } } else { - field.checked = false ; - } -} -END - my $breadcrumbs = (&Apache::lonhtmlcommon::breadcrumbs - (undef,'Broadcast e-mail to users','Broadcast_system_email')); - - $r->print(< - LON-CAPA Notification E-mail - - -$bodytag $breadcrumbs -
    -ENDONE - my $instcode = ''; - my @cats = ('Semester','Year','Department','Number'); - foreach my $category (@cats) { - if (defined($env{'form.'.$category})) { - unless ($env{'form.'.$category} eq '-1') { - $instcode .= $env{'form.'.$category}; +|; + + my %lt=&Apache::lonlocal::texthash( + 'nore' => 'No recipients identified', + 'emad' => 'e-mail address', + ); + my %elements = ( + subject => 'text', + message => 'text', + sender => 'text', + recipient => 'checkbox', + ); + $jscript .= &Apache::lonhtmlcommon::set_form_elements(\%elements); + + $r->print(&start_page(&add_script($jscript), + 'Broadcast e-mail to users', $formname)); + + my $coursefilter = $env{'form.coursepick'}; + my %courses = (); + if ($coursefilter eq 'all') { + %courses = &Apache::lonnet::courseiddump($cdom,'.','.','.','.','.'); + } elsif ($coursefilter eq 'category') { + my $instcode = ''; + my @cats = ('Semester','Year','Department','Number'); + foreach my $category (@cats) { + if (defined($env{'form.'.$category})) { + unless ($env{'form.'.$category} eq '-1') { + $instcode .= $env{'form.'.$category}; + } } } + if ($instcode eq '') { + $instcode = '.'; + } + %courses = &Apache::lonnet::courseiddump($cdom,'.','.',$instcode,'.','.'); + } elsif ($coursefilter eq 'specific') { + if ($env{'form.coursetotal'} > 1) { + my @course_ids = split(/&&/,$env{'form.courselist'}); + foreach (@course_ids) { + $courses{$_} = ''; + } + } else { + $courses{$env{'form.courselist'}} = ''; + } } - if ($instcode eq '') { - $instcode = '.'; - } - my %courses = &Apache::lonnet::courseiddump($cdom,'.','.',$instcode,'.','.'); + + my @types = &Apache::loncommon::get_env_multiple('form.types'); my @roles = &Apache::loncommon::get_env_multiple('form.roles'); + + my %longtypes = (); + my %authtypes = (); + my %email_defaults = (); + my $table_width = '100%'; + my $col_width = '200'; + + &form_elements(\%longtypes,\%authtypes); + foreach my $auth (keys(%authtypes)) { + if (exists($env{'form.'.$auth})) { + my $default = $env{'form.'.$auth}; + $default =~ s/^,+//; + $default =~ s/,+$//; + if ($auth =~ /^krb/) { + %{$email_defaults{$auth}} = (); + if ($default =~ /,/) { + my @items = split(/,/,$default); + foreach my $item (@items) { + my ($realm,$value) = split(/=/,$item); + $email_defaults{$auth}{$realm} = $value; + } + } else { + my ($realm,$value) = split(/=/,$default); + $email_defaults{$auth}{$realm} = $value; + } + } else { + $email_defaults{$auth} = $default; + } + } + } + + my $sender = &get_user_info($env{'user.name'},%email_defaults); + my %recipients = (); - foreach my $course_id (keys %courses) { - &get_active_users($course_id,\@roles,\%recipients); + my %users = (); + my %access = (); + my @sections = (); + my $totalrecip = 0; + my @unmatched = (); + foreach my $role (@roles) { + %{$users{$role}} = (); + } + foreach my $type (@types) { + $access{$type} = $type; + } + foreach my $course_id (keys(%courses)) { + my ($cdom,$cnum) = split(/_/,$course_id); + &Apache::loncommon::get_course_users($cdom,$cnum,\%access,\@roles,\@sections,\%users); + } + foreach my $role (keys(%users)) { + foreach my $user (keys(%{$users{$role}})) { + unless (defined($recipients{$user})) { + $recipients{$user} = &get_user_info($user,%email_defaults); + if ($recipients{$user} eq '') { + push @unmatched, $user; + } else { + $totalrecip ++; + } + } + } } - if (%recipients) { - $r->print('
    - - - - - -
    - - - - -
    - - - - -
    - - - - - - - - - - - - - - - - - -
    - - - - -
    Subject: -
    -
    - - - - -
    -
    -
    - - - - - -
    Message:
    -
    - - - - -
    - -
    -
    - - - - -
    Recipients: -
    -
    - - - - -
    - -   
    - '); - foreach my $username (sort keys %recipients) { + my $output; + + if ($totalrecip > 0) { + $output .= &Apache::lonhtmlcommon::start_pick_box($table_width); + $output .= &Apache::lonhtmlcommon::row_title($col_width,$tablecolor,&mt('Subject')); + $output .= ' '; + $output .= &Apache::lonhtmlcommon::row_closure(); + $output .= &Apache::lonhtmlcommon::row_title($col_width,$tablecolor,&mt('Message')); + $output .= ' '; + $output .= &Apache::lonhtmlcommon::row_closure(); + $output .= &Apache::lonhtmlcommon::row_title($col_width,$tablecolor,&mt('Recipients')); + $output .= '
    +    +
    '; + if (keys(%recipients) > 0) { + $output .= ''; + } + foreach my $username (sort(keys(%recipients))) { if ($recipients{$username} =~ /\@/) { my $value=&Apache::lonnet::escape($username).':'.&Apache::lonnet::escape($recipients{$username}); - $r->print(''); - $numrecep ++; + $output .= ''; + } + } + $output .= '
     username:domain  '.$lt{'emad'}.'
    '.$username.''.$recipients{$username}.'
    '.$username.'  '.$recipients{$username}.'
    '; + if (@unmatched) { + $output .= '

    '.&mt('Could not determine e-mail addresses for the following users:').'
      '; + foreach my $username (sort @unmatched) { + $output .= '
    • '.$username.'
    • '; } + $output .= '
    '; } - $r->print(' -
    -
    -
    - - - - -
    Submit: -
    -
    -
    - -   -

    -
    -
    -
    -
    -
    '); + $output .= ''; + $output .= &Apache::lonhtmlcommon::row_closure(); + $output .= &Apache::lonhtmlcommon::row_title($col_width,$tablecolor,&mt('Sender e-mail address')); + $output .= ''; + $output .= &Apache::lonhtmlcommon::row_closure(); + $output .= &Apache::lonhtmlcommon::submit_row($col_width,$tablecolor,&mt('Submit'),'process',&mt('Send Message')); + $output .= &Apache::lonhtmlcommon::end_pick_box(); } else { - $r->print('No recipients identified'); + $output .= $lt{'nore'}."\n". + ''."\n"; } - $r->print(''); + $output .= ''."\n"; + $output .= &Apache::lonhtmlcommon::echo_form_input(['command','origin','subject','message','recipient','sender'],); + $output .= &end_page(); + $r->print($output); return; } sub print_request_receipt { - my ($r,$dom) =@_; - my @recipients = &Apache::loncommon::get_env_multiple('recipients'); + my ($r,$formname,$dom,$tablecolor) =@_; + my @recipients = &Apache::loncommon::get_env_multiple('form.recipient'); my $subject = $env{'form.subject'}; my $message = $env{'form.message'}; - my $function = &Apache::loncommon::get_users_function(); - my $tablecolor = &Apache::loncommon::designparm($function.'.tabbg'); - my $bodytag = &Apache::loncommon::bodytag('Broadcast e-mail to users'); - my $html=&Apache::lonxml::xmlbegin(); - my $jscript; - my $breadcrumbs = &Apache::lonhtmlcommon::breadcrumbs - (undef,'Broadcast e-mail to users','Broadcast_system_email'); - $r->print(< - LON-CAPA Notification E-mail - - -$bodytag -$breadcrumbs -ENDONE - $r->print($subject.'

    '); - $r->print($message.'

    '); - foreach my $person (@recipients) { - my ($username,$email) = split/:/,$person; - $r->print('user: '.&Apache::lonnet::unescape($username).' email: '.&Apache::lonnet::unescape($email).'
    '); + my $from = $env{'form.sender'}; + my $jscript = <"javascript:goBack('pick_target')", + text=>"Select audience"}); + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"javascript:goBack('compose')", + text=>"Compose Message"}); + &Apache::lonhtmlcommon::add_breadcrumb + ({href=>"/adm/notify?command=process", + text=>"Outcome"}); + + + my $output = &start_page(&add_script($jscript), 'E-mail Delivery', + $formname); + + $output .= &Apache::lonhtmlcommon::start_pick_box(); + my @deliveries = (); + &broadcast_email(\@recipients,$subject,$from,$message,\@deliveries); + if (@deliveries > 0) { + &store_mail($subject,$message,$dom,\@deliveries); + $output .= ' + + + + + + + + + + + + + + +
    StatusSubjectMessageRecipients
    Sent'.&cr_to_br($subject).''.&cr_to_br($message).''; + foreach my $person (@deliveries) { + my ($username,$email) = split(/:/,$person); + $output .= &Apache::lonnet::unescape($email).' ('.&Apache::lonnet::unescape($username).')
    '."\n"; + } + $output .= '
    + + '; + } else { + $output .= 'No mail sent - no recipients identified'; } + $output .= &Apache::lonhtmlcommon::end_pick_box(); + $output .= '
    Send another message?'."\n"; + $output .= ''."\n". + ''."\n"; + $output .= &Apache::lonhtmlcommon::echo_form_input(['command','origin']); + $output .= &end_page(); + $r->print($output); return; } -sub get_active_users { - my ($course_id,$roles,$recipients) = @_; - if (@{$roles} > 0) { - my ($cdom,$cnum) = split/_/,$course_id; - my @coursepersonnel = &Apache::lonnet::getkeys('nohist_userroles',$cdom,$cnum); - foreach my $person (@coursepersonnel) { - my ($role,$user) = ($person =~ /^([^:]*):(.+)$/); - if (($role) && (grep/^$role$/,@{$roles})) { - unless (exists($$recipients{$user})) { - my ($uname,$udom) = split/:/,$user; - if ($uname ne '' && $udom ne '') { - if (&LONCAPA::Enrollment::check_user_status($udom,$uname,$cdom,$cnum,$role) eq 'ok') { - my %userinfo = &Apache::lonnet::get('environment',['permanenetemail','notification','critnotification',],$udom,$uname); - my @emailtypes = ('permanentemail','critnotification','notification'); - my $email = ''; - foreach (@emailtypes) { - $email = $userinfo{$_}; - if ($email =~ /\@/) { - last; - } - } - if ($email eq '') { - my $authinfo = &Apache::lonnet::queryauthenticate($uname,$udom); - my ($authtype,$autharg) = split/:/,$authinfo; - if (($authtype =~ /^krb/) && ($autharg =~ /^MSU/)) { - $email = $uname.'@msu.edu'; - } - } - $$recipients{$user} = $email; - } - } - } +sub broadcast_email { + my ($recipients,$subject,$from,$message,$deliveries)=@_; +# Should implement staggered delivery for large numbers of recipients?. + foreach my $user (@{$recipients}) { + my $msg = new Mail::Send; + my ($username,$to) = split(/:/,$user); + $username = &Apache::lonnet::unescape($username); + $to = &Apache::lonnet::unescape($to); + $msg->to($to); + $msg->subject($subject); + $msg->add('From',"$from"); + if (my $fh = $msg->open()) { + print $fh $message; + $fh->close; + push(@{$deliveries},$user); + } + } +} + +sub get_user_info { + my ($user,%email_defaults) = @_; + my ($uname,$udom) = split(/:/,$user); + my @emailtypes = ('permanentemail','critnotification','notification'); + my %userinfo = &Apache::lonnet::get('environment',\@emailtypes,$udom,$uname); + my $email = ''; + foreach my $type (@emailtypes) { + $email = $userinfo{$type}; + if ($email =~ /\@/) { + last; + } + } + if ($email eq '') { + my $authinfo = &Apache::lonnet::queryauthenticate($uname,$udom); + my ($authtype,$autharg) = split(/:/,$authinfo); + if ($authtype =~ /^krb/) { + if (defined($email_defaults{$authtype}{$autharg})) { + $email = $uname.'@'.$email_defaults{$authtype}{$autharg}; + } + } else { + if ((defined($email_defaults{$authtype})) && ($email_defaults{$authtype} ne '')) { + $email = $uname.'@'.$email_defaults{$authtype}; } } } + return $email; +} + +sub form_elements { + my ($longtypes,$authtypes) = @_; + %{$longtypes} = ( + active => 'Currently has access', + previous => 'Previously had access', + future => 'Will have future access', + ); + %{$authtypes} = ( + krb4 => 'Kerberos 4', + krb5 => 'Kerberos 5', + internal => 'Internal (LON-CAPA)', + unix => 'Filesystem (UNIX)', + local => 'Local/Customized', + ); + return; +} + +sub store_mail { + my ($subject,$message,$domain,$recipients,$attachmenturl) = @_; + my $msgid; + ($msgid,$message) = &Apache::lonmsg::packagemsg($subject,$message,undef,undef, + $attachmenturl,$recipients,undef,undef,'dcmail'); + +# Store in dc email db files on primary library server for domain. + my $server = $Apache::lonnet::domain_primary{$domain}; + if (defined($server)) { + unless (&Apache::lonnet::dcmailput($domain,$msgid,$message,$server) + eq 'ok') { + &Apache::lonnet::logthis('Storage of dc mail failed for domain'. + $domain.' for server: '. $server.'. Message ID was '.$msgid); + } + } else { + &Apache::lonnet::logthis('Storage of dc mail failed for domain'. + $domain.' as no primary server identified. Message ID was '.$msgid); + } +} + +sub cr_to_br { + my $incoming = shift; + $incoming =~ s/\n/\
    /g; + return $incoming; } 1;