[system] / branches / rel-2-0-patches / webwork2 / lib / WeBWorK / ContentGenerator / Instructor / Preflight.pm Repository:
ViewVC logotype

View of /branches/rel-2-0-patches/webwork2/lib/WeBWorK/ContentGenerator/Instructor/Preflight.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2523 - (download) (as text) (annotate)
Fri Jul 16 18:34:48 2004 UTC (8 years, 10 months ago)
File size: 14444 byte(s)
This commit was manufactured by cvs2svn to create branch 'rel-2-0-patches'.

    1 ################################################################################
    2 # WeBWorK Online Homework Delivery System
    3 # Copyright © 2000-2003 The WeBWorK Project, http://openwebwork.sf.net/
    4 # $CVSHeader: webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor/Preflight.pm,v 1.2 2004/06/03 19:58:00 toenail Exp $
    5 #
    6 # This program is free software; you can redistribute it and/or modify it under
    7 # the terms of either: (a) the GNU General Public License as published by the
    8 # Free Software Foundation; either version 2, or (at your option) any later
    9 # version, or (b) the "Artistic License" which comes with this package.
   10 #
   11 # This program is distributed in the hope that it will be useful, but WITHOUT
   12 # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   13 # FOR A PARTICULAR PURPOSE.  See either the GNU General Public License or the
   14 # Artistic License for more details.
   15 ################################################################################
   16 
   17 package WeBWorK::ContentGenerator::Instructor::Preflight;
   18 use base qw(WeBWorK::ContentGenerator::Instructor);
   19 
   20 =head1 NAME
   21 
   22 WeBWorK::ContentGenerator::Instructor::Preflight.pm  -- display past answers of many students
   23 
   24 =cut
   25 
   26 use strict;
   27 use warnings;
   28 use CGI qw();
   29 use WeBWorK::Utils qw(formatDateTime);
   30 use WeBWorK::HTML::OptionList qw/optionList/;
   31 use WeBWorK::HTML::ScrollingRecordList qw/scrollingRecordList/;
   32 
   33 sub initialize {
   34   my $self       = shift;
   35   my $r          = $self->r;
   36   my $urlpath    = $r->urlpath;
   37   my $db         = $r->db;
   38   my $ce         = $r->ce;
   39   my $authz      = $r->authz;
   40   my $courseName = $urlpath->arg("courseID");
   41   my $user       = $r->param('user');
   42 
   43   # Check permissions
   44   return unless ($authz->hasPermissions($user, "access_instructor_tools"));
   45 }
   46 
   47 
   48 sub body {
   49   my $self          = shift;
   50   my $r             = $self->r;
   51   my $urlpath       = $r->urlpath;
   52   my $db            = $r->db;
   53   my $ce            = $r->ce;
   54   my $authz         = $r->authz;
   55   my $root          = $ce->{webworkURLs}->{root};
   56   my $courseName    = $urlpath->arg('courseID');
   57   my $setName       = $r->param('setID') || "";     # these are passed in the search args in this case
   58   my $problemNumber = $r->param('problemID') || "";
   59   if ($problemNumber =~ /\!(\d+)/) { $problemNumber = $1 };
   60   my $user          = $r->param('user');
   61   my $key           = $r->param('key');
   62   my $studentUser   = $r->param('studentUser') || "";
   63 
   64   # Check permissions
   65   return CGI::div({class=>"ResultsWithError"}, "You are not authorized to access the Instructor tools.")
   66     unless $authz->hasPermissions($r->param("user"), "access_instructor_tools");
   67 
   68 
   69   my $showAnswersPage   = $urlpath->newFromModule($urlpath->module, courseID => $courseName);
   70   my $showAnswersURL    = $self->systemLink($showAnswersPage,authen => 0 );
   71 
   72   my ($safeUser, $safeCourse) = (showHTML($studentUser), showHTML($courseName));
   73   my ($safeSet, $safeProb) = (showHTML($setName), showHTML($problemNumber));
   74 
   75   my @defaultOrder = qw(user_id set_id problem_id date answers);
   76 
   77   my %prettyFieldNames;
   78 
   79   @prettyFieldNames{qw(
   80     user_id
   81     set_id
   82     problem_id
   83     date
   84     answers
   85   )} = (
   86     "User ID",
   87     "Set Name",
   88     "Problem Number",
   89     "Date",
   90     "Answers",
   91   );
   92   $prettyFieldNames{nofield} = "";
   93 
   94   #####################################################################
   95   # print form
   96   #####################################################################
   97 
   98   my @userIDs = grep /\w/, sort $db->listUsers();
   99   my @Users = $db->getUsers(@userIDs);
  100   my %users = map { $_ => $db->getUser($_)->first_name } @userIDs;
  101   my @setIDs = sort $db->listGlobalSets();
  102   my @GlobalSets = $db->getGlobalSets(@setIDs);
  103   my @GlobalProblems = $db->getAllGlobalProblems($setName);
  104 
  105   my $scrolling_user_list = scrollingRecordList({
  106     name => "studentUser",
  107     request => $r,
  108     default_sort => "lnfn",
  109     default_format => "lnfn_uid",
  110     default_filters => ["all"],
  111     default => "Select one or more users: ",
  112 #   hide_sort => 1,
  113 #   hide_format => 1,
  114 #   hide_filter => 1,
  115     size => 10,
  116 #   multiple => 0,
  117   }, @Users);
  118 
  119   my $scrolling_set_list = scrollingRecordList({
  120     name => "setID",
  121     request => $r,
  122     default_sort => "set_id",
  123     default_format => "set_id",
  124     default_filters => ["all"],
  125     default => "Select one or more sets: ",
  126 #   hide_sort => 1,
  127 #   hide_format => 1,
  128 #   hide_filter => 1,
  129     size => 10,
  130 #   multiple => 0,
  131   }, @GlobalSets);
  132 
  133   my $scrolling_problem_list = scrollingRecordList({
  134     name => "problemID",
  135     request => $r,
  136     default => "Select one or more problems: ",
  137     default_filters => ["all"],
  138 #   hide_sort => 1,
  139 #   hide_format => 1,
  140 #   hide_filter => 1,
  141     size => 10,
  142 #   multiple => 0,
  143   }, @GlobalProblems);
  144 
  145   my @selected_fields = $r->param("selected_fields");
  146   my @selected_answers = $r->param("selected_answers");
  147 
  148   print join ("",
  149     CGI::br(),
  150     "\n\n",
  151     CGI::hr(),
  152     CGI::start_form(
  153       -method => "post",
  154       -action => $showAnswersURL,
  155       -target => 'information',
  156     ),
  157       CGI::start_table(
  158         -border => "0",
  159         -cellpadding => "0",
  160         -cellspacing => "0",
  161       ),
  162         CGI::Tr(
  163           CGI::td({style=>"width:33%"}, $scrolling_user_list),
  164           CGI::td({style=>"width:33%"}, $scrolling_set_list),
  165           CGI::td({style=>"width:33%"}, $scrolling_problem_list),
  166         ),
  167         CGI::Tr({},
  168           CGI::submit(
  169             -name => 'action',
  170             -value => 'Past Answers for',
  171           ), "\n",
  172 #         $self->hidden_authen_fields,
  173 #         "   \n User:  ",
  174 #         CGI::textfield(
  175 #           -name => 'studentUser1',
  176 #           -value => $safeUser,
  177 #           -size => 10,
  178 #         ),
  179 #         "   \n Set:  ",
  180 #         CGI::textfield(
  181 #           -name => 'setID1',
  182 #           -value => $safeSet,
  183 #           -size => 10,
  184 #         ),
  185 #         "   \n Problem:   ",
  186 #         CGI::textfield(
  187 #           -name => 'problemID',
  188 #           -value => $safeProb,
  189 #           -size => 10,
  190 #         ),
  191 #         "   \n",
  192 #         CGI::br(),CGI::br(),
  193         ),
  194 #       CGI::Tr({},
  195 #         CGI::popup_menu(
  196 #           -name => 'studentUser',
  197 #           -size => 10,
  198 #           -values => \@userIDs,
  199 #           -multiple => 1,
  200 #         ),
  201 #         CGI::popup_menu(
  202 #           -name => 'setID',
  203 #           -values => \@setIDs,
  204 #           -size => 10,
  205 #           -multiple => 1,
  206 #         ),
  207 #       ),
  208         CGI::Tr({},
  209           CGI::td({},
  210             "Select which fields to show: " . CGI::br(),
  211             CGI::scrolling_list(
  212               -name => "selected_fields",
  213               -values => \@defaultOrder,
  214               -labels => \%prettyFieldNames,
  215               -default => \@selected_fields,
  216               -size => 5,
  217               -multiple => 1,
  218             ),
  219           ),
  220           CGI::td({},
  221             "and which answers to show: " . CGI::br(),
  222             CGI::scrolling_list(
  223               -name => "selected_answers",
  224               -values => [1..100],
  225               -default => \@selected_answers,
  226               -size => 5,
  227               -multiple => 1,
  228             )
  229           ),
  230         ),
  231       CGI::end_table({}),
  232     CGI::end_form({}),
  233   );
  234 
  235   #####################################################################
  236   # create ordering system
  237   #####################################################################
  238 
  239   # FIXME: We need a way to choose the order as well as the fields!
  240   my (@fieldOrder) = @selected_fields ? @selected_fields : @defaultOrder;
  241 
  242   if (defined($setName) and defined($problemNumber) )  {
  243     #####################################################################
  244     # print result table of answers
  245     #####################################################################
  246     my $answer_log    = $self->{ce}->{courseFiles}->{logs}->{'answer_log'};
  247 
  248     $studentUser = $r->param('studentUser') if ( defined($r->param('studentUser')) );
  249     my ($safeUser, $safeCourse) = (showHTML($studentUser), showHTML($courseName));
  250     my ($safeSet, $safeProb) = (showHTML($setName), showHTML($problemNumber));
  251 
  252 
  253     print CGI::h3( "Past Answers for " . ($safeUser ? "user $safeUser " : '' ) . ($safeSet ? "set $safeSet " : '' ) . ($safeSet and $safeProb ? ', ' : '') . ($safeProb ? "problem $safeProb" : ''));
  254 
  255     $studentUser = "[^|]*"    if (not defined $studentUser or $studentUser eq ""    or $studentUser eq "*");
  256     $setName = "[^|]*"  if ($setName eq ""  or $setName eq "*");
  257     $problemNumber = "[^|]*" if ($problemNumber eq "" or $problemNumber eq "*");
  258 
  259     #my $pattern = "^[[^]]*]|[^|]*\\|$setName\\|$problemNumber\\|";
  260     my $pattern = "\\|$studentUser\\|$setName\\|$problemNumber\\|";
  261 
  262     our ($lastdate, $lasttime, $lastID, $lastn);
  263 
  264 
  265     if (open(LOG,"$answer_log")) {
  266       my $line;
  267       local ($lastdate, $lasttime, $lastID, $lastn) = ("",0,"",0);
  268       $self->{lastdate}       = '';
  269       $self->{lasttime}       = '';
  270       $self->{lastID}         = '';
  271       $self->{lastn}          = '';
  272 
  273       # get data from file
  274 
  275       my @lines = grep(/$pattern/,<LOG>); close(LOG);
  276       chomp(@lines);
  277 
  278       my $maxcount = 0;
  279       foreach my $newline (@lines) {
  280         my @words = split /\t/, $newline;
  281         my $count = @words;
  282         $maxcount = $count if $count > $maxcount;
  283       }
  284       @selected_answers = (1..$maxcount) unless @selected_answers;
  285 
  286 #     print "<CENTER>\n";
  287       print CGI::start_table({
  288           -border => "1",
  289 #         -cellpadding => '3',
  290 #         -cellspacing => '0',
  291           -onload => "",
  292         }) . "\n";
  293 
  294       my @tableHeaders;
  295       foreach (@fieldOrder) {
  296         push @tableHeaders, $prettyFieldNames{$_} unless $_ eq "answers";
  297       }
  298       print CGI::Tr({}, CGI::th({}, \@tableHeaders) , CGI::th({-colspan => 200}, $prettyFieldNames{answers}));
  299 
  300       my @Records;
  301       #####################################################################
  302       # create array of records
  303       #####################################################################
  304       foreach $line ( @lines ) {
  305         my %fakeRecord = ();
  306         #print CGI::br() . $line;
  307         next if not $line =~ /\|(\w+)\|([\w\d_-]+)\|(\d+)\|\s*(\d+)(.*?)\t?$/;
  308         $fakeRecord{user_id} = "$1";
  309         $fakeRecord{set_id} = "$2";
  310         $fakeRecord{problem_id} = "$3";
  311         $fakeRecord{date} = $4; #formatDateTime($4);
  312         $fakeRecord{answers} = [ split "\t", "$5", -1 ] if $5; # the -1 stops split from dropping any trailing null fields
  313         my @answers = map { $_ ? showHTML($_) : CGI::small(CGI::i("empty")) } @{ $fakeRecord{answers} };
  314         shift @answers; # first field is always empty
  315         $fakeRecord{answers} = \@answers;
  316 
  317 
  318         my @tableCells;
  319         foreach (@fieldOrder) {
  320 
  321           #push @tableCells, showHTML($fakeRecord{$_});
  322         }
  323 
  324         push @Records, \%fakeRecord;
  325 
  326         #print join " ", map { "$_ = $fakeRecord{$_}" } keys %fakeRecord;
  327         #print CGI::br();
  328 #       print CGI::Tr({}, CGI::td({}, \@tableCells));
  329 
  330         #print $self->tableRow(split("\t",$line."\tx"));
  331       }
  332 
  333       #####################################################################
  334       # sort array of records
  335       #####################################################################
  336 
  337       @Records = sort byUSPD @Records;
  338 
  339       #####################################################################
  340       # print array of records
  341       #####################################################################
  342 
  343       foreach my $record (@Records) {
  344         my @tableCells;
  345         foreach (@fieldOrder) {
  346           if ($_ eq "answers") {
  347             my $i = 0;
  348             my %answers = map { ++$i => $_ } @{ $record->{$_} };
  349             push @tableCells, @answers{@selected_answers};
  350           } elsif ($_ eq "date") {
  351             my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime $record->{$_};
  352             $wday = ("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat")[$wday];
  353             $mon = ("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec")[$mon];
  354             $year += 1900;
  355             my $ampm = ("am", "pm")[$hour > 12];
  356             $hour = $hour % 12;
  357             push @tableCells, showHTML("$wday $mday $mon $year $hour:$min $ampm");
  358           } else {
  359             push @tableCells, $record->{$_};
  360           }
  361         }
  362 
  363         print CGI::Tr({}, CGI::td({}, \@tableCells));
  364       }
  365 
  366       # print a horizontal line
  367       #print CGI::Tr({}, CGI::td({colspan => $lastn}, CGI::hr({size => 3})));
  368       print CGI::end_table({});
  369 #     print "\n</CENTER>\n\n";
  370       print CGI::p(
  371                   CGI::i("No entries for " . ($safeUser ? "user $safeUser " : '' ) . ($safeSet ? "set $safeSet " : '' ) . ($safeSet and $safeProb ? ', ' : '') . ($safeProb ? "problem $safeProb" : ''))
  372       ) unless @lines;
  373 
  374     } else {
  375       print CGI::em("Can't open the access log $answer_log");
  376     }
  377   }
  378 
  379 
  380   return "";
  381 }
  382 
  383 sub tableRow {
  384   my $self       = shift;
  385   my $lastID     = $self->{lastID};
  386   my $lastn      = $self->{lastn};
  387   my $lasttime   = $self->{lasttime};
  388   my $lastdate   = $self->{lastdate};
  389   my ($out,$answer,$studentUser,$set,$prob) = "";
  390   my ($ID,$rtime,@answers) = @_; pop(@answers);
  391   my $date = scalar(localtime($rtime)); $date =~ s/\s+/ /g;
  392   my ($day,$month,$mdate,$time,$year) = split(" ",$date);
  393   $date = "$mdate $month $year";
  394   my $n = 2*(scalar(@answers)+1);
  395 
  396   if ($lastID ne $ID) {
  397     if ($lastn) {
  398       print qq{<TR><TD COLSPAN="$lastn"><HR SIZE="3"></TD></TR>\n<P>\n\n};
  399       print '<TABLE BORDER="0" CELLPADDING="0" CELLSPACING="3">',"\n";
  400     }
  401     ($studentUser,$set,$prob) = (split('\|',$ID))[1,2,3];
  402     $out .= qq{<TR ALIGN="CENTER"><TD COLSPAN="$n"><HR SIZE="3">
  403       User: <B>$studentUser</B> &nbsp;
  404       Set: <B>$set</B> &nbsp;
  405       Problem: <B>$prob</B></TD></TR>\n};
  406     $lastID = $ID; $lasttime = 0; $lastdate = "";
  407   }
  408 
  409   $out .= qq{<TR><TD COLSPAN="$n"><HR SIZE="1"></TD></TR>\n}
  410   if ($rtime - $lasttime > 30*60);
  411   $lasttime = $rtime; $lastn = $n;
  412 
  413   if ($lastdate ne $date) {
  414     $out .= qq{<TR><TD COLSPAN="$n"><SMALL><I>$date</I></SMALL></TD></TR>\n};
  415     $lastdate = $date;
  416   }
  417 
  418   $out .= '<TR><TD WIDTH="10"></TD>'.
  419     '<TD><FONT COLOR="#808080"><SMALL>'.$time.'</SMALL></FONT></TD>';
  420   foreach $answer (@answers) {
  421     $answer =~ s/(^\s+|\s+$)//g;
  422     $answer = showHTML($answer);
  423     $answer = "<SMALL><I>empty</I></SMALL>" if ($answer eq "");
  424     $out .= qq{<TD WIDTH="20"></TD><TD NOWRAP>$answer</TD>};
  425   }
  426   $out .= "</TR>\n";
  427   $out;
  428 }
  429 
  430 ################################################################################
  431 # sorts
  432 ################################################################################
  433 
  434 sub byUserID      { $a->{user_id}      cmp $b->{user_id}    }
  435 sub bySetID       { lc($a->{set_id})   cmp lc($b->{set_id})     }
  436 sub byProblemID   { $a->{problem_id}   <=> $b->{problem_id} }
  437 sub byDate        { $a->{date}         cmp $b->{date}       }
  438 
  439 sub byUSPD  { &byUserID || &bySetID || &byProblemID || &byDate }
  440 
  441 ##################################################
  442 #
  443 #  Make HTML symbols printable
  444 #
  445 sub showHTML {
  446   my $string = shift;
  447   return '' unless defined $string;
  448   $string =~ s/&/\&amp;/g;
  449   $string =~ s/</\&lt;/g;
  450   $string =~ s/>/\&gt;/g;
  451   $string =~ s//,/g;
  452   $string =~ s/ /&nbsp;/g;
  453   return $string;
  454 }
  455 
  456 1;

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9