Diff for /loncom/interface/lontrackstudent.pm between versions 1.9 and 1.15

version 1.9, 2004/12/13 21:08:09 version 1.15, 2005/04/07 06:56:23
Line 44  package Apache::lontrackstudent; Line 44  package Apache::lontrackstudent;
   
 use strict;  use strict;
 use Apache::Constants qw(:common :http);  use Apache::Constants qw(:common :http);
 use Apache::lonnet();  use Apache::lonmysql;
   use Apache::lonnet;
 use Apache::lonlocal;  use Apache::lonlocal;
 use Time::HiRes;  use Time::HiRes;
   
Line 55  sub get_data { Line 56  sub get_data {
     &Apache::lonhtmlcommon::Update_PrgWin      &Apache::lonhtmlcommon::Update_PrgWin
         ($r,$prog_state,&mt('Composing Query'));          ($r,$prog_state,&mt('Composing Query'));
     #      #
     my $query = &build_query($mode);  
     # Allow the other server to begin processing the data before we ask for it.      # Allow the other server to begin processing the data before we ask for it.
     sleep(5);      sleep(5);
     &Apache::lonnet::logthis('sending query '.$query);      #
       my $max_time = &get_max_time_in_db($r,$prog_state);
       if (defined($max_time)) {
           $r->print('<h3>'.&mt('Activity data goes to [_1]',
                                &Apache::lonlocal::locallocaltime($max_time)).
                     '</h3>');
           $r->rflush();
       } else {
           $r->print('<h3>'.&mt('Unable to retrieve any data.  Please reload this page and try again.').'</h3>');
           return;
       }
       my $query = &build_query($mode);
     ##      ##
     ## Send it along      ## Send it along
     my $home = $ENV{'course.'.$ENV{'request.course.id'}.'.home'};      my $home = $env{'course.'.$env{'request.course.id'}.'.home'};
     my $reply=&Apache::lonnet::metadata_query($query,undef,undef,[$home]);      my $reply=&Apache::lonnet::metadata_query($query,undef,undef,[$home]);
     if (ref($reply) ne 'HASH') {      if (ref($reply) ne 'HASH') {
         $r->print('<h2>'.          $r->print('<h2>'.
Line 90  sub get_data { Line 101  sub get_data {
         $r->print(&mt('Please try again in a few minutes.'));          $r->print(&mt('Please try again in a few minutes.'));
         return;          return;
     }      }
 #    $r->print('<h2>'.&mt('Elapsed Time = [_1] seconds',  
 #                         time-$starttime).'</h2>');  
     $r->rflush();      $r->rflush();
       #
     &Apache::lonhtmlcommon::Update_PrgWin      &Apache::lonhtmlcommon::Update_PrgWin
         ($r,$prog_state,&mt('Parsing results'));          ($r,$prog_state,&mt('Parsing results'));
 #    $r->print('<h2>'.      #
 #              &mt('Reloading this page may result in newer data').  
 #              '</h2>');  
     &output_results($r,$results_file,$navmap,$mode);      &output_results($r,$results_file,$navmap,$mode);
     &Apache::lonhtmlcommon::Update_PrgWin($r,$prog_state,&mt('Finished!'));      &Apache::lonhtmlcommon::Update_PrgWin($r,$prog_state,&mt('Finished!'));
     return;      return;
 }  }
   
   sub table_names {
       my $cid = $env{'request.course.id'};
       my $domain = $env{'course.'.$cid.'.domain'};
       my $home = $env{'course.'.$cid.'.home'};
       my $course = $env{'course.'.$cid.'.num'};
       my $prefix = $course.'_'.$domain.'_';
       #
       my %tables = 
           ( student =>&Apache::lonmysql::fix_table_name($prefix.'students'),
             res     =>&Apache::lonmysql::fix_table_name($prefix.'resource'),
             machine =>&Apache::lonmysql::fix_table_name($prefix.'machine_table'),
             activity=>&Apache::lonmysql::fix_table_name($prefix.'activity'),
             );
       return %tables;
   }
   
   sub get_max_time_in_db {
       my ($r,$prog_state) = @_;
       my %table = &table_names();
       my $query = qq{SELECT MAX(time) FROM $table{'activity'} };
       #
       my $home = $env{'course.'.$env{'request.course.id'}.'.home'};
       my $reply=&Apache::lonnet::metadata_query($query,undef,undef,[$home]);
       if (ref($reply) ne 'HASH') {
           return undef;
       }
       my $results_file = $r->dir_config('lonDaemons').'/tmp/'.$reply->{$home};
       my $endfile = $results_file.'.end';
       ##
       ## Check for the results
       &Apache::lonhtmlcommon::Update_PrgWin
           ($r,$prog_state,&mt('Waiting for results'));
       my $maxtime = 500;
       my $starttime = time;
       while (! -e $endfile && (time-$starttime < $maxtime)) {
           &Apache::lonhtmlcommon::Update_PrgWin
               ($r,$prog_state,&mt('Waiting up to [_1] seconds for results',
                                   $starttime+$maxtime-time));
           sleep(1);
       }
       if (! -e $endfile) {
           $r->print('<h2>'.
                     &mt('Unable to retrieve data.').'</h2>');
           $r->print(&mt('Please try again in a few minutes.'));
           return undef;
       }
       $r->rflush();
       #
       &Apache::lonhtmlcommon::Update_PrgWin
           ($r,$prog_state,&mt('Parsing results'));
       #
       if (! open(TIMEDATA,$results_file)) {
           $r->print('<h2>'.&mt('Unable to read results file.').'</h2>'.
                     '<p>'.
                     &mt('This is a serious error and has been logged.  '.
                         'You should contact your system administrator '.
                         'to resolve this issue.').
                     '</p>');
           return;
       }
       #
       my $timestr = '';
       while (my $line = <TIMEDATA>) {
           chomp($line);
           $timestr = &Apache::lonnet::unescape($line);
       }
       close(TIMEDATA);
       return &Apache::lonmysql::unsqltime($timestr);
   }
   
 sub build_query {  sub build_query {
     my ($mode) = @_;      my ($mode) = @_;
     my $cid = $ENV{'request.course.id'};      my $cid = $env{'request.course.id'};
     my $domain = $ENV{'course.'.$cid.'.domain'};      my $domain = $env{'course.'.$cid.'.domain'};
     my $home = $ENV{'course.'.$cid.'.home'};      my $home = $env{'course.'.$cid.'.home'};
     my $course = $ENV{'course.'.$cid.'.num'};      my $course = $env{'course.'.$cid.'.num'};
     my $prefix = $course.'_'.$domain.'_';      my $prefix = $course.'_'.$domain.'_';
     #      #
     my $student_table  = $prefix.'students';      my %table = &table_names();
     my $res_table      = $prefix.'resource';  
     my $action_table   = $prefix.'actions';  
     my $machine_table  = $prefix.'machine_table';  
     my $activity_table = $prefix.'activity';  
     #      #
     my $query;      my $query;
     if ($mode eq 'full_class') {      if ($mode eq 'full_class') {
         $query = qq{          $query = qq{
         SELECT B.resource,A.time,C.student,A.action,E.machine,A.action_values           SELECT B.resource,A.time,C.student,A.action,E.machine,A.action_values 
             FROM $activity_table AS A              FROM $table{'activity'} AS A
             LEFT JOIN $res_table      AS B ON B.res_id=A.res_id               LEFT JOIN $table{'res'}      AS B ON B.res_id=A.res_id 
             LEFT JOIN $student_table  AS C ON C.student_id=A.student_id               LEFT JOIN $table{'student'}  AS C ON C.student_id=A.student_id 
             LEFT JOIN $machine_table  AS E ON E.machine_id=A.machine_id              LEFT JOIN $table{'machine'}  AS E ON E.machine_id=A.machine_id
             WHERE A.student_id>10  
             ORDER BY A.time DESC              ORDER BY A.time DESC
             LIMIT 500              LIMIT 500
         };          };
Line 133  sub build_query { Line 206  sub build_query {
         my $student = $1.':'.$2;          my $student = $1.':'.$2;
         $query = qq{          $query = qq{
             SELECT B.resource,A.time,A.action,E.machine,A.action_values               SELECT B.resource,A.time,A.action,E.machine,A.action_values 
                 FROM $activity_table AS A                  FROM $table{'activity'} AS A
                 LEFT JOIN $res_table      AS B ON B.res_id=A.res_id                   LEFT JOIN $table{'res'}      AS B ON B.res_id=A.res_id 
                 LEFT JOIN $student_table  AS C ON C.student_id=A.student_id                   LEFT JOIN $table{'student'}  AS C ON C.student_id=A.student_id 
                 LEFT JOIN $machine_table  AS E ON E.machine_id=A.machine_id                  LEFT JOIN $table{'machine'}  AS E ON E.machine_id=A.machine_id
                 WHERE C.student='$student'                  WHERE C.student='$student'
                 ORDER BY A.time DESC                  ORDER BY A.time DESC
                 LIMIT 500                  LIMIT 500
Line 152  sub output_results { Line 225  sub output_results {
     my ($r,$results_file,$navmap,$mode) = @_;      my ($r,$results_file,$navmap,$mode) = @_;
     ##      ##
     ##      ##
       if (! -s $results_file) {
           # results file is empty, just let them know there is no data
           $r->print('<h2>'.&mt('No data was returned for your request').'</h2>');
           return;
       }
     if (! open(ACTIVITYDATA,$results_file)) {      if (! open(ACTIVITYDATA,$results_file)) {
         $r->print('<h2>'.&mt('Unable to read results file.').'</h2>'.          $r->print('<h2>'.&mt('Unable to read results file.').'</h2>'.
                   '<p>'.                    '<p>'.
Line 189  sub output_results { Line 267  sub output_results {
     ##      ##
     ##      ##
     while (my $line = <ACTIVITYDATA>) {      while (my $line = <ACTIVITYDATA>) {
           # FIXME: does not pass symbs along :(
         chomp($line);          chomp($line);
         $line = &Apache::lonnet::unescape($line);          $line = &Apache::lonnet::unescape($line);
         if (++$count % 50 == 0) {          if (++$count % 50 == 0) {
Line 200  sub output_results { Line 279  sub output_results {
         }          }
         my ($symb,$timestamp,$student,$action,$machine,$values);          my ($symb,$timestamp,$student,$action,$machine,$values);
         if ($mode eq 'full_class') {          if ($mode eq 'full_class') {
             ($symb,$timestamp,$student,$action,$machine,$values) =              ($symb,$timestamp,$student,$action,$machine,$values) = split(',',$line,6);
                 map { &Apache::lonnet::unescape($_); } split(',',$line,6);  
         } else {          } else {
             ($symb,$timestamp,$action,$machine,$values) =              ($symb,$timestamp,$action,$machine,$values) = split(',',$line,5);
                 map { &Apache::lonnet::unescape($_); } split(',',$line,5);  
         }          }
    foreach ($symb,$timestamp,$student,$action,$machine) {
       $_=&Apache::lonnet::unescape($_);
    }
         my ($title,$src);          my ($title,$src);
         if ($symb =~ m:^/adm/:) {          if ($symb =~ m:^/adm/:) {
             $title = $symb;              $title = $symb;
Line 213  sub output_results { Line 293  sub output_results {
         } else {          } else {
             my $nav_res = $navmap->getBySymb($symb);              my $nav_res = $navmap->getBySymb($symb);
             if (defined($nav_res)) {              if (defined($nav_res)) {
                 $title = $nav_res->title();                  $title = $nav_res->compTitle();
                 $src   = $nav_res->src();                  $src   = $nav_res->src();
             } else {              } else {
                 if ($src =~ m|^/res|) {                  if ($src =~ m|^/res|) {
Line 253  sub output_results { Line 333  sub output_results {
             $class = 'warning';              $class = 'warning';
         }          }
         # Clean up the values          # Clean up the values
         $values =~ s/counter=\d+$//;   $values = &display_values($action,$values);
         #          #
         # Build the row for output          # Build the row for output
         my $tablerow = qq{<tr class="$class">};          my $tablerow = qq{<tr class="$class">};
         if ($src =~ m|^/adm/|) {          if ($src =~ m|^/adm/|) {
             $tablerow .=               $tablerow .= 
                 '<td><nobr>'.$title.'</td>';                  '<td valign="top"><nobr>'.$title.'</nobr></td>';
         } else {          } else {
             $tablerow .=               $tablerow .= 
                 '<td><nobr>'.                  '<td valign="top"><nobr>'.
                 '<a href="'.$src.'">'.$title.'</a>'.                  '<a href="'.$src.'">'.$title.'</a>'.
                 '</nobr></td>';                  '</nobr></td>';
         }          }
         $tablerow .= '<td><nobr>'.$timestamp.'</nobr></td>';          $tablerow .= '<td valign="top"><nobr>'.$timestamp.'</nobr></td>';
         if ($mode eq 'full_class') {          if ($mode eq 'full_class') {
             $tablerow.='<td>'.$student.'</td>';              $tablerow.='<td valign="top">'.$student.'</td>';
         }          }
         $tablerow .=           $tablerow .= 
             '<td>'.$action.'</td>'.              '<td valign="top">'.$action.'</td>'.
 #            '<td>'.$machine.'</td>'.  #            '<td>'.$machine.'</td>'.
             '<td>'.$values.'</td>'.              '<td valign="top">'.$values.'</td>'.
             '</tr>';              '</tr>';
         $r->print($tablerow.$/);          $r->print($tablerow.$/);
     }      }
Line 284  sub output_results { Line 364  sub output_results {
   
 ###################################################################  ###################################################################
 ###################################################################  ###################################################################
   sub display_values {
       my ($action,$values)=@_;
       my $result='<table>';
       if ($action eq 'CSTORE') {
    my %values=map {split('=',$_,-1)} split(/\&/,$values);
    foreach my $key (sort(keys(%values))) {
       $result.='<tr><td align="right">'.
    &Apache::lonnet::unescape($key).
    '</td><td>=</td><td align="left">'.
    &Apache::lonnet::unescape($values{$key}).'</td></tr>';
    }
    $result.='</table>';
       } elsif ($action eq 'POST') {
    my %values=
       map {split('=',&Apache::lonnet::unescape($_),-1)} split(/\&/,$values);
    foreach my $key (sort(keys(%values))) {
       if ($key eq 'counter') { next; }
       $result.='<tr><td align="right">'.$key.'</td>'.
    '<td>=</td><td align="left">'.$values{$key}.'</td></tr>';
    }
    $result.='</table>';
       } else {
    $result=&Apache::lonnet::unescape($values)
       }
       return $result;
   }
   ###################################################################
   ###################################################################
 sub request_data_update {  sub request_data_update {
     my $command = 'prepare activity log';      my $command = 'prepare activity log';
     my $cid = $ENV{'request.course.id'};      my $cid = $env{'request.course.id'};
     my $domain = $ENV{'course.'.$cid.'.domain'};      my $domain = $env{'course.'.$cid.'.domain'};
     my $home = $ENV{'course.'.$cid.'.home'};      my $home = $env{'course.'.$cid.'.home'};
     my $course = $ENV{'course.'.$cid.'.num'};      my $course = $env{'course.'.$cid.'.num'};
 #    &Apache::lonnet::logthis($command.' '.$course.' '.$domain.' '.$home);  #    &Apache::lonnet::logthis($command.' '.$course.' '.$domain.' '.$home);
     my $result = &Apache::lonnet::metadata_query($command,$course,$domain,      my $result = &Apache::lonnet::metadata_query($command,$course,$domain,
                                                  [$home]);                                                   [$home]);
Line 355  sub handler { Line 463  sub handler {
     $loaderror=      $loaderror=
         &Apache::lonnet::overloaderror          &Apache::lonnet::overloaderror
         ($r,          ($r,
          $ENV{'course.'.$ENV{'request.course.id'}.'.home'});           $env{'course.'.$env{'request.course.id'}.'.home'});
     if ($loaderror) { return $loaderror; }      if ($loaderror) { return $loaderror; }
     #      #
     # Check for access      # Check for access
     if (! &Apache::lonnet::allowed('vsa',$ENV{'request.course.id'})) {      if (! &Apache::lonnet::allowed('vsa',$env{'request.course.id'})) {
         $ENV{'user.error.msg'}=          $env{'user.error.msg'}=
             $r->uri.":vsa:0:0:Cannot student activity for complete course";              $r->uri.":vsa:0:0:Cannot student activity for complete course";
         if (!           if (! 
             &Apache::lonnet::allowed('vsa',              &Apache::lonnet::allowed('vsa',
                                      $ENV{'request.course.id'}.'/'.                                       $env{'request.course.id'}.'/'.
                                      $ENV{'request.course.sec'})) {                                       $env{'request.course.sec'})) {
             $ENV{'user.error.msg'}=              $env{'user.error.msg'}=
                 $r->uri.":vsa:0:0:Cannot view student activity with given role";                  $r->uri.":vsa:0:0:Cannot view student activity with given role";
             return HTTP_NOT_ACCEPTABLE;              return HTTP_NOT_ACCEPTABLE;
         }          }
Line 393  sub handler { Line 501  sub handler {
                                             bug=>'instructor interface'});                                              bug=>'instructor interface'});
     #      #
     # Give the LON-CAPA page header      # Give the LON-CAPA page header
     $r->print('<html><head>'.&styles.'<title>'.      my $html=&Apache::lonxml::xmlbegin();
       $r->print($html.'<head>'.&styles().'<title>'.
               &mt('Student Activity').                &mt('Student Activity').
               "</title></head>\n".                "</title></head>\n".
               &Apache::loncommon::bodytag('Student Activity').                &Apache::loncommon::bodytag('Student Activity').
Line 416  sub handler { Line 525  sub handler {
         ($r,\%prog_state,&mt('Contacting course home server'));          ($r,\%prog_state,&mt('Contacting course home server'));
     #      #
     my $result = &request_data_update();      my $result = &request_data_update();
     if (ref($result) eq 'HASH') {  
         $result = join(' ',map { $_.'=>'.$result->{$_}; } keys(%$result));  
     }  
     #      #
     if (exists($ENV{'form.selected_student'})) {      if (exists($env{'form.selected_student'})) {
         # For now, just show all the data, in the future allow selection of          # For now, just show all the data, in the future allow selection of
         # a student          # a student
         my ($sname,$sdom) = split(':',$ENV{'form.selected_student'});          my ($sname,$sdom) = split(':',$env{'form.selected_student'});
         if ($sname =~ /^\w*$/ && $sdom =~ /^\w*$/) {          if ($sname =~ /^\w*$/ && $sdom =~ /^\w*$/) {
             $r->print('<h2>'.              $r->print('<h2>'.
                       &mt('Recent activity of [_1]@[_2]',$sname,$sdom).                        &mt('Recent activity of [_1]@[_2]',$sname,$sdom).
Line 433  Compiling student activity data can take Line 539  Compiling student activity data can take
 It may be necessary to reload this page to get the most current information.  It may be necessary to reload this page to get the most current information.
 END  END
             &get_data($r,\%prog_state,$navmap,              &get_data($r,\%prog_state,$navmap,
                       'student:'.$ENV{'form.selected_student'});                        'student:'.$env{'form.selected_student'});
         } else {          } else {
             $r->print('<h2>'.&mt('Unable to process for [_1]@[_2]',              $r->print('<h2>'.&mt('Unable to process for [_1]@[_2]',
                                  $sname,$sdom).'</h2>');                                   $sname,$sdom).'</h2>');

Removed from v.1.9  
changed lines
  Added in v.1.15


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