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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2980 - (download) (as text) (annotate)
Wed Nov 3 19:52:01 2004 UTC (8 years, 6 months ago)
File size: 14405 byte(s)
This commit was manufactured by cvs2svn to create branch 'rel-2-1-patches'.

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

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9