File:  [LON-CAPA] / loncom / interface / lontrackstudent.pm
Revision 1.2: download - view: text, annotated - select for diffs
Wed Aug 11 23:37:36 2004 UTC (19 years, 10 months ago) by matthew
Branches: MAIN
CVS tags: HEAD
&get_all_data is getting to be fleshed out.  Requests, receives, and
displays activity log data in an ugly table.  Found bugs in navmaps so
resource titles and links are not working.  Head to /adm/trackstudent to
see it in action (once most development servers have updated).

    1: # The LearningOnline Network with CAPA
    2: #
    3: # $Id: lontrackstudent.pm,v 1.2 2004/08/11 23:37:36 matthew Exp $
    4: #
    5: # Copyright Michigan State University Board of Trustees
    6: #
    7: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
    8: #
    9: # LON-CAPA is free software; you can redistribute it and/or modify
   10: # it under the terms of the GNU General Public License as published by
   11: # the Free Software Foundation; either version 2 of the License, or
   12: # (at your option) any later version.
   13: #
   14: # LON-CAPA is distributed in the hope that it will be useful,
   15: # but WITHOUT ANY WARRANTY; without even the implied warranty of
   16: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   17: # GNU General Public License for more details.
   18: #
   19: # You should have received a copy of the GNU General Public License
   20: # along with LON-CAPA; if not, write to the Free Software
   21: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
   22: #
   23: # /home/httpd/html/adm/gpl.txt
   24: #
   25: # http://www.lon-capa.org/
   26: #
   27: ###
   28: 
   29: =pod
   30: 
   31: =head1 NAME
   32: 
   33: lontrackstudent
   34: 
   35: =head1 SYNOPSIS
   36: 
   37: Track student progress through course materials
   38: 
   39: =over 4
   40: 
   41: =cut
   42: 
   43: package Apache::lontrackstudent;
   44: 
   45: use strict;
   46: use Apache::Constants qw(:common :http);
   47: use Apache::lonnet();
   48: use Apache::lonlocal;
   49: use Time::HiRes;
   50: 
   51: ###################################################################
   52: ###################################################################
   53: sub get_all_data {
   54:     my ($r,$prog_state,$navmap) = @_;
   55:     ##
   56:     ## Compose the query
   57:     &Apache::lonhtmlcommon::Update_PrgWin
   58:         ($r,$prog_state,&mt('Composing Query'));
   59:     #
   60:     my $query;
   61:     my $cid = $ENV{'request.course.id'};
   62:     my $domain = $ENV{'course.'.$cid.'.domain'};
   63:     my $home = $ENV{'course.'.$cid.'.home'};
   64:     my $course = $ENV{'course.'.$cid.'.num'};
   65:     my $prefix = $course.'_'.$domain.'_';
   66:     #
   67:     my $student_table  = $prefix.'students';
   68:     my $res_table      = $prefix.'resource';
   69:     my $action_table   = $prefix.'actions';
   70:     my $machine_table  = $prefix.'machine_table';
   71:     my $activity_table = $prefix.'activity';
   72:     #
   73:     $query = qq{
   74:         select B.resource,A.time,C.student,D.action,E.machine,A.action_values 
   75:             FROM $activity_table AS A
   76:             LEFT JOIN $res_table AS B ON B.res_id=A.res_id 
   77:             LEFT JOIN $student_table  AS C ON C.student_id=A.student_id 
   78:             LEFT JOIN $action_table   AS D ON D.action_id=A.action_id 
   79:             LEFT JOIN $machine_table  AS E ON E.machine_id=A.machine_id
   80:     };
   81:     $query =~ s|$/||g;
   82:     # &Apache::lonnet::logthis($query);
   83:     ##
   84:     ## Send it along
   85:     my $reply=&Apache::lonnet::metadata_query($query,undef,undef,[$home]);
   86:     if (ref($reply) ne 'HASH') {
   87:         $r->print('<h2>'.
   88:                   &mt('Error contacting home server for course: [_1]',
   89:                       $reply).
   90:                   '</h2>');
   91:         return;
   92:     }
   93:     my $results_file = $r->dir_config('lonDaemons').'/tmp/'.$reply->{$home};
   94:     my $endfile = $results_file.'.end';
   95:     ##
   96:     ## Check for the results
   97:     &Apache::lonhtmlcommon::Update_PrgWin
   98:         ($r,$prog_state,&mt('Waiting for results'));
   99:     my $maxtime = 500;
  100:     my $starttime = time;
  101:     while (! -e $endfile && (time-$starttime < $maxtime)) {
  102:         sleep(1);
  103:         &Apache::lonhtmlcommon::Update_PrgWin
  104:             ($r,$prog_state,&mt('Waiting for results'));
  105:     }
  106:     if (! -e $endfile) {
  107:         $r->print('<h2>'.
  108:                   &mt('Unable to retrieve data.').'</h2>');
  109:         $r->print(&mt('Please try again in a few minutes.'));
  110:         return;
  111:     }
  112:     &Apache::lonhtmlcommon::Update_PrgWin
  113:         ($r,$prog_state,&mt('Parsing results'));
  114:     if (! open(ACTIVITYDATA,$results_file)) {
  115:         $r->print('<h2>'.
  116:                   &mt('Unable to read results file.  This is a serious error and has been logged.  You should contact your system administrator to resolve this issue.  If you are the system administrator, I feel sorry for you.').
  117:                   '</h2>');
  118:         return;
  119:     }
  120:     my $tableheader = 
  121:         '<table><tr>'.
  122:         '<th>'.&mt('Resource').'</th>'.
  123:         '<th>'.&mt('Time').'</th>'.
  124:         '<th>'.&mt('Student').'</th>'.
  125:         '<th>'.&mt('Action').'</th>'.
  126:         '<th>'.&mt('Originating Server').'</th>'.
  127:         '<th>'.&mt('Data').'</th>'.
  128:         '</tr>'.$/;
  129:     my $count =0;
  130:     $r->print($tableheader);
  131:     $r->rflush();
  132:     while (my $line = <ACTIVITYDATA>) {
  133:         $line = &Apache::lonnet::unescape($line);
  134:         if (++$count % 50 == 0) {
  135:             $r->print('</table>'.$/);
  136:             $r->rflush();
  137:             $r->print($tableheader);
  138:         }
  139:         my ($symb,$timestamp,$student,$action,$machine,$values) =
  140:             map { &Apache::lonnet::unescape($_); } split(',',$line,6);
  141:         my ($title,$src);
  142:         if ($symb =~ m:^/(res|adm)/:) {
  143:             $title = $symb;
  144:             $src = $symb;
  145:         } else {
  146:             # We may need to add 'uploaded/' to the symb
  147:             # 
  148:             # Hey, guess what - navmaps->getBySymb 
  149:             # does not work with uploaded resources/new style courses/something
  150:             # The fact that our symbs do not have uploaded/ prepended to them
  151:             # then they (most often but not always) should, is likely to be
  152:             # a puzzle too.
  153:             #my $nav_res = $navmap->getBySymb($symb);
  154:             $title = 'resource title goes here'; # $nav_res->title();
  155:             $src   = '/dev/null'; # $nav_res->src();
  156:         }
  157:         $r->print('<tr>'.
  158:                   '<td>'.'<a href="'.$src.'">'.$title.'</a>'.'</td>'.
  159:                   '<td><nobr>'.$timestamp.'</nobr></td>'.
  160:                   '<td>'.$student.'</td>'.
  161:                   '<td>'.$action.'</td>'.
  162:                   '<td>'.$machine.'</td>'.
  163:                   '<td>'.$values.'</td>'.'</tr>'.$/);
  164:     }
  165:     $r->print('</table>'.$/);
  166:     close(ACTIVITYDATA);
  167:     &Apache::lonhtmlcommon::Update_PrgWin
  168:         ($r,$prog_state,&mt('Finished!'));
  169:     return;
  170: }
  171: 
  172: sub get_student_data {}
  173: sub html_output_student_data {}
  174: sub html_output_class_data {}
  175: 
  176: sub request_data_update {
  177:     my $command = 'prepare activity log';
  178:     my $cid = $ENV{'request.course.id'};
  179:     my $domain = $ENV{'course.'.$cid.'.domain'};
  180:     my $home = $ENV{'course.'.$cid.'.home'};
  181:     my $course = $ENV{'course.'.$cid.'.num'};
  182:     &Apache::lonnet::logthis($command.' '.$course.' '.$domain.' '.$home);
  183:     my $result = &Apache::lonnet::metadata_query($command,$course,$domain,
  184:                                                  [$home]);
  185:     return $result;
  186: }
  187: 
  188: ###################################################################
  189: ###################################################################
  190: 
  191: 
  192: ###################################################################
  193: ###################################################################
  194: sub handler {
  195:     my $r=shift;
  196:     my $c = $r->connection();
  197:     #
  198:     # Check for overloading here and on the course home server
  199:     my $loaderror=&Apache::lonnet::overloaderror($r);
  200:     if ($loaderror) { return $loaderror; }
  201:     $loaderror=
  202:         &Apache::lonnet::overloaderror
  203:         ($r,
  204:          $ENV{'course.'.$ENV{'request.course.id'}.'.home'});
  205:     if ($loaderror) { return $loaderror; }
  206:     #
  207:     # Check for access
  208:     if (! &Apache::lonnet::allowed('vsa',$ENV{'request.course.id'})) {
  209:         $ENV{'user.error.msg'}=
  210:             $r->uri.":vsa:0:0:Cannot student activity for complete course";
  211:         if (! 
  212:             &Apache::lonnet::allowed('vsa',
  213:                                      $ENV{'request.course.id'}.'/'.
  214:                                      $ENV{'request.course.sec'})) {
  215:             $ENV{'user.error.msg'}=
  216:                 $r->uri.":vsa:0:0:Cannot view student activity with given role";
  217:             return HTTP_NOT_ACCEPTABLE;
  218:         }
  219:     }
  220:     #
  221:     # Send the header
  222:     &Apache::loncommon::no_cache($r);
  223:     &Apache::loncommon::content_type($r,'text/html');
  224:     $r->send_http_header;
  225:     if ($r->header_only) { return OK; }
  226:     #
  227:     # Extract form elements from query string
  228:     &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
  229:                                             ['selected_student']);
  230:     #
  231:     # We will almost always need this...
  232:     my $navmap = Apache::lonnavmaps::navmap->new();
  233:     # 
  234:     &Apache::lonhtmlcommon::clear_breadcrumbs();
  235:     &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/studentactivity',
  236:                                             title=>'Student Activity',
  237:                                             text =>'Student Activity',
  238:                                             faq=>139,
  239:                                             bug=>'instructor interface'});
  240:     #
  241:     # Give the LON-CAPA page header
  242:     $r->print('<html><head><title>'.
  243:               &mt('Student Activity').
  244:               "</title></head>\n".
  245:               &Apache::loncommon::bodytag('Student Activity').
  246:               &Apache::lonhtmlcommon::breadcrumbs(undef,'Student Activity'));
  247:     $r->rflush();
  248:     #
  249:     # Begin form output
  250:     $r->print('<form name="trackstudent" method="post" action="/adm/trackstudent">');
  251:     $r->print('<br />');
  252:     $r->print('<div name="statusline">'.
  253:               &mt('Status:[_1]',
  254:                   '<input type="text" name="status" size="60" value="" />').
  255:               '</div>');
  256:     $r->rflush();
  257:     my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin
  258:         ($r,&mt('Student Activity Retrieval'),
  259:          &mt('Student Activity Retrieval'),undef,'inline',undef,
  260:          'trackstudent','status');
  261:     &Apache::lonhtmlcommon::Update_PrgWin
  262:         ($r,\%prog_state,&mt('Contacting course home server'));
  263:     #
  264:     my $result = &request_data_update();
  265:     if (ref($result) eq 'HASH') {
  266:         $result = join(' ',map { $_.'=>'.$result->{$_}; } keys(%$result));
  267:     }
  268:     $r->print('<h2>'.$result.'</h2>');
  269:     #
  270:     if (! exists($ENV{'form.selected_student'})) {
  271:         # Choose a student
  272:         $r->print('If you worked here you would be done by now');
  273:     } else {
  274:         # Show a students activity
  275:         $r->print('I would like to have something to show you but I do not.');
  276:     }
  277:     #
  278:     &get_all_data($r,\%prog_state,$navmap);
  279: 
  280: #    &Apache::lonhtmlcommon::Update_PrgWin
  281: #        ($r,\%prog_state,&mt('Done'));
  282: 
  283:     #
  284:     $r->print("</form>\n");
  285:     $r->print("</body>\n</html>\n");
  286:     $r->rflush();
  287:     #
  288:     return OK;
  289: }
  290: 
  291: 1;
  292: 
  293: #######################################################
  294: #######################################################
  295: 
  296: =pod
  297: 
  298: =back
  299: 
  300: =cut
  301: 
  302: #######################################################
  303: #######################################################
  304: 
  305: __END__
  306: 

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