Annotation of loncom/interface/lontrackstudent.pm, revision 1.2
1.1 matthew 1: # The LearningOnline Network with CAPA
2: #
1.2 ! matthew 3: # $Id: lontrackstudent.pm,v 1.1 2004/08/11 18:41:05 matthew Exp $
1.1 matthew 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: ###################################################################
1.2 ! matthew 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:
1.1 matthew 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: #
1.2 ! matthew 231: # We will almost always need this...
! 232: my $navmap = Apache::lonnavmaps::navmap->new();
1.1 matthew 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: #
1.2 ! matthew 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: #
1.1 matthew 249: # Begin form output
1.2 ! matthew 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>');
1.1 matthew 256: $r->rflush();
1.2 ! matthew 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'));
1.1 matthew 263: #
264: my $result = &request_data_update();
265: if (ref($result) eq 'HASH') {
1.2 ! matthew 266: $result = join(' ',map { $_.'=>'.$result->{$_}; } keys(%$result));
1.1 matthew 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: #
1.2 ! matthew 278: &get_all_data($r,\%prog_state,$navmap);
! 279:
! 280: # &Apache::lonhtmlcommon::Update_PrgWin
! 281: # ($r,\%prog_state,&mt('Done'));
! 282:
! 283: #
1.1 matthew 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>