Annotation of loncom/interface/lontrackstudent.pm, revision 1.3
1.1 matthew 1: # The LearningOnline Network with CAPA
2: #
1.3 ! matthew 3: # $Id: lontrackstudent.pm,v 1.2 2004/08/11 23:37:36 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
1.3 ! matthew 80: LIMIT 500
1.2 matthew 81: };
82: $query =~ s|$/||g;
83: # &Apache::lonnet::logthis($query);
84: ##
85: ## Send it along
86: my $reply=&Apache::lonnet::metadata_query($query,undef,undef,[$home]);
87: if (ref($reply) ne 'HASH') {
88: $r->print('<h2>'.
89: &mt('Error contacting home server for course: [_1]',
90: $reply).
91: '</h2>');
92: return;
93: }
94: my $results_file = $r->dir_config('lonDaemons').'/tmp/'.$reply->{$home};
95: my $endfile = $results_file.'.end';
96: ##
97: ## Check for the results
98: &Apache::lonhtmlcommon::Update_PrgWin
99: ($r,$prog_state,&mt('Waiting for results'));
100: my $maxtime = 500;
101: my $starttime = time;
102: while (! -e $endfile && (time-$starttime < $maxtime)) {
103: sleep(1);
104: &Apache::lonhtmlcommon::Update_PrgWin
105: ($r,$prog_state,&mt('Waiting for results'));
106: }
107: if (! -e $endfile) {
108: $r->print('<h2>'.
109: &mt('Unable to retrieve data.').'</h2>');
110: $r->print(&mt('Please try again in a few minutes.'));
111: return;
112: }
113: &Apache::lonhtmlcommon::Update_PrgWin
114: ($r,$prog_state,&mt('Parsing results'));
115: if (! open(ACTIVITYDATA,$results_file)) {
116: $r->print('<h2>'.
117: &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.').
118: '</h2>');
119: return;
120: }
121: my $tableheader =
122: '<table><tr>'.
123: '<th>'.&mt('Resource').'</th>'.
124: '<th>'.&mt('Time').'</th>'.
125: '<th>'.&mt('Student').'</th>'.
126: '<th>'.&mt('Action').'</th>'.
127: '<th>'.&mt('Originating Server').'</th>'.
128: '<th>'.&mt('Data').'</th>'.
129: '</tr>'.$/;
130: my $count =0;
131: $r->print($tableheader);
132: $r->rflush();
133: while (my $line = <ACTIVITYDATA>) {
134: $line = &Apache::lonnet::unescape($line);
135: if (++$count % 50 == 0) {
136: $r->print('</table>'.$/);
137: $r->rflush();
138: $r->print($tableheader);
139: }
140: my ($symb,$timestamp,$student,$action,$machine,$values) =
141: map { &Apache::lonnet::unescape($_); } split(',',$line,6);
142: my ($title,$src);
143: if ($symb =~ m:^/(res|adm)/:) {
144: $title = $symb;
145: $src = $symb;
146: } else {
147: # We may need to add 'uploaded/' to the symb
148: #
149: # Hey, guess what - navmaps->getBySymb
150: # does not work with uploaded resources/new style courses/something
151: # The fact that our symbs do not have uploaded/ prepended to them
152: # then they (most often but not always) should, is likely to be
153: # a puzzle too.
1.3 ! matthew 154: #&Apache::lonnet::logthis('trackstudent:symb = '.$symb);
! 155: # my $nav_res = $navmap->getBySymb($symb);
1.2 matthew 156: $title = 'resource title goes here'; # $nav_res->title();
157: $src = '/dev/null'; # $nav_res->src();
158: }
159: $r->print('<tr>'.
160: '<td>'.'<a href="'.$src.'">'.$title.'</a>'.'</td>'.
161: '<td><nobr>'.$timestamp.'</nobr></td>'.
162: '<td>'.$student.'</td>'.
163: '<td>'.$action.'</td>'.
164: '<td>'.$machine.'</td>'.
165: '<td>'.$values.'</td>'.'</tr>'.$/);
166: }
167: $r->print('</table>'.$/);
168: close(ACTIVITYDATA);
169: &Apache::lonhtmlcommon::Update_PrgWin
170: ($r,$prog_state,&mt('Finished!'));
171: return;
172: }
173:
1.1 matthew 174: sub get_student_data {}
175: sub html_output_student_data {}
176: sub html_output_class_data {}
177:
178: sub request_data_update {
179: my $command = 'prepare activity log';
180: my $cid = $ENV{'request.course.id'};
181: my $domain = $ENV{'course.'.$cid.'.domain'};
182: my $home = $ENV{'course.'.$cid.'.home'};
183: my $course = $ENV{'course.'.$cid.'.num'};
184: &Apache::lonnet::logthis($command.' '.$course.' '.$domain.' '.$home);
185: my $result = &Apache::lonnet::metadata_query($command,$course,$domain,
186: [$home]);
187: return $result;
188: }
189:
190: ###################################################################
191: ###################################################################
192:
193:
194: ###################################################################
195: ###################################################################
196: sub handler {
197: my $r=shift;
198: my $c = $r->connection();
199: #
200: # Check for overloading here and on the course home server
201: my $loaderror=&Apache::lonnet::overloaderror($r);
202: if ($loaderror) { return $loaderror; }
203: $loaderror=
204: &Apache::lonnet::overloaderror
205: ($r,
206: $ENV{'course.'.$ENV{'request.course.id'}.'.home'});
207: if ($loaderror) { return $loaderror; }
208: #
209: # Check for access
210: if (! &Apache::lonnet::allowed('vsa',$ENV{'request.course.id'})) {
211: $ENV{'user.error.msg'}=
212: $r->uri.":vsa:0:0:Cannot student activity for complete course";
213: if (!
214: &Apache::lonnet::allowed('vsa',
215: $ENV{'request.course.id'}.'/'.
216: $ENV{'request.course.sec'})) {
217: $ENV{'user.error.msg'}=
218: $r->uri.":vsa:0:0:Cannot view student activity with given role";
219: return HTTP_NOT_ACCEPTABLE;
220: }
221: }
222: #
223: # Send the header
224: &Apache::loncommon::no_cache($r);
225: &Apache::loncommon::content_type($r,'text/html');
226: $r->send_http_header;
227: if ($r->header_only) { return OK; }
228: #
229: # Extract form elements from query string
230: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},
231: ['selected_student']);
232: #
1.2 matthew 233: # We will almost always need this...
234: my $navmap = Apache::lonnavmaps::navmap->new();
1.1 matthew 235: #
236: &Apache::lonhtmlcommon::clear_breadcrumbs();
237: &Apache::lonhtmlcommon::add_breadcrumb({href=>'/adm/studentactivity',
238: title=>'Student Activity',
239: text =>'Student Activity',
240: faq=>139,
241: bug=>'instructor interface'});
242: #
1.2 matthew 243: # Give the LON-CAPA page header
244: $r->print('<html><head><title>'.
245: &mt('Student Activity').
246: "</title></head>\n".
247: &Apache::loncommon::bodytag('Student Activity').
248: &Apache::lonhtmlcommon::breadcrumbs(undef,'Student Activity'));
249: $r->rflush();
250: #
1.1 matthew 251: # Begin form output
1.2 matthew 252: $r->print('<form name="trackstudent" method="post" action="/adm/trackstudent">');
253: $r->print('<br />');
254: $r->print('<div name="statusline">'.
255: &mt('Status:[_1]',
256: '<input type="text" name="status" size="60" value="" />').
257: '</div>');
1.1 matthew 258: $r->rflush();
1.2 matthew 259: my %prog_state=&Apache::lonhtmlcommon::Create_PrgWin
260: ($r,&mt('Student Activity Retrieval'),
261: &mt('Student Activity Retrieval'),undef,'inline',undef,
262: 'trackstudent','status');
263: &Apache::lonhtmlcommon::Update_PrgWin
264: ($r,\%prog_state,&mt('Contacting course home server'));
1.1 matthew 265: #
266: my $result = &request_data_update();
267: if (ref($result) eq 'HASH') {
1.2 matthew 268: $result = join(' ',map { $_.'=>'.$result->{$_}; } keys(%$result));
1.1 matthew 269: }
270: $r->print('<h2>'.$result.'</h2>');
271: #
272: if (! exists($ENV{'form.selected_student'})) {
273: # Choose a student
274: $r->print('If you worked here you would be done by now');
275: } else {
276: # Show a students activity
277: $r->print('I would like to have something to show you but I do not.');
278: }
279: #
1.2 matthew 280: &get_all_data($r,\%prog_state,$navmap);
281:
282: # &Apache::lonhtmlcommon::Update_PrgWin
283: # ($r,\%prog_state,&mt('Done'));
284:
285: #
1.1 matthew 286: $r->print("</form>\n");
287: $r->print("</body>\n</html>\n");
288: $r->rflush();
289: #
290: return OK;
291: }
292:
293: 1;
294:
295: #######################################################
296: #######################################################
297:
298: =pod
299:
300: =back
301:
302: =cut
303:
304: #######################################################
305: #######################################################
306:
307: __END__
308:
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>