Diff for /loncom/interface/lonwhatsnew.pm between versions 1.4 and 1.29

version 1.4, 2005/04/07 04:22:03 version 1.29, 2005/09/12 03:32:31
Line 35  use Apache::lonhtmlcommon(); Line 35  use Apache::lonhtmlcommon();
 use Apache::lonlocal;  use Apache::lonlocal;
 use Apache::loncoursedata();  use Apache::loncoursedata();
 use Apache::lonnavmaps();  use Apache::lonnavmaps();
   use Apache::lonuserstate;
 use Apache::Constants qw(:common :http);  use Apache::Constants qw(:common :http);
 use Time::Local;  use Time::Local;
   use GDBM_File;
   
 #----------------------------  #----------------------------
 # handler  # handler
Line 45  use Time::Local; Line 47  use Time::Local;
   
 sub handler {  sub handler {
     my $r = shift;      my $r = shift;
       if ($r->header_only) {
           &Apache::loncommon::content_type($r,'text/html');
           $r->send_http_header;
           return OK;
       }
     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['command']);      &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['command']);
   
     my $command = $ENV{'form.command'};      my $command;
       if ($env{'form.action'} eq 'reset') {
     if ($command eq '') {          $command = 'reset';
         $command = "info";      } elsif ($env{'form.action'} eq 'update') {
           $command = 'update';
       } else {
           $command = $env{'form.command'};
     }      }
   
       &Apache::loncommon::content_type($r,'text/html');
       $r->send_http_header;
     $r->print(&display_header());      $r->print(&display_header());
     if (! (($ENV{'request.course.fn'}) && (&Apache::lonnet::allowed('vsa',$ENV{'request.course.id'})))) {      if (! (($env{'request.course.fn'}) && (&Apache::lonnet::allowed('vsa',$env{'request.course.id'})))) {
         # Not in a course, or not allowed to modify parms          # Not in a course, or not allowed to modify parms
         $ENV{'user.error.msg'}="/adm/whatsnew:vsa:0:0:Cannot display student activity";          $env{'user.error.msg'}="/adm/whatsnew:vsa:0:0:Cannot display student activity";
         return HTTP_NOT_ACCEPTABLE;          return HTTP_NOT_ACCEPTABLE;
     }      }
   
       &Apache::lonhtmlcommon::clear_breadcrumbs();
       if ($command eq 'chgthreshold') {
           &Apache::lonhtmlcommon::add_breadcrumb
               ({href=>'/adm/whatsnew?command=threshold',
                 text=>"Change thresholds"});
           $r->print(&Apache::lonhtmlcommon::breadcrumbs
               (undef,'Course Action Items','Course_Action_Items_Thresholds'));
       } else {
           &Apache::lonhtmlcommon::add_breadcrumb
               ({href=>'/adm/whatsnew',
                 text=>"Display Action Items"});
           $r->print(&Apache::lonhtmlcommon::breadcrumbs
               (undef,'Course Action Items','Course_Action_Items_Display'));
       }
     &display_main_box($r,$command);      &display_main_box($r,$command);
       return OK;
 }  }
   
 #------------------------------  #------------------------------
Line 73  sub display_main_box { Line 100  sub display_main_box {
     my ($r,$command) = @_;      my ($r,$command) = @_;
     my $domain=&Apache::loncommon::determinedomain();      my $domain=&Apache::loncommon::determinedomain();
     my $tabbg=&Apache::loncommon::designparm('coordinator.tabbg',$domain);      my $tabbg=&Apache::loncommon::designparm('coordinator.tabbg',$domain);
     $r->print(<<END_OF_BLOCK);      $r->print('<table width="100%" border="0" cellpadding="5" cellspacing="0"><tr><td width="100%">');
 <br />  
 <br />      my %threshold_titles = (
 <table width="100%" border="0" cellpadding="0" cellspacing="0">                           av_attempts => 'Average number of attempts',
  <tr>                           degdiff => 'Degree of difficulty',
   <td width="100%" bgcolor="#000000">                           numstudents => 'Total number of students with submissions',
    <table width="100%" border="0" cellpadding="1" cellspacing="0">      );
     <tr>      my $cdom = $env{'course.'.$env{'request.course.id'}.'.domain'};
      <td width="100%" bgcolor="#000000">      my $crs = $env{'course.'.$env{'request.course.id'}.'.num'};
       <table width="100%" border="0" cellpadding="0" cellspacing="1" bgcolor="#ffffff">  
        <tr>      if ($command eq 'chgthreshold') {
         <td colspan="2" width="100%" bgcolor="$tabbg">          &display_config_box($r,$command,$tabbg,\%threshold_titles,$cdom,$crs);
          <table width="100%" border="0" cellpadding="5" cellspacing="0">  
           <tr>  
            <td width="100%">  
             <table width="100%" border="0" cellpadding="0" cellspacing="0">  
              <tr>  
               <td>  
                <font face="arial,verdana" size="3"><b>Course Action Items</b></font></td>  
               </td>  
               <td align="right">&nbsp;  
               </td>  
              </tr>  
             </table>  
            </td>  
           </tr>  
          </table>  
         </td>  
        </tr>  
        <tr>  
         <td width="100" valign="top" bgcolor="#dddddd" height="100%">  
          <table width="100" border="0" cellpadding="0" cellspacing="0" height="100%">  
           <tr>  
            <td valign="top" height="100%">  
 END_OF_BLOCK  
     &display_nav_box($r,$command);  
     $r->print('</td></tr></table></td>');  
     $r->print('<td width="100%" bgcolor="#ffffff"><table width="100%" border="0" cellpadding="5" cellspacing="0"><tr><td width="100%">');  
    
     if ($command eq 'config') {  
         &display_config_box($r);  
     } else {      } else {
         &display_actions_box($r);          &display_actions_box($r,$command,\%threshold_titles,$cdom,$crs);
     }      }
     $r->print(<<END_OF_BLOCK);      $r->print(<<END_OF_BLOCK);
               </td>  
              </tr>  
             </table>  
            </td>  
           </tr>  
          </table>  
         </td>  
        </tr>  
       </table>  
      </td>  
     </tr>  
    </table>  
   </td>    </td>
  </tr>   </tr>
 </table><br />  </table><br />
Line 138  END_OF_BLOCK Line 124  END_OF_BLOCK
 END_OF_BLOCK  END_OF_BLOCK
 }  }
   
 #------------------------------  
 # display_nav_box  
 #  
 # Display the navigation box  
 #------------------------------  
                                                                                   
 sub display_nav_box {  
     my ($r,$command) = @_;  
     $r->print('<table width="100" border="0" cellpadding="3" cellspacing="0">'."\n");  
     if ($command eq "info") {  
         $r->print('<tr><td bgcolor="#ffffff">');  
         $r->print('<small><b>Action Items</b></small><br />');  
         $r->print('</td></tr>');  
     } else {  
         $r->print('<tr><td>');  
         $r->print('<small><a href="/adm/whatsnew?command=info">Current Action Items</a></small><br />');  
         $r->print('</td></tr>');  
     }  
     $r->print('<tr><td>&nbsp;</td></tr>');  
     if ($command eq "config") {  
         $r->print('<tr><td bgcolor="#ffffff">');  
         $r->print('<small><b>Display options</b></small><br />');  
         $r->print('</td></tr>');  
     } else {  
         $r->print('<tr><td>');  
         $r->print('<small><a href="/adm/whatsnew?command=config">Display options</a></small><br />');  
         $r->print('</td></tr>');  
     }  
     $r->print('</table>');  
 }  
   
 #-------------------------------  #-------------------------------
 # display_header  # display_header
 #  #
Line 196  ENDHEAD Line 151  ENDHEAD
 #-------------------------------  #-------------------------------
                                                                                                                                                                   
 sub display_actions_box() {  sub display_actions_box() {
     my $r = shift;      my ($r,$command,$threshold_titles,$cdom,$crs) = @_;
   
     my $rowColor1 = "#ffffff";      my $rowColor1 = "#ffffff";
     my $rowColor2 = "#eeeeee";      my $rowColor2 = "#eeeeee";
Line 205  sub display_actions_box() { Line 160  sub display_actions_box() {
     my %unread = ();      my %unread = ();
     my %ungraded = ();      my %ungraded = ();
     my %bombed = ();      my %bombed = ();
       my %triggered = ();
     my @newmsgs = ();      my @newmsgs = ();
     my @critmsgs = ();      my @critmsgs = ();
     my @newdiscussions = ();      my @newdiscussions = ();
     my @tograde = ();      my @tograde = ();
     my @bombs = ();      my @bombs = ();
       my @warnings = ();
       my %res_title = ();
   
     my $domain=&Apache::loncommon::determinedomain();      my $domain=&Apache::loncommon::determinedomain();
     my $function;      my $function;
     if ($ENV{'request.role'}=~/^(cc|in|ta|ep)/) {      if ($env{'request.role'}=~/^(cc|in|ta|ep)/) {
         $function='coordinator';          $function='coordinator';
     }      }
     if ($ENV{'request.role'}=~/^(su|dc|ad|li)/) {      if ($env{'request.role'}=~/^(su|dc|ad|li)/) {
         $function='admin';          $function='admin';
     }      }
   
       my %threshold = (
                         av_attempts => 2,
                         degdiff => 0.5,
                         numstudents => 2,
                        );
   
     my $pgbg=&Apache::loncommon::designparm($function.'.pgbg',$domain);      my $pgbg=&Apache::loncommon::designparm($function.'.pgbg',$domain);
     my $tabbg=&Apache::loncommon::designparm($function.'.tabbg',$domain);      my $tabbg=&Apache::loncommon::designparm($function.'.tabbg',$domain);
   
     &getitems(\%unread,\%ungraded,\%bombed,\@newdiscussions,\@tograde,\@bombs);      unless ($env{'request.course.id'}) {
           $r->print('<br /><b><center>You are accessing an invalid course.</center></b><br /><br />');
           return;
       }
       if (tie(my %bighash,'GDBM_File',$env{'request.course.fn'}.'.db',
       &GDBM_READER(),0640)) {
    my $furl=$bighash{'first_url'};
    $r->print('<font size="+1"><a href="'.$furl.'">Go to first resource</a></font><a href="/adm/preferences?action=changecourseinit"></font><br />Change your preferences</a> to suppress display of this screen when accessing courses as Course Coordinator in the future.<br /><hr />');
    untie(%bighash);
       }
   
       my $result;
   
       if ($command eq 'reset') {
           $result = &process_reset($cdom,$crs);
       } elsif ($command eq 'update') {
           $result = &process_update($cdom,$crs,$threshold_titles);
       }
       if ($result) {
           $r->print($result.'<hr width="100%" />');
       }
       $r->rflush();
   
       &get_curr_thresholds(\%threshold,$cdom,$crs);
       &getitems(\%unread,\%ungraded,\%bombed,\%triggered,\@newdiscussions,\@tograde,\@bombs,\@warnings,$rowColor1,$rowColor2,\%threshold,$cdom,$crs,%res_title);
     my ($msgcount,$critmsgcount) = &getmail(\@newmsgs,\@critmsgs);      my ($msgcount,$critmsgcount) = &getmail(\@newmsgs,\@critmsgs);
   
     unless ($ENV{'request.course.id'}) {      $r->print('<br /><table border="0" width="100%" cellpadding="2" cellspacing="4"><tr><td align="left" valign="top" width="45%">');
         $r->print('<br /><b><center>You are accessing an invalid course</center></b><br /><br />');  
         return;  ## UNGRADED ITEMS ##
       $r->print(<<END);
              <table border="0" cellpadding="0" cellspacing="0" bgcolor="#000000" width="100%">
               <tr><td>
                <table border="0" cellpadding="1" cellspacing="1" bgcolor="#000000" width="100%">
                 <tr>
                  <td bgcolor="$tabbg"><b>Problems requiring handgrading</b></td></tr>
                     <tr>
                      <td bgcolor="#ffffff">
                        <table cellpadding="2" cellspacing="0" border="0" width="100%">
   END
   
       if (@tograde > 0) {
           $r->print('<tr bgcolor="#cccccc"><td><b><small>Problem Name</small></b></td><td align="right"><b><small>Number ungraded</small></b></td></tr>');
           my $rowNum = 0;
           foreach my $res (@tograde) {
               if ($rowNum %2 == 1) {
                   $rowColor = $rowColor1;
               } else {
                   $rowColor = $rowColor2;
               }
               my ($map,$id,$url)=&Apache::lonnet::decode_symb($res);
               my $linkurl=&Apache::lonnet::clutter($url);
               $linkurl .= '?symb='.&Apache::lonnet::escape($res);
   
               $r->print('<tr bgcolor="'.$rowColor.'"><td><a href="'.$linkurl.'"><small>'.$ungraded{$res}{title}.'</small></a></td><td align="right"><small>'.$ungraded{$res}{count}.'</small></td></tr>');
               $rowNum ++;
           }
       } else {
           $r->print('<tr><td bgcolor="#ffffff"><br><center><i><b><small>&nbsp;&nbsp;No problems require handgrading&nbsp;&nbsp;</small><br><br></b></i></td></tr>');
       }
       $r->print('</table></td></tr></table></td></tr></table><br />');
   
   ## BOMBS ##
        $r->print(<<"END");
              <table border="0" cellpadding="0" cellspacing="0" bgcolor="#000000" width="100%">
               <tr>
                <td>
                  <table border="0" cellpadding="1" cellspacing="1" bgcolor="#000000" width="100%">
                  <tr>
                   <td bgcolor="$tabbg"><b>Problems with errors</b></td>
                  </tr>
                   <tr>
                   <td bgcolor="#ffffff">
                    <table width="100%" cellspacing="0" cellpadding="0" border="0">
   END
        my $bombnum = 0;
        if (@bombs > 0) {
           $r->print('<tr bgcolor="#cccccc"><td><b><small>Resource</small></b></td><td align="right"><b><small>Number of errors</small></b></td></tr>');
           @bombs = sort { &cmp_title($a,$b,\%res_title) } @bombs;
           foreach my $bomb (@bombs) {
               if ($bombnum %2 == 1) {
    $rowColor = $rowColor1;
               } else {
                   $rowColor = $rowColor2;
               }
               $r->print('<tr bgcolor="'.$rowColor.'"><td><small>'.$bombed{$bomb}{errorlink}.'</small></td><td align="right"><small>'.$bombed{$bomb}{errorcount}.'</small></td></tr>');
               $bombnum ++;
           }
       } else {
           $r->print('<tr><td bgcolor="#ffffff"><br /><center><b><i><small>No problems with errors</small></i></b></center><br /></td></tr>');
     }      }
       $r->print('</table></td></tr></table></td></tr></table><br />');
   
     $r->print('<b>Course Action Items</b><br /><hr width="100%" /><table border="0" width="100%" cellpadding="2" cellspacing="4" bgcolor="#ffffff"><tr><td align="left" valign="top" width="45%">');  # DEGDIFF AND AV. TRIES TRIGGERS
       $r->print(<<"END");
              <table border="0" cellpadding="0" cellspacing="0" bgcolor="#000000" width="100%">
               <tr>
                <td>
                  <table border="0" cellpadding="1" cellspacing="1" bgcolor="#000000" width="100%">
                  <tr>
                   <td bgcolor="$tabbg"><b>Problems with av. attempts &ge; $threshold{'av_attempts'} or deg. difficulty &ge; $threshold{'degdiff'}<br /> and total number of students with submissions &ge; $threshold{'numstudents'}</b></td>
                  </tr>
                  <tr>
                   <td bgcolor="$tabbg" align="right"><a href="/adm/whatsnew?command=chgthreshold"><b><small>Change thresholds?</small></b></a></td>
                  </tr>
                   <tr>
                   <td bgcolor="#ffffff">
                    <table width="100%" cellspacing="2" cellpadding="2" border="0">
   END
       my $warningnum = 0;
       if (@warnings > 0) {
           @warnings = sort { &cmp_title($a,$b,\%res_title) } @warnings;
           $r->print('<form name="reset_tracking" method="post">'.
                    '  <input type="hidden" name="action" value="reset" />'."\n");
           $r->print('<tr bgcolor="#cccccc"><td><b><small>Resource</small></b></td><td align="right"><b><small>Part</small></b></td><td align="right"><b><small>Num. students</small></b></td><td align="right"><b><small>Av. Attempts</small></b></td><td align="right"><b><small>Deg. Diff</small></b></td><td align="right"><b><small>Last Reset</small></b></td><td align="right"><b><small>Reset Count?</small></b></td></tr>');
           foreach my $res (@warnings) {
               if ($warningnum %2 == 1) {
                   $rowColor = $rowColor1;
               } else {
                   $rowColor = $rowColor2;
               }
               my ($map,$id,$url)=&Apache::lonnet::decode_symb($res);
               my $linkurl=&Apache::lonnet::clutter($url);
               my $rowspan;
               if ($triggered{$res}{numparts} > 1) {
                   $rowspan = 'rowspan="'.$triggered{$res}{numparts}.'"';
               }
               $linkurl .= '?symb='.&Apache::lonnet::escape($res);
               $r->print('<tr bgcolor="'.$rowColor.'"><td '.$rowspan.'><a href="'.$linkurl.'"><small>'.$triggered{$res}{title}.'</small></a></td>'.$triggered{$res}{text});
               $warningnum ++;
           }
           $r->print('<tr bgcolor="#cccccc"><td colspan="7" align="right"><br /><b><small><input type="submit" name="counters" value="Reset counters to 0" /></form>'); 
       } else {
           $r->print('<tr><td bgcolor="#ffffff"><br /><center><b><i><small>No problems satisfy threshold criteria.</small></i></b></center><br /></td></tr>');
       }
       $r->print('</table></td></tr></table></td></tr></table><br />');
   
       $r->print('</td><td width="5%">&nbsp;</td><td align="left" valign="top" width-"50%">');
   
 ## UNREAD COURSE DISCUSSION POSTS ##  ## UNREAD COURSE DISCUSSION POSTS ##
     $r->print(<<"END");      $r->print(<<"END");
Line 239  sub display_actions_box() { Line 332  sub display_actions_box() {
                <tr><td>                 <tr><td>
                 <table border="0" cellpadding="1" cellspacing="1" bgcolor="#000000" width="100%">                  <table border="0" cellpadding="1" cellspacing="1" bgcolor="#000000" width="100%">
                  <tr>                   <tr>
                   <td bgcolor="$tabbg"><b>Unread course discussion posts:</b></td>                    <td bgcolor="$tabbg"><b>Unread course discussion posts</b></td>
                  </tr>                   </tr>
                  <tr>                   <tr>
                    <td bgcolor="#ffffff">                     <td bgcolor="#ffffff">
                    <table cellpadding="2" cellspacing="0" border="0" width="100%">                     <table cellpadding="2" cellspacing="0" border="0" width="100%">
 END  END
                                                                                     
     if (@newdiscussions > 0) {      if (@newdiscussions > 0) {
 #        @newdiscussions = sort { &cmp_title($a,$b) } @newdiscussions;          $r->print('<tr bgcolor="#cccccc"><td><b><small>Location</small></b></td><td><b><small>Type</small></b><td align="right"><b><small>Number of new posts</small></b></td></tr>');
           @newdiscussions = sort { &cmp_title($a,$b,\%res_title) } @newdiscussions;
         my $rowNum = 0;          my $rowNum = 0;
         foreach my $ressymb (@newdiscussions) {          foreach my $ressymb (@newdiscussions) {
             my $forum_title = $unread{$ressymb}{'title'};              my $forum_title = $unread{$ressymb}{'title'};
     my $feedurl=&Apache::lonfeedback::get_feedurl($ressymb);              my $type = 'Resource';
               my $feedurl=&Apache::lonfeedback::get_feedurl($ressymb);
               if ($feedurl =~ /bulletinboard/) {
                   $type = 'Bulletin Board';
               }
             my $unreadnum = keys(%{$unread{$ressymb}});              my $unreadnum = keys(%{$unread{$ressymb}});
             $unreadnum = $unreadnum - 2;              $unreadnum = $unreadnum - 2;
             if ($unreadnum > 0) {              if ($unreadnum > 0) {
Line 260  END Line 358  END
                 } else {                  } else {
                     $rowColor = $rowColor2;                      $rowColor = $rowColor2;
                 }                  }
                 $r->print('<tr><td bgcolor="'.$rowColor.'"><small><a href="'.$feedurl.'?symb='.$unread{$ressymb}{symb}.'">'.$forum_title.':</a>&nbsp;</td><td bgcolor="'.$rowColor.'" align="right">'.$unreadnum.'&nbsp;</td></tr>');                  $r->print('<tr bgcolor="'.$rowColor.'"><td><small><a href="'.$feedurl.'?symb='.$unread{$ressymb}{symb}.'">'.$forum_title.'</a>&nbsp;</td><td><small>'.$type.'</small></td><td align="right">'.$unreadnum.'&nbsp;</td></tr>');
                 $rowNum ++;                  $rowNum ++;
             }              }
         }          }
Line 269  END Line 367  END
     }      }
     $r->print('</table></td></tr></table></td></tr></table><br />');      $r->print('</table></td></tr></table></td></tr></table><br />');
   
 ## UNGRADED ITEMS ##  
     $r->print(<<END);  
            <table border="0" cellpadding="0" cellspacing="0" bgcolor="#000000" width="100%">  
             <tr><td>  
              <table border="0" cellpadding="1" cellspacing="1" bgcolor="#000000" width="100%">  
               <tr>  
                <td bgcolor="$tabbg"><b>Problems requiring handgrading:</b></td></tr>  
                   <tr>  
                    <td bgcolor="#ffffff">  
                      <table cellpadding="2" cellspacing="0" border="0" width="100%">  
 END  
   
     if (@tograde > 0) {  
         $r->print('<tr><th bgcolor="#cccccc">Problem Name</th><th>Number ungraded</th></tr>');  
         my $rowNum = 0;  
         foreach my $res (@tograde) {  
             if ($rowNum %2 == 1) {  
                 $rowColor = $rowColor1;  
             } else {  
                 $rowColor = $rowColor2;  
             }  
               
             $r->print('<tr bgcolor="'.$rowColor.'"><td>'.$ungraded{$res}{title}.'</td><td>'.$ungraded{$res}{count}.'</td></tr>');  
             $rowNum ++;  
         }  
     } else {  
         $r->print('<tr><td bgcolor="#ffffff"><br><center><i><b><small>&nbsp;&nbsp;No problems require handgrading&nbsp;&nbsp;</small><br><br></b></i></td></tr>');  
     }  
     $r->print('</table></td></tr></table></td></tr></table><br />');  
     $r->print('</td><td width="5%">&nbsp;</td><td align="left" valign="top" width-"50%">');  
   
 ## MESSAGES ##  ## MESSAGES ##
     $r->print(<<END);      $r->print(<<END);
            <table border="0" cellpadding="0" cellspacing="0" bgcolor="#000000" width="100%">             <table border="0" cellpadding="0" cellspacing="0" bgcolor="#000000" width="100%">
Line 314  END Line 381  END
                  <table width="100%" cellspacing="0" cellpadding="0" border="0">                   <table width="100%" cellspacing="0" cellpadding="0" border="0">
 END  END
     if ($msgcount > 0) {      if ($msgcount > 0) {
           $r->print('<tr bgcolor="#cccccc"><td><b><small>'.&mt('Number').'</small></b></td><td><b><small>'.&mt('Subject').'</small></b></td><td><b><small>'.&mt('Sender').'</small></b></td><td><b><small>'.&mt('Date/Time').'</small></b></td></tr>');
         my $rowNum = 0;          my $rowNum = 0;
         my $mailcount = 1;           my $mailcount = 1; 
         foreach my $msg (@newmsgs) {          foreach my $msg (@newmsgs) {
Line 322  END Line 390  END
             } else {              } else {
                 $rowColor = $rowColor2;                  $rowColor = $rowColor2;
             }              }
             $r->print('<tr><td bgcolor="'.$rowColor.'" valign="top"><small>'.$mailcount.'. &nbsp;<small></td><td valign="top"><small><a href="/adm/mail?">'.$msg->{'shortsub'}.'</a>&nbsp; &nbsp;</small></td><td valign="top"><small>&nbsp;'.$msg->{'from'}.'@'.$msg->{'fromdom'}.'&nbsp;</small></td><td valign="top"><small>'.$msg->{'sendtime'}.'</small></td></tr>');              $r->print('<tr bgcolor="'.$rowColor.'"><td valign="top"><small>'.$mailcount.'. &nbsp;<small></td><td valign="top"><small><a href="/adm/communicate">'.$msg->{'shortsub'}.'</a>&nbsp; &nbsp;</small></td><td valign="top"><small>&nbsp;'.$msg->{'from'}.'@'.$msg->{'fromdom'}.'&nbsp;</small></td><td valign="top"><small>'.$msg->{'sendtime'}.'</small></td></tr>');
             $rowNum ++;              $rowNum ++;
             $mailcount ++;              $mailcount ++;
         }          }
Line 345  END Line 413  END
 END  END
   
     if ($critmsgcount > 0) {      if ($critmsgcount > 0) {
           $r->print('<tr bgcolor="#cccccc"><td><b><small>Number</small></b></td><td><b><small>Subject</small></b></td><td><b><small>Sender</small></b></td><td><b><small>Date/Time</small></b></td></tr>');
         my $rowNum = 0;          my $rowNum = 0;
         my $mailcount = 1;          my $mailcount = 1;
         foreach my $msg (@critmsgs) {          foreach my $msg (@critmsgs) {
Line 353  END Line 422  END
             } else {              } else {
                 $rowColor = $rowColor2;                  $rowColor = $rowColor2;
             }              }
             $r->print('<tr><td bgcolor="'.$rowColor.'" valign="top"><small>'.$mailcount.'. &nbsp;<small></td><td valign="top"><small><a href="/adm/mail?">'.$msg->{'shortsub'}.'</a>&nbsp; &nbsp;</small></td><td valign="top"><small>&nbsp;'.$msg->{'from'}.'@'.$msg->{'fromdom'}.'&nbsp;</small></td><td valign="top"><small>'.$msg->{'sendtime'}.'</small></td></tr>');              $r->print('<tr bgcolor="'.$rowColor.'"><td valign="top"><small>'.$mailcount.'. &nbsp;<small></td><td valign="top"><small><a href="/adm/email?folder=critical">'.$msg->{'shortsub'}.'</a>&nbsp; &nbsp;</small></td><td valign="top"><small>&nbsp;'.$msg->{'from'}.'@'.$msg->{'fromdom'}.'&nbsp;</small></td><td valign="top"><small>'.$msg->{'sendtime'}.'</small></td></tr>');
             $rowNum ++;              $rowNum ++;
             $mailcount ++;              $mailcount ++;
         }          }
Line 363  END Line 432  END
                                                                                                                                                                 
     $r->print('</table></td></tr></table></td></tr></table><br />');      $r->print('</table></td></tr></table></td></tr></table><br />');
   
 ## BOMBS ##  
     $r->print(<<END);  
            <table border="0" cellpadding="0" cellspacing="0" bgcolor="#000000" width="100%">  
             <tr>  
              <td>  
               <table border="0" cellpadding="1" cellspacing="1" bgcolor="#000000" width="100%">  
                <tr>  
                 <td bgcolor="$tabbg"><b>Problems with errors</b></td>  
                </tr>  
                <tr>  
                 <td bgcolor="#ffffff">  
                  <table width="100%" cellspacing="0" cellpadding="0" border="0">  
 END  
     my $bombnum = 0;  
     if (@bombs > 0) {  
 #        @bombs = sort { &cmp_title($a,$b) } @bombs;  
         foreach my $bomb (@bombs) {  
             if ($bombnum %2 == 1) {  
                 $rowColor = $rowColor1;  
             } else {  
                 $rowColor = $rowColor2;  
             }  
             $r->print('<tr bgcolor="'.$rowColor.'"><td>'.$bombed{$bomb}{errorlink}.'</td></tr>');  
             $bombnum ++;  
         }  
     } else {  
         $r->print('<tr><td bgcolor="#ffffff"><br /><center><b><i><small>No problems with errors</small></i></b></center><br /></td></tr>');  
     }  
     $r->print('</table></td></tr></td></tr></table>');  
     $r->print('      $r->print('
            </table>             </table>
           </td>            </td>
Line 400  END Line 440  END
     $r->print('</td></tr></table>');      $r->print('</td></tr></table>');
 }  }
   
   #-------------------------------
   # display_config_box
   #
   # Display the threshold setting screen 
   #
   #-------------------------------
                                                                                   
   sub display_config_box() {
       my ($r,$command,$tabbg,$threshold_titles,$cdom,$crs) = @_;
       my %threshold = ();
       my $rowColor1 = "#ffffff";
       my $rowColor2 = "#eeeeee";
       my $rowColor;
   
       my @thresholditems = ("av_attempts","degdiff","numstudents");
       my %threshold_titles = (
                            av_attempts => 'Average number of attempts',
                            degdiff => 'Degree of difficulty',
                            numstudents => 'Total number of students with submissions',
                            );
       &get_curr_thresholds(\%threshold,$cdom,$crs);
   
       $r->print('<br /><form name="thresholdform" method="post"><table border="0" cellpadding="2" cellspacing="4"><tr><td align="left" valign="top" width="45%">
              <table border="0" cellpadding="0" cellspacing="0" bgcolor="#000000">
               <tr>
                <td>
                  <table border="0" cellpadding="1" cellspacing="1" bgcolor="#000000">
                   <tr>
                   <td bgcolor="#ffffff">
                    <table cellspacing="0" cellpadding="4" border="0">
        <tr bgcolor="'.$tabbg.'">
         <th>Threshold Name</th>
         <th>Current value</th>
         <th>Change?</th>
        </tr>');
       my $rowNum =0;
       foreach my $type (@thresholditems) {
           my $parameter = 'internal.threshold_'.$type;
   # onchange is javascript to automatically check the 'Set' button.
           my $onchange = 'onFocus="javascript:window.document.forms'.
                 "['thresholdform'].elements['".$parameter."_setparmval']".
                 '.checked=true;"';
           if ($rowNum %2 == 1) {
               $rowColor = $rowColor1;
           } else {
               $rowColor = $rowColor2;
           }
           $r->print('
        <tr bgcolor="'.$rowColor.'">
         <td>'.$threshold_titles{$type}.'</td>
         <td>'.&Apache::lonhtmlcommon::textbox($parameter.'_value',
                                               $threshold{$type},
                                               10,$onchange).'</td>
         <td>'
              .&Apache::lonhtmlcommon::checkbox($parameter.'_setparmval').
         '</td>
        </tr>');
           $rowNum ++;
       }
       $r->print('</table></td></tr></table></td></tr></table>
              <br /><input type="submit" name="threshold" value="Make changes" />
                    <input type="hidden" name="action" value="update" />
                  </form>');
   }
   
 sub getitems {  sub getitems {
     my ($unread,$ungraded,$bombed,$newdiscussions,$tograde,$bombs) = @_;      my ($unread,$ungraded,$bombed,$triggered,$newdiscussions,$tograde,$bombs,$warnings,$rowColor1,$rowColor2,$threshold,$cdom,$crs,$res_title) = @_;
     my $navmap = Apache::lonnavmaps::navmap->new();      my $navmap = Apache::lonnavmaps::navmap->new();
     my @allres=$navmap->retrieveResources();      # force retrieve Resource to seed the part id cache we'll need it later
     my %discussiontime = &Apache::lonnet::dump('discussiontimes',      my @allres=$navmap->retrieveResources(undef,sub {if ($_[0]->is_problem) { $_[0]->parts();} return 1;});
                $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},      my %discussiontime = &Apache::lonnet::dump('discussiontimes',$cdom,$crs);
                $ENV{'course.'.$ENV{'request.course.id'}.'.num'});      my %lastread = &Apache::lonnet::dump('nohist_'.$env{'request.course.id'}.
     my %lastread = &Apache::lonnet::dump('nohist_'.$ENV{'request.course.id'}.'_discuss',$ENV{'user.domain'},$ENV{'user.name'},'lastread');                  '_discuss',$env{'user.domain'},$env{'user.name'},'lastread');
     my %lastreadtime = ();      my %lastreadtime = ();
     my @discussions = ();      my @discussions = ();
     my ($classlist,$keylist) = &Apache::loncoursedata::get_classlist();      my ($classlist,$keylist) = &Apache::loncoursedata::get_classlist();
   
       my %resourcetracker =  &Apache::lonnet::dump('nohist_resourcetracker',
                  $cdom,$crs);
       my $warningnum = 0;
     foreach my $key (keys(%lastread)) {      foreach my $key (keys(%lastread)) {
         my $newkey = $key;          my $newkey = $key;
         $newkey =~ s/_lastread$//;          $newkey =~ s/_lastread$//;
Line 421  sub getitems { Line 529  sub getitems {
         my $result = '';          my $result = '';
         my $applies = 0;          my $applies = 0;
         my $symb = $resource->symb();          my $symb = $resource->symb();
         %{$$bombed{$symb}} = ();  #        %{$$bombed{$symb}} = ();
         %{$$ungraded{$symb}} = ();          %{$$ungraded{$symb}} = ();
           %{$$triggered{$symb}} = ();
           $$triggered{$symb}{numparts} = 0;
         my $title = $resource->compTitle();          my $title = $resource->compTitle();
         my $ressymb = $symb;          $$res_title{$symb} = $title;
         if ($ressymb =~ m-(___adm/\w+/\w+)/(\d+)/bulletinboard$-) {          my $ressymb = $resource->wrap_symb();
             $ressymb = &Apache::lonfeedback::wrap_symb('bulletin___'.$2.$1.'/'.  
        $2.'/bulletinboard');  
         }  
   
 # Check for unread discussion postings  # Check for unread discussion postings
         if (defined($discussiontime{$ressymb})) {   if ($resource->hasDiscussion()) {
             push(@discussions,$ressymb);              push(@discussions,$ressymb);
             my $prevread = 0;              my $prevread = 0;
             my $unreadcount = 0;              my $unreadcount = 0;
Line 441  sub getitems { Line 547  sub getitems {
             if (defined($lastreadtime{$ressymb})) {              if (defined($lastreadtime{$ressymb})) {
                 $prevread = $lastreadtime{$ressymb};                  $prevread = $lastreadtime{$ressymb};
             }              }
             my %contrib = &Apache::lonnet::restore($ressymb,$ENV{'request.course.id'},              my %contrib = &Apache::lonnet::restore($ressymb,
             $ENV{'course.'.$ENV{'request.course.id'}.'.domain'},                               $env{'request.course.id'},$cdom,$crs);
             $ENV{'course.'.$ENV{'request.course.id'}.'.num'});  
             if ($contrib{'version'}) {              if ($contrib{'version'}) {
                 for (my $id=1;$id<=$contrib{'version'};$id++) {                  for (my $id=1;$id<=$contrib{'version'};$id++) {
                     unless (($contrib{'hidden'}=~/\.$id\./) || ($contrib{'deleted'}=~/\.$id\./)) {                      unless (($contrib{'hidden'}=~/\.$id\./) || ($contrib{'deleted'}=~/\.$id\./)) {
                         if ($prevread <$contrib{$id.':timestamp'}) {                          if ($prevread <$contrib{$id.':timestamp'}) {
                             $$unread{$ressymb}{$unreadcount} = $id.': '.$contrib{$id.':subject'};                              $$unread{$ressymb}{$unreadcount} = $id.': '.$contrib{$id.':subject'};
                             $unreadcount ++;                              $unreadcount ++;
                             push(@{$newdiscussions}, $ressymb);  
                         }                          }
                     }                      }
                 }                  }
             }              }
         }              if ($unreadcount) { push(@{$newdiscussions}, $ressymb); }
    }
   
 # Check for ungraded problems  # Check for ungraded problems
         if ($resource->is_problem()) {          if ($resource->is_problem()) {
             my $ctr = 0;              my $ctr = 0;
             my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb);              my ($map,$ind,$url)=&Apache::lonnet::decode_symb($symb);
             my ($partlist,$handgrade,$responseType) = &Apache::grades::response_type($url,$symb);      my $partlist=$resource->parts();
             foreach my $student (keys(%$classlist)) {      my $handgradeable;
                 my ($uname,$udom) = split(/:/,$student);      foreach my $part (@$partlist) {
                 my %status=&Apache::grades::student_gradeStatus($url,$symb,$udom,$uname,$partlist);   if ($resource->handgrade($part) eq 'yes') {
                 my $submitted = 0;      $handgradeable=1; last;
                 my $graded = 0;   }
                 foreach (keys(%status)) {      }
                     $submitted = 1 if ($status{$_} ne 'nothing');      if ($handgradeable) {
                     $graded = 1 if ($status{$_} !~ /^correct/);   foreach my $student (keys(%$classlist)) {
                     my ($foo,$partid,$foo1) = split(/\./,$_);      my ($uname,$udom) = split(/:/,$student);
                     if ($status{'resource.'.$partid.'.submitted_by'} ne '') {      my %status=&Apache::grades::student_gradeStatus($url,$symb,$udom,$uname,$partlist);
                         $submitted = 0;      my $submitted = 0;
                     }      my $ungraded = 0;
                 }      foreach (keys(%status)) {
                 next if (!$submitted || !$graded);   $submitted = 1 if ($status{$_} ne 'nothing');
                 $ctr ++;   $ungraded = 1 if ($status{$_} =~ /^ungraded/);
             }   my ($foo,$partid,$foo1) = split(/\./,$_);
             if ($ctr) {   if ($status{'resource.'.$partid.'.submitted_by'} ne '') {
                 $$ungraded{$symb}{count} = $ctr;      $submitted = 0;
                 $$ungraded{$symb}{title} = $title;   }
                 push(@{$tograde}, $symb);      }
             }      next if (!$submitted || !$ungraded);
       $ctr ++;
    }
    if ($ctr) {
       $$ungraded{$symb}{count} = $ctr;
       $$ungraded{$symb}{title} = $title;
       push(@{$tograde}, $symb);
    }
       }
         }          }
   
 # Check for bombs  # Check for bombs
         if ($resource->getErrors()) {          if ($resource->getErrors()) {
             my $errors = $resource->getErrors();              my $errors = $resource->getErrors();
       $errors =~ s/^,//;
             my @bombs = split(/,/, $errors);              my @bombs = split(/,/, $errors);
             my $errorcount = scalar(@bombs);              my $errorcount = scalar(@bombs);
             my $errorlink = '<a href="/adm/email?display='.              my $errorlink = '<a href="/adm/email?display='.
                             &Apache::lonnet::escape($$bombs[0]).'">';                              &Apache::lonnet::escape($bombs[0]).'">'.
                               $title.'</a>';
             $$bombed{$symb}{errorcount} = $errorcount;              $$bombed{$symb}{errorcount} = $errorcount;
             $$bombed{$symb}{errorlink} = $errorlink;              $$bombed{$symb}{errorlink} = $errorlink;
             push(@{$bombs}, $symb);              push(@{$bombs}, $symb);
         }          }
   # Compile maxtries and degree of difficulty for problem parts
           my @parts = @{$resource->parts()};
           my %stats;
           my %lastreset = ();
           my $warning = 0;
           my $rowColor;
           foreach my $part (@parts) {
               %{$stats{$part}} = ();
               my ($attempts,$users,$corrects,$degdiff,$av_attempts);
               if (exists($resourcetracker{$symb."\0".$part."\0attempts"})) {
                   $attempts = $resourcetracker{$symb."\0".$part."\0attempts"};
               }
               if (exists($resourcetracker{$symb."\0".$part."\0users"})) {
                   $users = $resourcetracker{$symb."\0".$part."\0users"};
               }
               if (exists($resourcetracker{$symb."\0".$part."\0correct"})) {
                   $corrects = $resourcetracker{$symb."\0".$part."\0correct"};
               }
               if ($attempts > 0) {
                   $degdiff =  1 - ($corrects/$attempts);
                   $degdiff = sprintf("%.2f",$degdiff);
               }
               if ($users > 0) {
                   $av_attempts = $attempts/$users;
                   $av_attempts = sprintf("%.2f",$av_attempts);
               }
               if ((($degdiff ne '' && $degdiff >= $$threshold{'degdiff'}) || ($av_attempts ne '' && $av_attempts >= $$threshold{'av_attempts'})) && ($users >= $$threshold{'numstudents'})) {
                   $stats{$part}{degdiff} = $degdiff;
                   $stats{$part}{attempts} = $av_attempts;
                   $stats{$part}{users} = $users;
    $lastreset{$part} = $resourcetracker{$symb."\0".$part."\0resettime"};
                   $warning = 1;
               }
           }
           if ($warning) {
               if ($warningnum %2 == 1) {
                   $rowColor = $rowColor1;
               } else {
                   $rowColor = $rowColor2;
               }
               $$triggered{$symb}{title} = $resource->title;
               foreach my $part (@parts) {
                   if (exists($stats{$part}{users})) {
                       my $resetname = 'reset_'.&Apache::lonnet::escape($symb."\0".$part);
                       my $resettitle = 'title_'.&Apache::lonnet::escape($symb."\0".$part);
                       if ($$triggered{$symb}{numparts}) {
                           $$triggered{$symb}{text} .= '<tr bgcolor="'.$rowColor.'">'."\n";
                       }
                       if (@parts > 1) {
                           $$triggered{$symb}{text} .= '
                            <td align="right"><small>part - '.$part.'<small></td>';
                       } else {
                           $$triggered{$symb}{text} .= '
                            <td align="right"><small>single part</small></td>';
                       }
                       $$triggered{$symb}{text} .= '
                            <td align="right"><small>'.$stats{$part}{users}.'</small></td>
                            <td align="right"><small>'.$stats{$part}{attempts}.'</small></td>
                            <td align="right"><small>'.$stats{$part}{degdiff}.'</small></td>
                            <td align="right"><small>'.$lastreset{$part}.'</small></td>
                            <td align="right"><small><input type="checkbox" name="'.$resetname.'" /><input type="hidden" name="'.$resettitle.'" value="'.&Apache::lonnet::escape($$triggered{$symb}{title}).'" /></td> 
                           </tr>';
                       $$triggered{$symb}{numparts} ++;
                   }
               }
               push(@{$warnings},$symb);
               $warningnum ++;
           }
       }
   }
   
   sub get_curr_thresholds {
       my ($threshold,$cdom,$crs) = @_;
       my %coursesettings = &Apache::lonnet::dump('environment',
                                        $cdom,$crs,'internal.threshold');
       if (exists($coursesettings{'internal.threshold_av_attempts'})) {
           $$threshold{'av_attempts'} = $coursesettings{'internal.threshold_av_attempts'};
       }
       if (exists($coursesettings{'internal.threshold_degdiff'})) {
           $$threshold{'degdiff'} = $coursesettings{'internal.threshold_degdiff'};
       }
       if (exists($coursesettings{'internal.threshold_numstudents'})) {
           $$threshold{'numstudents'} = $coursesettings{'internal.threshold_numstudents'};
     }      }
 # Compile maxtries and degree of difficulty.  }
   
   sub process_reset {
       my ($dom,$crs) = @_;
       my $result = '<b>Counters reset for following problems (and parts):</b><br />';
       my @agg_types = ('attempts','users','correct');
       my %agg_titles = (
                        attempts => 'Number of submissions',
                        users => 'Students with submissions',
                        correct => 'Number of correct submissions',
                        );
       my @resets = ();
       my %titles = ();
       foreach my $key (keys(%env)) {
           next if ($key !~ /^form\.reset_(.+)$/);
           my $title = &Apache::lonnet::unescape($env{'form.title_'.$1});
           my $reset_item = &Apache::lonnet::unescape($1);
           my %curr_aggregates = &Apache::lonnet::dump('nohist_resourcetracker',$dom,$crs,$reset_item);
           my %aggregates = ();
           my ($symb,$part) = split(/\0/,$reset_item);
           foreach my $type (@agg_types) {
               $aggregates{$reset_item."\0".$type} = 0;
           }  
    $aggregates{$reset_item."\0".'resettime'} = time;
           my $putresult = &Apache::lonnet::put('nohist_resourcetracker',\%aggregates,
                             $dom,$crs);
           if ($putresult eq 'ok') {
               $result .= $title.' -part '.$part.': ';
               my %new_aggregates = &Apache::lonnet::dump('nohist_resourcetracker',$dom,$crs,$reset_item);
               foreach my $type (@agg_types) {
                   $result .= $agg_titles{$type}.' = '.$new_aggregates{$reset_item."\0".$type}.'; ';
               }
               $result =~ s/; $//;
               $result .= '<br />';
           } else {
               $result = $title.' -part '.$part.': '.&mt('Unable to reset counters to zero due to [_1]',$putresult).'.<br />'."\n";
           }
       }
       return $result;
   }
   
   sub process_update {
       my ($dom,$crs,$threshold_titles) = @_;
       my $setoutput = '<b>Changes to threshold(s) for problem tracking:</b><br />';
       foreach (keys %env) {
           next if ($_!~/^form\.(.+)\_setparmval$/);
           my $name  = $1;
           my $value = $env{'form.'.$name.'_value'};
           if ($name && defined($value)) {
               my $put_result = &Apache::lonnet::put('environment',
                                                     {$name=>$value},$dom,$crs);
              
               my ($shortname) = ($name =~ /^internal\.threshold_(.+)$/); 
               if ($put_result eq 'ok') {
                   $setoutput.=&mt('Set threshold for [_1] to [_2]',
    '<b>'.$$threshold_titles{$shortname}.'</b>',
    '<b>'.$value.'</b>').'<br />';
       } else {
                   $setoutput.=&mt('Unable to set threshold for [_1] to [_2] due to [_3].',
    '<b>'.$name.'</b>','<b>'.$value.'</b>',
    '<tt>'.$put_result.'</tt>').'<br />';
               }
           }
       }
       return $setoutput;
 }  }
   
 sub getmail {  sub getmail {
Line 505  sub getmail { Line 767  sub getmail {
 # Check for unread mail in course  # Check for unread mail in course
     my $msgcount = 0;      my $msgcount = 0;
   
     my @messages = &Apache::lonnet::getkeys('nohist_email');      my @messages = sort(&Apache::lonnet::getkeys('nohist_email'));
     foreach my $message (@messages) {      foreach my $message (@messages) {
  my $msgid=&Apache::lonnet::escape($message);   my $msgid=&Apache::lonnet::escape($message);
         my ($sendtime,$shortsubj,$fromname,$fromdom,$fromcid,$status)=          my ($sendtime,$shortsubj,$fromname,$fromdom,$status,$fromcid)=
             &Apache::lonmsg::unpackmsgid($msgid);              &Apache::lonmsg::unpackmsgid($msgid);
         if ($fromcid eq $ENV{'request.course.id'}) {          if (($fromcid) && ($fromcid eq $env{'request.course.id'})) {
             if (defined($sendtime) && $sendtime!~/error/) {              if (defined($sendtime) && $sendtime!~/error/) {
                 my $numsendtime = $sendtime;                  my $numsendtime = $sendtime;
                 $sendtime = &Apache::lonlocal::locallocaltime($sendtime);                  $sendtime = &Apache::lonlocal::locallocaltime($sendtime);
                 if ($status eq 'new') {                  if ($status eq 'new') {
                     $$msgcount ++;                      $msgcount ++;
                       if ($shortsubj eq '') {
                           $shortsubj = &mt('No subject');
                       }
                       $shortsubj = &Apache::lonnet::unescape($shortsubj);
                     push(@{$newmsgs}, {                      push(@{$newmsgs}, {
                         msgid    => $msgid,                          msgid    => $msgid,
                         sendtime => $sendtime,                          sendtime => $sendtime,
                         shortsub => &Apache::lonnet::unescape($shortsubj),                          shortsub => $shortsubj,
                         from     => $fromname,                          from     => $fromname,
                         fromdom  => $fromdom                          fromdom  => $fromdom
                         });                          });
Line 533  sub getmail { Line 799  sub getmail {
     my $result = '';      my $result = '';
     my $critmsgcount = 0;      my $critmsgcount = 0;
     foreach my $msgid (sort(keys(%what))) {      foreach my $msgid (sort(keys(%what))) {
         my ($sendtime,$shortsubj,$fromname,$fromdom,$fromcid,$status)=          my ($sendtime,$shortsubj,$fromname,$fromdom,$status,$fromcid)=
             &Apache::lonmsg::unpackmsgid($_);              &Apache::lonmsg::unpackmsgid($msgid);
         if ($fromcid eq  $ENV{'request.course.id'}) {          if (($fromcid) && ($fromcid eq  $env{'request.course.id'})) {
             if (defined($sendtime) && $sendtime!~/error/) {              if (defined($sendtime) && $sendtime!~/error/) {
                 my $numsendtime = $sendtime;                  my $numsendtime = $sendtime;
                 $sendtime = &Apache::lonlocal::locallocaltime($sendtime);                  $sendtime = &Apache::lonlocal::locallocaltime($sendtime);
                 $critmsgcount ++;                  $critmsgcount ++;
                   if ($shortsubj eq '') {
                       $shortsubj = &mt('No subject');
                   }
                   $shortsubj = &Apache::lonnet::unescape($shortsubj);
                 push(@{$critmsgs}, {                  push(@{$critmsgs}, {
                         msgid    => $msgid,                          msgid    => $msgid,
                         sendtime => $sendtime,                          sendtime => $sendtime,
                         shortsub => &Apache::lonnet::unescape($shortsubj),                          shortsub => $shortsubj,
                         from     => $fromname,                          from     => $fromname,
                         fromdom  => $fromdom                          fromdom  => $fromdom
                         });                          });
Line 554  sub getmail { Line 824  sub getmail {
 }  }
   
 sub cmp_title {  sub cmp_title {
     my ($atitle,$btitle) = (lc($_[0]->compTitle),lc($_[1]->compTitle));      my ($a,$b,$res_title) = @_;
       my ($atitle,$btitle) = (lc($$res_title{$a}),lc($$res_title{$b}));
     $atitle=~s/^\s*//;      $atitle=~s/^\s*//;
     $btitle=~s/^\s*//;      $btitle=~s/^\s*//;
     return $atitle cmp $btitle;      return $atitle cmp $btitle;
 }  }
   
   1;

Removed from v.1.4  
changed lines
  Added in v.1.29


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>
500 Internal Server Error

Internal Server Error

The server encountered an internal error or misconfiguration and was unable to complete your request.

Please contact the server administrator at root@localhost to inform them of the time this error occurred, and the actions you performed just before this error.

More information about this error may be available in the server error log.