Diff for /loncom/interface/Attic/lonchart.pm between versions 1.1 and 1.43

version 1.1, 2001/01/31 23:21:06 version 1.43, 2002/06/05 05:05:38
Line 1 Line 1
 # The LearningOnline Network with CAPA  # The LearningOnline Network with CAPA
   # (Publication Handler
   #
   # $Id$
   #
   # Copyright Michigan State University Board of Trustees
   #
   # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
   #
   # LON-CAPA is free software; you can redistribute it and/or modify
   # it under the terms of the GNU General Public License as published by
   # the Free Software Foundation; either version 2 of the License, or
   # (at your option) any later version.
   #
   # LON-CAPA is distributed in the hope that it will be useful,
   # but WITHOUT ANY WARRANTY; without even the implied warranty of
   # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   # GNU General Public License for more details.
   #
   # You should have received a copy of the GNU General Public License
   # along with LON-CAPA; if not, write to the Free Software
   # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   #
   # /home/httpd/html/adm/gpl.txt
   #
   # http://www.lon-capa.org/
   #
 # Homework Performance Chart  # Homework Performance Chart
 #  #
 # (Navigate Maps Handler  # (Navigate Maps Handler
Line 6 Line 32
 # (Page Handler  # (Page Handler
 #  #
 # (TeX Content Handler  # (TeX Content Handler
 #  # YEAR=2000
 # 05/29/00,05/30 Gerd Kortemeyer)  # 05/29/00,05/30 Gerd Kortemeyer)
 # 08/30,08/31,09/06,09/14,09/15,09/16,09/19,09/20,09/21,09/23,  # 08/30,08/31,09/06,09/14,09/15,09/16,09/19,09/20,09/21,09/23,
 # 10/02,10/10,10/14,10/16,10/18,10/19,10/31,11/6,11/14,11/16 Gerd Kortemeyer)  # 10/02,10/10,10/14,10/16,10/18,10/19,10/31,11/6,11/14,11/16 Gerd Kortemeyer)
   # YEAR=2001
   # 3/1/1,6/1,17/1,29/1,30/1,31/1 Gerd Kortemeyer)
   # 7/10/01 Behrouz Minaei
   # 9/8 Gerd Kortemeyer
   # 10/1, 10/19, 11/17, 11/22, 11/24, 11/28 12/18 Behrouz Minaei
   # YEAR=2002
   # 2/1, 2/6, 2/19, 2/28 Behrouz Minaei
 #  #
 # 3/1/1,6/1,17/1,29/1,30/1 Gerd Kortemeyer)  ###
 #  
 # 1/31 Gerd Kortemeyer  
   
 package Apache::lonchart;  package Apache::lonchart;
   
 use strict;  use strict;
 use Apache::Constants qw(:common :http);  use Apache::Constants qw(:common :http);
 use Apache::lonnet();  use Apache::lonnet();
   use Apache::loncommon();
 use HTML::TokeParser;  use HTML::TokeParser;
 use GDBM_File;  use GDBM_File;
   
 # -------------------------------------------------------------- Module Globals  # -------------------------------------------------------------- Module Globals
 my %hash;  my %hash;
   my %CachData;
 my @cols;  my @cols;
 my @rowlabels;  my $r;
 my @students;  my $c;
    
 # ------------------------------------------------------------- Find out status  # ------------------------------------------------------------- Find out status
   
 sub astatus {  sub ExtractStudentData {
     my $rid=shift;      my ($name,$coid)=@_;
     my $code=' ';      my ($sname,$sdom) = split(/\:/,$name);
     $rid=~/(\d+)\.(\d+)/;      my $ResId;
     my $symb=&Apache::lonnet::declutter($hash{'map_id_'.$1}).'___'.$2.'___'.      my $Code;
      &Apache::lonnet::declutter($hash{'src_'.$rid});      my $Tries;
     my $answer=&Apache::lonnet::reply(      my $Wrongs;
               "restore:$ENV{'user.domain'}:$ENV{'user.name'}:".      my %TempHash;
               $ENV{'request.course.id'}.':'.      my $Version;
               &Apache::lonnet::escape($symb),      my $problemsCorrect;
               "$ENV{'user.home'}");      my $problemsSolved;
     my %returnhash=();      my $totalProblems;
     map {      my $LatestVersion;
  my ($name,$value)=split(/\=/,$_);      my $Str;
         $returnhash{&Apache::lonnet::unescape($name)}=  
                     &Apache::lonnet::unescape($value);      # Handle Student information ------------------------------------------
     } split(/\&/,$answer);      # Handle errors
     if ($returnhash{'version'}) {  #    if($CachData{$name.':error'} =~ /environment/) {
        my $version;  # my $errorMessage = $CachData{$name.':error'};
        for ($version=1;$version<=$returnhash{'version'};$version++) {  # return '<td>'.$sname.'</td><td>'.$sdom.
           map {  #    '</td><td><font color="#000088">'.$errorMessage.'</font></td>';
              $returnhash{$_}=$returnhash{$version.':'.$_};  #    }
           } split(/\:/,$returnhash{$version.':keys'});  
        }      # Handle user data
        my $totaltries=0;      $Str  = '<td><pre>'.$sname.'</pre></td><td><pre>'.$sdom;
        map {      $Str .= '</pre></td><td><pre>'.$CachData{$name.':section'};
            if (($_=~/\.(\w+)\.solved$/) && ($_!~/^\d+\:/)) {      $Str .= '</pre></td><td><pre>'.$CachData{$name.':id'};
                my $part=$1;      $Str .= '</pre></td><td><pre>'.$CachData{$name.':fullname'};
        if ($returnhash{$_} eq 'correct_by_student') {      $Str .= '</pre></td>';
                    unless (($code eq '.') || ($code eq '-')) { $code='*'; }  
                    $totaltries+=$returnhash{'resource.'.$part.'.tries'};      if($CachData{$name.':error'} =~ /course/) {
                } elsif ($returnhash{$_} eq 'correct_by_override') {   return $Str;
                    unless (($code eq '.') || ($code eq '-')) { $code='+'; }  # my $errorMessage = 'May have no course data or '.
                } elsif ($returnhash{$_} eq 'incorrect_attempted') {  #                   $CachData{$name.':error'};
                    $code='.';  # return '<td>'.$sname.'</td><td>'.$sdom.
                } elsif ($returnhash{$_} eq 'incorrect_by_override') {  #    '</td><td><font color="#000088">'.$errorMessage.'</font></td>';
                    $code='-';      }
                } elsif ($returnhash{$_} eq 'excused') {  
                    unless (($code eq '.') || ($code eq '-')) { $code='x'; }      # Handle problem data ------------------------------------------------
                }      $Str .= '<td><pre>';
            }      $problemsCorrect = 0;
        } keys %returnhash;      $totalProblems = 0;
        if (($code eq '*') && ($totaltries<10)) { $code="$totaltries"; }      $problemsSolved = 0;
       my $IterationNo = 0;
       foreach $ResId (@cols) {
    if ($IterationNo == 0) {
       # Looks to be skipping start resource
       $IterationNo++; 
       next;
    }
   
    # ResId is 0 for sequences and pages, 
    # please check tracetable for changes
    if (!$ResId) {
       my $outputProblemsCorrect = sprintf( "%3d", $problemsCorrect );
       $Str .= '<font color="#007700">'.$outputProblemsCorrect.
       '</font></pre></td>';
       $Str .= '<td><pre>';
       $problemsSolved += $problemsCorrect;
       $problemsCorrect=0;
       next; 
    }
   
    # Set $1 and $2
    $ResId=~/(\d+)\.(\d+)/;
    my $meta=$hash{'src_'.$ResId};
    my $numberOfParts = 0;
    undef %TempHash;
    foreach (split(/\,/,&Apache::lonnet::metadata($meta,'keys'))) {
   #----------- Overwrite $1 in next statement ---------------------------------
       if ($_=~/^stores\_(\d+)\_tries$/) {
    my $Part=&Apache::lonnet::metadata($meta,$_.'.part');
    if ( $TempHash{"$Part"} eq '' ) { 
       $TempHash{"$Part"} = $Part;
       $TempHash{$numberOfParts}=$Part;
       $TempHash{"$Part.Code"} = ' ';  
       $numberOfParts++;
    }
       }
    }
   
   #----------- Using $1 and $2 -----------------------------------------------
    my $Prob = &Apache::lonnet::symbclean(
          &Apache::lonnet::declutter($hash{'map_id_'.$1} ).
                          '___'.$2.'___'.
                          &Apache::lonnet::declutter( $hash{'src_'.$ResId} ));
    $Code=' ';
    $Tries = 0;
    $LatestVersion = $CachData{$name.":version:$Prob"};
   
    if ( $LatestVersion ) {
       for ( my $Version=1; $Version<=$LatestVersion; $Version++ ) {
    my $vkeys = $CachData{$name.":$Version:keys:$Prob"};
    my @keys = split(/\:/,$vkeys);  
   
    foreach my $Key (@keys) {
   #---------------------- Changing $1 -------------------------------------------
       if (($Key=~/\.(\w+)\.solved$/) && ($Key!~/^\d+\:/)) {
   #---------------------- Using $1 -----------------------------------------------
    my $Part = $1;
    $Tries = $CachData{$name.":$Version:$Prob".
      ":resource.$Part.tries"};
    $TempHash{"$Part.Tries"}=($Tries) ? $Tries : 0;
    my $Val = $CachData{$name.":$Version:$Prob".
       ":resource.$Part.solved"};
    if    ($Val eq 'correct_by_student')   {$Code = '*';} 
    elsif ($Val eq 'correct_by_override')  {$Code = '+';}
    elsif ($Val eq 'incorrect_attempted')  {$Code = '.';} 
    elsif ($Val eq 'incorrect_by_override'){$Code = '-';}
    elsif ($Val eq 'excused')              {$Code = 'x';}
    elsif ($Val eq 'ungraded_attempted')   {$Code = '#';}
    else                                   {$Code = ' ';}
   
    $TempHash{"$Part.Code"} = $Code;
       }
    }
       }
   # Actually append problem to output (all parts)
       $Str.='<a href="/adm/grades?symb='.
                   &Apache::lonnet::escape($Prob).
                   '&student='.$sname.'&domain='.$sdom.'&command=submission">'; 
       for(my $n = 0; $n < $numberOfParts; $n++) {  
    my $part = $TempHash{$n};
    my $code2 = $TempHash{"$part.Code"};
    if($code2 eq '*') {
       $problemsCorrect++;
   # !!!!!!!!!!!------------------------- Should 10 not be maxtries? ------------
       if (($TempHash{"$part.Tries"}<10) ||
    ($TempHash{"$part.Tries"} eq '')) {
    $TempHash{"$part.Code"}=$TempHash{"$part.Tries"};
       }
    } elsif($code2 eq '+') {
       $problemsCorrect++;
    }
   
    $Str .= $TempHash{"$part.Code"};
   
    if($code2 ne 'x') {
       $totalProblems++;
    }
       }
       $Str.='</a>';
    } else {
       for(my $n=0; $n<$numberOfParts; $n++) {
    $Str.=' ';
    $totalProblems++;
       }
    }
     }      }
     return $code;  
       $Str .= '<td><pre><font color="#000088">'.$problemsSolved.
       ' / '.$totalProblems.'</font></pre></td>';
   
       return $Str;
   }
   
   sub CreateForm {
       my $OpSel1='';
       my $OpSel2='';
       my $OpSel3='';
       my $Status = $ENV{'form.status'};
       if ( $Status eq 'Any' ) { $OpSel3='selected'; }
       elsif ($Status eq 'Expired' ) { $OpSel2 = 'selected'; }
       else { $OpSel1 = 'selected'; }
   
       my $Ptr = '<form name=stat method=post action="/adm/chart" >'."\n";
       $Ptr .= '<b> Sort by: &nbsp; </b>'."\n";
       $Ptr .= '&nbsp;&nbsp;&nbsp;';
       $Ptr .= '<input type=submit name=sort value="User Name" />'."\n";
       $Ptr .= '&nbsp;&nbsp;&nbsp;';
       $Ptr .= '<input type=submit name=sort value="Last Name" />'."\n";
       $Ptr .= '&nbsp;&nbsp;&nbsp;';
       $Ptr .= '<input type=submit name=sort value="Section"/>'."\n";
       $Ptr .= '<br><br>';
       $Ptr .= '<b> Student Status: &nbsp; </b>'."\n".
               '<select name="status">'. 
               '<option '.$OpSel1.' >Active</option>'."\n".
               '<option '.$OpSel2.' >Expired</option>'."\n".
       '<option '.$OpSel3.' >Any</option> </select> '."\n";
       $Ptr .= '&nbsp;&nbsp;&nbsp;';
       $Ptr .= '<input type=submit name=sort value="Recalculate Chart"/>'."\n";
       $Ptr .= '</form>'."\n";
       $r->print( $Ptr );
   }
   
   sub CreateTableHeadings {
       $r->print('<tr>');
       $r->print('<td>User Name</td>');
       $r->print('<td>Domain</td>');
       $r->print('<td>Section</td>');
       $r->print('<td>PID</td>');
       $r->print('<td>Full Name</td>');
   
       my $ResId;
       my $IterationNo = 0;
       foreach $ResId (@cols) {
    if ($IterationNo == 0) {$IterationNo++; next;}
    if (!$ResId) { 
   #    my $PrNo = sprintf( "%3d", $ProbNo );
   #    $Str .= '<td><font color="#007700">Chapter '.$PrNo.'</font></td>';
       $r->print('<td><font color="#007700">Chapter '.'0'.'</font></td>');
    }
       }
   
       $r->print('</tr>');
       $r->rflush();
   
       return;
 }  }
   
 # ------------------------------------------------------------ Build page table  # ------------------------------------------------------------ Build page table
Line 84  sub tracetable { Line 280  sub tracetable {
     my ($rid,$beenhere)=@_;      my ($rid,$beenhere)=@_;
     unless ($beenhere=~/\&$rid\&/) {      unless ($beenhere=~/\&$rid\&/) {
        $beenhere.=$rid.'&';           $beenhere.=$rid.'&';  
   # new ... updating the map according to sequence and page
        if (defined($hash{'is_map_'.$rid})) {         if (defined($hash{'is_map_'.$rid})) {
            if ($hash{'map_type_'.$hash{'map_pc_'.$hash{'src_'.$rid}}}      my $cmap=$hash{'map_type_'.$hash{'map_pc_'.$hash{'src_'.$rid}}};
             eq 'sequence') {              if ( $cmap eq 'sequence' || $cmap eq 'page' ) { 
                $cols[$#cols+1]=0;                  $cols[$#cols+1]=0; 
            }             }
            if ((defined($hash{'map_start_'.$hash{'src_'.$rid}})) &&             if ((defined($hash{'map_start_'.$hash{'src_'.$rid}})) &&
Line 113  sub tracetable { Line 310  sub tracetable {
           }            }
        }         }
        if (defined($hash{'to_'.$rid})) {         if (defined($hash{'to_'.$rid})) {
           map {            foreach (split(/\,/,$hash{'to_'.$rid})){
               &tracetable($hash{'goesto_'.$_},$beenhere);                &tracetable($hash{'goesto_'.$_},$beenhere);
           } split(/\,/,$hash{'to_'.$rid});            }
        }         }
     }      }
 }  }
   
 # ================================================================ Main Handler  sub usection {
       my ($udom,$unam,$courseid,$ActiveFlag)=@_;
       $courseid=~s/\_/\//g;
       $courseid=~s/^(\w)/\/$1/;
   
       my %result=&Apache::lonnet::dump('roles',$udom,$unam);
   
       my($checkForError)=keys (%result);
       if($checkForError =~ /^(con_lost|error|no_such_host)/i) {
    return -1;
       }
   
 sub handler {      my $cursection='-1';
   my $r=shift;      my $oldsection='-1';
       my $status='Expired';
       foreach my $key (keys (%result)) {
    my $value = $result{$key};
           if ($key=~/^$courseid(?:\/)*(\w+)*\_st$/) {
               my $section=$1;
               if ($key eq $courseid.'_st') { $section=''; }
       my ($dummy,$end,$start)=split(/\_/,$value);
       my $now=time;
       my $notactive=0;
       if ($start) {
    if($now<$start) {
       $notactive=1;
    }
       }
       if($end) {
    if ($now>$end) {
       $notactive=1;
    }
       }
       if($notactive == 0) {
    $status='Active';
    $cursection=$section;
       }
       if($notactive == 1) {
    $oldsection=$section;
       }
    }
       }
       if($status eq $ActiveFlag) {
    if($cursection eq '-1') {
       return $oldsection;
    }
    return $cursection;
       }
       if($ActiveFlag eq 'Any') {
    if($cursection eq '-1') {
       return $oldsection;
    }
    return $cursection;
       }
       return '-1';
   }
   
   if (&Apache::lonnet::allowed('vgr',$ENV{'request.course.id'})) {  sub ProcessFullName {
 # ------------------------------------------- Set document type for header only      my ($name)=@_;
       my $Str = '';
   
       if($CachData{$name.':lastname'} ne '') {
    $Str .= $CachData{$name.':lastname'}.' ';
    if($CachData{$name.':generation'} ne '') {
       $Str .= $CachData{$name.':generation'};
    } else {
       chop($Str);
    }
    $Str .= ', ';
    if($CachData{$name.':firstname'} ne '') {
       $Str .= $CachData{$name.':firstname'}.' ';
    }
    if($CachData{$name.':middlename'} ne '') {
       $Str .= $CachData{$name.':middlename'};
    } else {
       chop($Str);
       if($CachData{$name.'firstname'} eq '') {
    chop($Str);
       }
    }
       } else {
    if($CachData{$name.':firstname'} ne '') {
       $Str .= $CachData{$name.':firstname'}.' ';
    }
    if($CachData{$name.':middlename'} ne '') {
       $Str .= $CachData{$name.':middlename'}.' ';
    }
    if($CachData{$name.':generation'} ne '') {
       $Str .= $CachData{$name.':generation'};
    } else {
       chop($Str);
    }
       }
   
   if ($r->header_only) {      return $Str;
        if ($ENV{'browser.mathml'}) {  }
            $r->content_type('text/xml');  
        } else {  
            $r->content_type('text/html');  
        }  
        $r->send_http_header;  
        return OK;  
    }  
   
   my $requrl=$r->uri;  sub DownloadStudentInformation {
 # ----------------------------------------------------------------- Tie db file      my ($name,$courseID)=@_;
   if ($ENV{'request.course.fn'}) {      my ($studentName,$studentDomain) = split(/\:/,$name);
       my $fn=$ENV{'request.course.fn'};      my $checkForError;
       if (-e "$fn.db") {      my $key;
           if (tie(%hash,'GDBM_File',"$fn.db",&GDBM_READER,0640)) {      my $Status=$CachData{$name.':Status'};
 # ------------------------------------------------------------------- Hash tied  
   #-----------------------------------------------------------------
       # Download student environment data, specifically the full name and id.
       my %studentInformation=&Apache::lonnet::get('environment',
    ['lastname','generation',
    'firstname','middlename',
    'id'],
    $studentDomain,$studentName);
       if($c->aborted()) {
    return;
       }
       ($checkForError)=keys (%studentInformation);
       if($checkForError =~ /^(con_lost|error|no_such_host)/i) {
    $CachData{$name.':error'}=
       'Could not download student environment data.';
   # return;
    $CachData{$name.':lastname'}='';
    $CachData{$name.':generation'}='';
    $CachData{$name.':firstname'}='';
    $CachData{$name.':middlename'}='';
    $CachData{$name.':fullname'}='';
    $CachData{$name.':id'}='';
       } else {
    $CachData{$name.':lastname'}=$studentInformation{'lastname'};
    $CachData{$name.':generation'}=$studentInformation{'generation'};
    $CachData{$name.':firstname'}=$studentInformation{'firstname'};
    $CachData{$name.':middlename'}=$studentInformation{'middlename'};
    $CachData{$name.':fullname'}=&ProcessFullName($name);
    $CachData{$name.':id'}=$studentInformation{'id'};
       }
   
       # Download student course data
       my %courseData=&Apache::lonnet::dump($courseID,$studentDomain,
    $studentName);
       if($c->aborted()) {
    return;
       }
       ($checkForError)=keys (%courseData);
       if($checkForError =~ /^(con_lost|error|no_such_host)/i) {
    $CachData{$name.':error'}='Could not download course data.';
   # return;
       } else {
    foreach $key (keys (%courseData)) {
       $CachData{$name.':'.$key}=$courseData{$key};
    }
       }
   
       # Get student's section number
       my $sec=&usection($studentDomain, $studentName, $courseID, $Status);
       if($sec != -1) {
    $CachData{$name.':section'}=sprintf('%3s',$sec);
       } else {
    $CachData{$name.':section'}='';
       }
   
 # ------------------------------------------------------------------ Build page      return;
   }
   
 # ---------------------------------------------------------------- Send headers  sub SortStudents {
   # --------------------------------------------------------------- Sort Students
       my $Pos = $ENV{'form.sort'};
       my @students = split(/:::/,$CachData{'NamesOfStudents'});
       my %sortData;
   
       if($Pos eq 'Last Name') {
    for(my $index=0; $index<$#students+1; $index++) {
       $sortData{$CachData{$students[$index].':fullname'}}=
    $students[$index];
    }
       } elsif($Pos eq 'Section') {
    for(my $index=0; $index<$#students+1; $index++) {
       $sortData{$CachData{$students[$index].':section'}.
         $students[$index]}=$students[$index];
    }
       } else {
    # Sort by user name
    for(my $index=0; $index<$#students+1; $index++) {
       $sortData{$students[$index]}=$students[$index];
    }
       }
   
              $r->content_type('text/html');      my @order = ();
              $r->send_http_header;      foreach my $key (sort keys(%sortData)) {
              $r->print(   push (@order,$sortData{$key});
   '<html><head><title>LON-CAPA Assessment Chart</title></head>');      }
   
      $r->print('<body bgcolor="#FFFFFF">'.  
                                     '<script>window.focus();</script>'.  
                            '<img align=right src=/adm/lonIcons/lonlogos.gif>'.  
                                     '<h1>Assessment Chart</h1>');  
   
 # ---------------------------------------------------------------- Course title      return @order;
   }
   
     $r->print('<h1>'.  sub CollectClasslist {
             $ENV{'course.'.$ENV{'request.course.id'}.'.description'}.'</h1>');  # -------------------------------------------------------------- Get class list
       my $cid=$ENV{'request.course.id'};
       my $chome=$ENV{'course.'.$cid.'.home'};
       my ($cdom,$cnum)=split(/\_/,$cid);
       my %classlist=&Apache::lonnet::dump('classlist',$cdom,$cnum);
       my @names = ();
   
       my($checkForError)=keys (%classlist);
       if($checkForError =~ /^(con_lost|error|no_such_host)/i) {
    $r->print('<h1>Could not access course data</h1>');
    push (@names, 'error');
    return @names;
       }
   
   # ------------------------------------- Calculate Status and number of students
       my $now=time;
       foreach my $name (sort(keys(%classlist))) {
    my $value=$classlist{$name};
    my ($end,$start)=split(/\:/,$value);
    my $active=1;
    my $Status=$ENV{'form.status'};
    $Status = ($Status) ? $Status : 'Active';
    if((($end) && $now > $end) && (($Status eq 'Active'))) { 
       $active=0; 
    }
    if(($Status eq 'Expired') && ($end == 0 || $now < $end)) {
       $active=0;
    }
    if($active) {
       push(@names,$name);
       $CachData{$name.':Status'}=$Status;
    }
       }
   
 # ------------------------------- This is going to take a while, produce output      $CachData{'NamesOfStudents'}=join(":::",@names);
   
              $r->rflush();      return @names;
   }
   
   sub BuildChart {
 # ----------------------- Get first and last resource, see if there is anything  # ----------------------- Get first and last resource, see if there is anything
       my $firstres=$hash{'map_start_/res/'.$ENV{'request.course.uri'}};
       my $lastres=$hash{'map_finish_/res/'.$ENV{'request.course.uri'}};
       if (!($firstres) || !($lastres)) {
    $r->print('<h3>Undefined course sequence</h3>');
    return;
       }
   
   # --------------- Find all assessments and put them into some linear-like order
       &tracetable($firstres,'&'.$lastres.'&');
   
               my $firstres=$hash{'map_start_/res/'.$ENV{'request.course.uri'}};  
               my $lastres=$hash{'map_finish_/res/'.$ENV{'request.course.uri'}};  
               if (($firstres) && ($lastres)) {  
 # ----------------------------------------------------------------- Render page  # ----------------------------------------------------------------- Render page
       &CreateForm();
   
                  my $cid=$ENV{'request.course.id'};      my $cid=$ENV{'request.course.id'};
                  my $chome=$ENV{'course.'.$cid.'.home'};      my $ChartDB = "/home/httpd/perl/tmp/$ENV{'user.name'}".
                  my ($cdom,$cnum)=split(/\_/,$cid);                    "_$ENV{'user.domain'}_$cid\_chart.db";
       my $isCached = 0;
       my @students;
       if ((-e "$ChartDB") && ($ENV{'form.sort'} ne 'Recalculate Chart')) {
    if (tie(%CachData,'GDBM_File',"$ChartDB",&GDBM_READER,0640)) {
       $isCached = 1;
       @students=&SortStudents();
    } else {
       $r->print("Unable to tie hash to db file");
       $r->rflush();
       return;
    }
       } else {
    if (tie(%CachData,'GDBM_File',$ChartDB,&GDBM_NEWDB,0640)) {
       $isCached = 0;
       @students=&CollectClasslist();
       if($students[0] eq 'error') {
    return;
       }
    } else {
       $r->print("Unable to tie hash to db file");
       return;
    }
       }
   
 # ---------------------------------------------- Read class list and row labels      $r->print('<h3>'.($#students+1).' students</h3>');
       $r->rflush();
   
     undef @rowlabels;  # ----------------------------------------------------------------- Start table
     undef @students;      $r->print('<table><tbody>');
   #    &CreateTableHeadings();
       my @updateStudentList = ();
       foreach my $student (@students) {
    if($c->aborted()) {
       if($isCached == 0) {
    $CachData{'NamesOfStudents'}=join(":::",@updateStudentList);
       }
       last;
    }
    if($isCached == 0) {
       &DownloadStudentInformation($student,$cid);
       push (@updateStudentList, $student);
    }
    my $Str=&ExtractStudentData($student,$cid);
    $r->print('<tr>'.$Str.'</tr>');
       }
       $r->print('</tbody></table>');
   
     my $classlst=&Apache::lonnet::reply      untie(%CachData);
                                  ('dump:'.$cdom.':'.$cnum.':classlist',$chome);  
     my $now=time;  
     unless ($classlst=~/^error\:/) {  
         map {  
             my ($name,$value)=split(/\=/,$_);  
             my ($end,$start)=split(/\:/,&Apache::lonnet::unescape($value));  
             my $active=1;  
             if (($end) && ($now>$end)) { $active=0; }  
             if ($active) {  
                 my $thisindex=$#students+1;  
                 $name=&Apache::lonnet::unescape($name);  
                 $students[$thisindex]=$name;  
                 my ($sname,$sdom)=split(/\:/,$name);  
                 my $ssec=&Apache::lonnet::usection($sdom,$sname,$cid);  
                 if ($ssec==-1) {  
                     $rowlabels[$thisindex]=  
                       'Data not available: '.$name;  
                 } else {  
                     my %reply=&Apache::lonnet::idrget($sdom,$sname);  
                     my $reply=&Apache::lonnet::reply('get:'.$sdom.':'.$sname.  
       ':environment:firstname&middlename&lastname&generation',  
                       &Apache::lonnet::homeserver($sname,$sdom));  
                     $rowlabels[$thisindex]=  
                       $ssec.' '.$reply{$sname}.' ';  
                     map {  
                      $rowlabels[$thisindex].=&Apache::lonnet::unescape($_).' ';  
                     } split(/\&/,$reply);  
                 }  
             }  
         } sort split(/\&/,$classlst);  
   
     } else {      return;
         $r->print('<h1>Could not access course data</h1>');  }
     }  
   
     my $allstudents=$#students+1;  sub Start {
     $r->print('<h3>'.$allstudents.' students</h3>');      $r->print('<head><title>'.
                 'LON-CAPA Assessment Chart</title></head>');
       $r->print('<body bgcolor="#FFFFFF">'.
                 '<script>window.focus();</script>'.
                 '<img align=right src=/adm/lonIcons/lonlogos.gif>'.
                 '<h1>Assessment Chart</h1>');
   # ---------------------------------------------------------------- Course title
       $r->print('<h1>'.$ENV{'course.'.$ENV{'request.course.id'}.
                 '.description'}.'</h1><h3>'.localtime().
                 "</h3><p><pre>1..9: correct by student in 1..9 tries\n".
                 "   *: correct by student in more than 9 tries\n".
         "   +: correct by override\n".
                 "   -: incorrect by override\n".
         "   .: incorrect attempted\n".
         "   #: ungraded attempted\n".
                 "    : not attempted\n".
         "   x: excused</pre><p>"); 
   # ------------------------------- This is going to take a while, produce output
     $r->rflush();      $r->rflush();
   
 # --------------- Find all assessments and put them into some linear-like order      &BuildChart();
   
    &tracetable($firstres,'&'.$lastres.'&');      $r->print('</body>');
   
 # ----------------------------------------------------------------- Start table      return;
   }
   
                           $r->print('<p><pre>');  # ================================================================ Main Handler
    my $index;  
                            for ($index=0;$index<=$#students;$index++) {  
                               $r->print(  
                                        substr($students[$index].  
        '                                                        ',0,14).' ! '.  
  substr($rowlabels[$index].  
        '                                                        ',0,45).' ! ');  
                               map {  
                                   if ($_) {  
                                      $r->print(&astatus($_,$students[$index]));  
                                   } else {  
                                      $r->print(' ! ');  
                                   }  
                               } @cols;  
                               $r->print("\n");  
                               $r->rflush();  
                           }  
                           $r->print('</pre>');  
   
      } else {  sub handler {
                  $r->print('<h3>Undefined course sequence</h3>');      undef %hash;
              }      undef %CachData;
       undef @cols;
   
       $r=shift;
       $c = $r->connection;
       if (&Apache::lonnet::allowed('vgr',$ENV{'request.course.id'})) {
   # ------------------------------------------- Set document type for header only
    if ($r->header_only) {
       if ($ENV{'browser.mathml'}) {
    $r->content_type('text/xml');
       } else {
    $r->content_type('text/html');
       }
       &Apache::loncommon::no_cache($r);
       $r->send_http_header;
       return OK;
    }
   
                       $r->print('</body></html>');   my $requrl=$r->uri;
                                        # ----------------------------------------------------------------- Tie db file
    if ($ENV{'request.course.fn'}) {
       my $fn=$ENV{'request.course.fn'};
       if (-e "$fn.db") {
    if (tie(%hash,'GDBM_File',"$fn.db",&GDBM_READER,0640)) {
   # ------------------------------------------------------------------- Hash tied
   # ---------------------------------------------------------------- Send headers
       $r->content_type('text/html');
       $r->send_http_header;
       $r->print('<html>');
       &Start();
       $r->print('</html>');
       $r->rflush();
 # ------------------------------------------------------------- End render page  # ------------------------------------------------------------- End render page
               } else {   } else {
                   $r->content_type('text/html');      $r->content_type('text/html');
                   $r->send_http_header;      $r->send_http_header;
   $r->print('<html><body>Coursemap undefined.</body></html>');      $r->print('<html><body>Coursemap undefined.</body></html>');
               }   }
 # ------------------------------------------------------------------ Untie hash  # ------------------------------------------------------------------ Untie hash
               unless (untie(%hash)) {   unless (untie(%hash)) {
                    &Apache::lonnet::logthis("<font color=blue>WARNING: ".      &Apache::lonnet::logthis("<font color=blue>WARNING: ".
                        "Could not untie coursemap $fn (browse).</font>");        "Could not untie coursemap $fn (browse).</font>"); 
               }   }
   
 # -------------------------------------------------------------------- All done  # -------------------------------------------------------------------- All done
       return OK;   return OK;
 # ----------------------------------------------- Errors, hash could no be tied  # ----------------------------------------------- Errors, hash could no be tied
       }      }
   } else {   } else {
   $ENV{'user.error.msg'}="$requrl:bre:0:0:Course not initialized";      $ENV{'user.error.msg'}="$requrl:bre:0:0:Course not initialized";
   return HTTP_NOT_ACCEPTABLE;       return HTTP_NOT_ACCEPTABLE; 
 }   }
 } else {      } else {
       $ENV{'user.error.msg'}=   $ENV{'user.error.msg'}=
         $r->uri.":vgr:0:0:Cannot view grades for complete course";          $r->uri.":vgr:0:0:Cannot view grades for complete course";
       return HTTP_NOT_ACCEPTABLE;    return HTTP_NOT_ACCEPTABLE; 
       }
 }  
 }  }
 1;  1;
 __END__  __END__
   
   
   
   
   
   
   

Removed from v.1.1  
changed lines
  Added in v.1.43


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>