Parent Directory
|
Revision Log
Revision 5319 -
(view)
(download)
(as text)
Original Path: trunk/webwork2/lib/WeBWorK/ContentGenerator/Feedback.pm
| 1 : | sh002i | 668 | ################################################################################ |
| 2 : | sh002i | 1663 | # WeBWorK Online Homework Delivery System |
| 3 : | sh002i | 5319 | # Copyright © 2000-2007 The WeBWorK Project, http://openwebwork.sf.net/ |
| 4 : | # $CVSHeader: webwork2/lib/WeBWorK/ContentGenerator/Feedback.pm,v 1.43 2007/02/14 18:16:46 sh002i Exp $ | ||
| 5 : | sh002i | 1663 | # |
| 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 : | sh002i | 668 | ################################################################################ |
| 16 : | |||
| 17 : | package WeBWorK::ContentGenerator::Feedback; | ||
| 18 : | sh002i | 818 | use base qw(WeBWorK::ContentGenerator); |
| 19 : | sh002i | 668 | |
| 20 : | =head1 NAME | ||
| 21 : | |||
| 22 : | WeBWorK::ContentGenerator::Feedback - Send mail to professors. | ||
| 23 : | |||
| 24 : | =cut | ||
| 25 : | |||
| 26 : | sh002i | 818 | # *** feedback should be exempt from authentication, so that people can send |
| 27 : | sh002i | 668 | # feedback from the login page! |
| 28 : | |||
| 29 : | use strict; | ||
| 30 : | use warnings; | ||
| 31 : | use Data::Dumper; | ||
| 32 : | gage | 4235 | #use CGI qw(-nosticky ); |
| 33 : | use WeBWorK::CGI; | ||
| 34 : | sh002i | 668 | use Mail::Sender; |
| 35 : | sh002i | 4108 | use Socket qw/unpack_sockaddr_in inet_ntoa/; # for remote host/port info |
| 36 : | sh002i | 668 | use Text::Wrap qw(wrap); |
| 37 : | sh002i | 3639 | use WeBWorK::Utils qw/formatDateTime decodeAnswers/; |
| 38 : | sh002i | 668 | |
| 39 : | sh002i | 4594 | use mod_perl; |
| 40 : | use constant MP2 => ( exists $ENV{MOD_PERL_API_VERSION} and $ENV{MOD_PERL_API_VERSION} >= 2 ); | ||
| 41 : | |||
| 42 : | sh002i | 668 | # request paramaters used |
| 43 : | # | ||
| 44 : | # user | ||
| 45 : | # key | ||
| 46 : | # module | ||
| 47 : | # set (if from ProblemSet or Problem) | ||
| 48 : | # problem (if from Problem) | ||
| 49 : | # displayMode (if from Problem) | ||
| 50 : | # showOldAnswers (if from Problem) | ||
| 51 : | # showCorrectAnswers (if from Problem) | ||
| 52 : | # showHints (if from Problem) | ||
| 53 : | # showSolutions (if from Problem) | ||
| 54 : | |||
| 55 : | # state data sent | ||
| 56 : | # | ||
| 57 : | # user object for current user | ||
| 58 : | # permission level of current user | ||
| 59 : | # current session key | ||
| 60 : | # which ContentGenerator module called Feedback? | ||
| 61 : | # set object for current set (if from ProblemSet or Problem) | ||
| 62 : | # problem object for current problem (if from Problem) | ||
| 63 : | # display options (if from Problem) | ||
| 64 : | |||
| 65 : | sub body { | ||
| 66 : | sh002i | 1876 | my ($self) = @_; |
| 67 : | my $r = $self->r; | ||
| 68 : | my $ce = $r->ce; | ||
| 69 : | my $db = $r->db; | ||
| 70 : | sh002i | 2724 | my $authz = $r->authz; |
| 71 : | sh002i | 668 | |
| 72 : | # get form fields | ||
| 73 : | my $key = $r->param("key"); | ||
| 74 : | my $userName = $r->param("user"); | ||
| 75 : | my $module = $r->param("module"); | ||
| 76 : | my $setName = $r->param("set"); | ||
| 77 : | my $problemNumber = $r->param("problem"); | ||
| 78 : | my $displayMode = $r->param("displayMode"); | ||
| 79 : | my $showOldAnswers = $r->param("showOldAnswers"); | ||
| 80 : | my $showCorrectAnswers = $r->param("showCorrectAnswers"); | ||
| 81 : | my $showHints = $r->param("showHints"); | ||
| 82 : | my $showSolutions = $r->param("showSolutions"); | ||
| 83 : | my $from = $r->param("from"); | ||
| 84 : | my $feedback = $r->param("feedback"); | ||
| 85 : | gage | 3127 | my $courseID = $r->urlpath->arg("courseID"); |
| 86 : | sh002i | 668 | |
| 87 : | sh002i | 1636 | my ($user, $set, $problem); |
| 88 : | $user = $db->getUser($userName) # checked | ||
| 89 : | if defined $userName and $userName ne ""; | ||
| 90 : | if (defined $user) { | ||
| 91 : | $set = $db->getMergedSet($userName, $setName) # checked | ||
| 92 : | if defined $setName and $setName ne ""; | ||
| 93 : | $problem = $db->getMergedProblem($userName, $setName, $problemNumber) # checked | ||
| 94 : | if defined $set and defined $problemNumber && $problemNumber ne ""; | ||
| 95 : | } else { | ||
| 96 : | $set = $db->getGlobalSet($setName) # checked | ||
| 97 : | if defined $setName and $setName ne ""; | ||
| 98 : | $problem = $db->getGlobalProblem($setName, $problemNumber) # checked | ||
| 99 : | if defined $set and defined $problemNumber && $problemNumber ne ""; | ||
| 100 : | } | ||
| 101 : | sh002i | 668 | |
| 102 : | sh002i | 1883 | # generate context URLs |
| 103 : | sh002i | 1636 | my $emailableURL; |
| 104 : | my $returnURL; | ||
| 105 : | if ($user) { | ||
| 106 : | sh002i | 1883 | my $modulePath; |
| 107 : | my @args; | ||
| 108 : | if ($set) { | ||
| 109 : | if ($problem) { | ||
| 110 : | $modulePath = $r->urlpath->newFromModule("WeBWorK::ContentGenerator::Problem", | ||
| 111 : | courseID => $r->urlpath->arg("courseID"), | ||
| 112 : | setID => $set->set_id, | ||
| 113 : | problemID => $problem->problem_id, | ||
| 114 : | ); | ||
| 115 : | @args = qw/displayMode showOldAnswers showCorrectAnswers showHints showSolutions/; | ||
| 116 : | } else { | ||
| 117 : | $modulePath = $r->urlpath->newFromModule("WeBWorK::ContentGenerator::ProblemSet", | ||
| 118 : | courseID => $r->urlpath->arg("courseID"), | ||
| 119 : | setID => $set->set_id, | ||
| 120 : | ); | ||
| 121 : | @args = (); | ||
| 122 : | } | ||
| 123 : | } else { | ||
| 124 : | $modulePath = $r->urlpath->newFromModule("WeBWorK::ContentGenerator::ProblemSets", | ||
| 125 : | courseID => $r->urlpath->arg("courseID"), | ||
| 126 : | ); | ||
| 127 : | @args = (); | ||
| 128 : | } | ||
| 129 : | sh002i | 4108 | $emailableURL = $self->systemLink($modulePath, |
| 130 : | sh002i | 1883 | authen => 0, |
| 131 : | params => [ "effectiveUser", @args ], | ||
| 132 : | sh002i | 4108 | use_abs_url => 1, |
| 133 : | sh002i | 1883 | ); |
| 134 : | sh002i | 4108 | $returnURL = $self->systemLink($modulePath, |
| 135 : | sh002i | 1883 | authen => 1, |
| 136 : | params => [ @args ], | ||
| 137 : | ); | ||
| 138 : | sh002i | 1636 | } else { |
| 139 : | sh002i | 1883 | $emailableURL = "(not available)"; |
| 140 : | sh002i | 1636 | $returnURL = ""; |
| 141 : | } | ||
| 142 : | sh002i | 4108 | my $homeModulePath = $r->urlpath->newFromModule("WeBWorK::ContentGenerator::Home"); |
| 143 : | my $systemURL = $self->systemLink($homeModulePath, authen=>0, use_abs_url=>1); | ||
| 144 : | sh002i | 1636 | |
| 145 : | sh002i | 2849 | unless ($authz->hasPermissions($userName, "submit_feedback")) { |
| 146 : | $self->feedbackNotAllowed($returnURL); | ||
| 147 : | return ""; | ||
| 148 : | } | ||
| 149 : | |||
| 150 : | sh002i | 3623 | # determine the recipients of the email |
| 151 : | my @recipients = $self->getFeedbackRecipients(); | ||
| 152 : | |||
| 153 : | unless (@recipients) { | ||
| 154 : | $self->noRecipientsAvailable($returnURL); | ||
| 155 : | return ""; | ||
| 156 : | } | ||
| 157 : | |||
| 158 : | sh002i | 668 | if (defined $r->param("sendFeedback")) { |
| 159 : | sh002i | 740 | # get verbosity level |
| 160 : | my $verbosity = $ce->{mail}->{feedbackVerbosity}; | ||
| 161 : | |||
| 162 : | sh002i | 668 | # determine the sender of the email |
| 163 : | sh002i | 3698 | my $sender; |
| 164 : | if ($user) { | ||
| 165 : | if ($user->email_address) { | ||
| 166 : | $sender = $user->rfc822_mailbox; | ||
| 167 : | } else { | ||
| 168 : | if ($user->full_name) { | ||
| 169 : | $sender = $user->full_name . " <$from>" | ||
| 170 : | } else { | ||
| 171 : | $sender = $from; | ||
| 172 : | } | ||
| 173 : | } | ||
| 174 : | } else { | ||
| 175 : | $sender = $from; | ||
| 176 : | } | ||
| 177 : | sh002i | 668 | |
| 178 : | sh002i | 740 | # sanity checks |
| 179 : | sh002i | 668 | unless ($sender) { |
| 180 : | malsyned | 830 | $self->feedbackForm($user, $returnURL, |
| 181 : | sh002i | 668 | "No Sender specified."); |
| 182 : | return ""; | ||
| 183 : | } | ||
| 184 : | gage | 1501 | unless ($feedback) { |
| 185 : | $self->feedbackForm($user, $returnURL, | ||
| 186 : | "Message was blank."); | ||
| 187 : | return ""; | ||
| 188 : | } | ||
| 189 : | sh002i | 668 | |
| 190 : | sh002i | 3645 | my %subject_map = ( |
| 191 : | 'c' => $courseID, | ||
| 192 : | 'u' => $user ? $user->user_id : undef, | ||
| 193 : | 's' => $set ? $set->set_id : undef, | ||
| 194 : | 'p' => $problem ? $problem->problem_id : undef, | ||
| 195 : | 'x' => $user ? $user->section : undef, | ||
| 196 : | 'r' => $user ? $user->recitation : undef, | ||
| 197 : | '%' => '%', | ||
| 198 : | ); | ||
| 199 : | my $chars = join("", keys %subject_map); | ||
| 200 : | my $subject = $ce->{mail}{feedbackSubjectFormat} | ||
| 201 : | || "WeBWorK feedback from %c: %u set %s/prob %p"; # default if not entered | ||
| 202 : | $subject =~ s/%([$chars])/defined $subject_map{$1} ? $subject_map{$1} : ""/eg; | ||
| 203 : | |||
| 204 : | sh002i | 4594 | # get info about remote user (stolen from &WeBWorK::Authen::write_log_entry) |
| 205 : | my ($remote_host, $remote_port); | ||
| 206 : | if (MP2) { | ||
| 207 : | $remote_host = $r->connection->remote_addr->ip_get || "UNKNOWN"; | ||
| 208 : | $remote_port = $r->connection->remote_addr->port || "UNKNOWN"; | ||
| 209 : | } else { | ||
| 210 : | ($remote_port, $remote_host) = unpack_sockaddr_in($r->connection->remote_addr); | ||
| 211 : | $remote_host = defined $remote_host ? inet_ntoa($remote_host) : "UNKNOWN"; | ||
| 212 : | $remote_port = "UNKNOWN" unless defined $remote_port; | ||
| 213 : | } | ||
| 214 : | #my $user_agent = $r->headers_in("User-Agent"); | ||
| 215 : | |||
| 216 : | my $headers = "X-Remote-Host: $remote_host\n"; | ||
| 217 : | sh002i | 3646 | $headers .= "X-WeBWorK-Module: $module\n" if defined $module; |
| 218 : | $headers .= "X-WeBWorK-Course: $courseID\n" if defined $courseID; | ||
| 219 : | if ($user) { | ||
| 220 : | $headers .= "X-WeBWorK-User: ".$user->user_id."\n"; | ||
| 221 : | $headers .= "X-WeBWorK-Section: ".$user->section."\n"; | ||
| 222 : | $headers .= "X-WeBWorK-Recitation: ".$user->recitation."\n"; | ||
| 223 : | } | ||
| 224 : | $headers .= "X-WeBWorK-Set: ".$set->set_id."\n" if $set; | ||
| 225 : | $headers .= "X-WeBWorK-Problem: ".$problem->problem_id."\n" if $problem; | ||
| 226 : | |||
| 227 : | sh002i | 668 | # bring up a mailer |
| 228 : | my $mailer = Mail::Sender->new({ | ||
| 229 : | sh002i | 4778 | from => $ce->{mail}{smtpSender}, |
| 230 : | fake_from => $sender, | ||
| 231 : | sh002i | 668 | to => join(",", @recipients), |
| 232 : | smtp => $ce->{mail}->{smtpServer}, | ||
| 233 : | sh002i | 3645 | subject => $subject, |
| 234 : | sh002i | 3646 | headers => $headers, |
| 235 : | sh002i | 668 | }); |
| 236 : | unless (ref $mailer) { | ||
| 237 : | malsyned | 830 | $self->feedbackForm($user, $returnURL, |
| 238 : | sh002i | 668 | "Failed to create a mailer: $Mail::Sender::Error"); |
| 239 : | return ""; | ||
| 240 : | } | ||
| 241 : | unless (ref $mailer->Open()) { | ||
| 242 : | malsyned | 830 | $self->feedbackForm($user, $returnURL, |
| 243 : | sh002i | 668 | "Failed to open the mailer: $Mail::Sender::Error"); |
| 244 : | return ""; | ||
| 245 : | } | ||
| 246 : | my $MAIL = $mailer->GetHandle(); | ||
| 247 : | |||
| 248 : | sh002i | 740 | # print message |
| 249 : | sh002i | 668 | print $MAIL |
| 250 : | sh002i | 4108 | wrap("", "", "This feedback message was automatically generated by the WeBWorK", |
| 251 : | sh002i | 4594 | "system at $systemURL, in response to a request from $remote_host:$remote_port." |
| 252 : | sh002i | 4108 | ), "\n\n"; |
| 253 : | sh002i | 668 | |
| 254 : | sh002i | 3648 | print $MAIL "Click this link to see the page from which the user sent feedback:\n", |
| 255 : | "$emailableURL\n\n"; | ||
| 256 : | |||
| 257 : | sh002i | 668 | if ($feedback) { |
| 258 : | print $MAIL | ||
| 259 : | "***** The feedback message: *****\n\n", | ||
| 260 : | wrap("", "", $feedback), "\n\n"; | ||
| 261 : | } | ||
| 262 : | sh002i | 740 | if ($problem and $verbosity >= 1) { |
| 263 : | sh002i | 668 | print $MAIL |
| 264 : | "***** Data about the problem processor: *****\n\n", | ||
| 265 : | |||
| 266 : | "Display Mode: $displayMode\n", | ||
| 267 : | sh002i | 3639 | "Show Old Answers: " . ($showOldAnswers ? "yes" : "no") . "\n", |
| 268 : | "Show Correct Answers: " . ($showCorrectAnswers ? "yes" : "no") . "\n", | ||
| 269 : | "Show Hints: " . ($showHints ? "yes" : "no") . "\n", | ||
| 270 : | "Show Solutions: " . ($showSolutions ? "yes" : "no") . "\n\n", | ||
| 271 : | sh002i | 668 | } |
| 272 : | sh002i | 740 | if ($user and $verbosity >= 1) { |
| 273 : | sh002i | 668 | print $MAIL |
| 274 : | "***** Data about the user: *****\n\n", | ||
| 275 : | sh002i | 3639 | #$user->toString(), "\n\n"; |
| 276 : | $self->format_user($user), "\n"; | ||
| 277 : | sh002i | 668 | } |
| 278 : | sh002i | 740 | if ($problem and $verbosity >= 1) { |
| 279 : | sh002i | 668 | print $MAIL |
| 280 : | "***** Data about the problem: *****\n\n", | ||
| 281 : | sh002i | 3639 | #$problem->toString(), "\n\n"; |
| 282 : | $self->format_userproblem($problem), "\n"; | ||
| 283 : | sh002i | 668 | } |
| 284 : | sh002i | 740 | if ($set and $verbosity >= 1) { |
| 285 : | sh002i | 668 | print $MAIL |
| 286 : | sh002i | 3357 | "***** Data about the homework set: *****\n\n", |
| 287 : | sh002i | 3639 | #$set->toString(), "\n\n"; |
| 288 : | $self->format_userset($set), "\n"; | ||
| 289 : | sh002i | 668 | } |
| 290 : | sh002i | 740 | if ($ce and $verbosity >= 2) { |
| 291 : | sh002i | 668 | print $MAIL |
| 292 : | "***** Data about the environment: *****\n\n", | ||
| 293 : | Dumper($ce), "\n\n"; | ||
| 294 : | } | ||
| 295 : | |||
| 296 : | sh002i | 3639 | # Close returns the mailer object on success, a negative value on failure, |
| 297 : | # zero if mailer was not opened. | ||
| 298 : | my $result = $mailer->Close; | ||
| 299 : | sh002i | 668 | |
| 300 : | sh002i | 3639 | if (ref $result) { |
| 301 : | # print confirmation | ||
| 302 : | print CGI::p("Your message was sent successfully."); | ||
| 303 : | print CGI::p(CGI::a({-href => $returnURL}, "Return to your work")); | ||
| 304 : | print CGI::pre(wrap("", "", $feedback)); | ||
| 305 : | } else { | ||
| 306 : | $self->feedbackForm($user, $returnURL, | ||
| 307 : | "Failed to send message ($result): $Mail::Sender::Error"); | ||
| 308 : | } | ||
| 309 : | sh002i | 668 | } else { |
| 310 : | # just print the feedback form, with no message | ||
| 311 : | sh002i | 1876 | $self->feedbackForm($user, $returnURL, ""); |
| 312 : | sh002i | 668 | } |
| 313 : | |||
| 314 : | return ""; | ||
| 315 : | } | ||
| 316 : | |||
| 317 : | sh002i | 2849 | sub feedbackNotAllowed { |
| 318 : | my ($self, $returnURL) = @_; | ||
| 319 : | |||
| 320 : | print CGI::p("You are not allowed to send feedback."); | ||
| 321 : | print CGI::p(CGI::a({-href=>$returnURL}, "Cancel Feedback")) if $returnURL; | ||
| 322 : | } | ||
| 323 : | |||
| 324 : | sh002i | 3623 | sub noRecipientsAvailable { |
| 325 : | my ($self, $returnURL) = @_; | ||
| 326 : | |||
| 327 : | print CGI::p("No feedback recipients are listed for this course."); | ||
| 328 : | print CGI::p(CGI::a({-href=>$returnURL}, "Cancel Feedback")) if $returnURL; | ||
| 329 : | } | ||
| 330 : | |||
| 331 : | sh002i | 1876 | sub feedbackForm { |
| 332 : | my ($self, $user, $returnURL, $message) = @_; | ||
| 333 : | my $r = $self->r; | ||
| 334 : | sh002i | 668 | |
| 335 : | print CGI::start_form(-method=>"POST", -action=>$r->uri); | ||
| 336 : | print $self->hidden_authen_fields; | ||
| 337 : | sh002i | 1883 | print $self->hidden_fields(qw( |
| 338 : | module set problem displayMode showOldAnswers showCorrectAnswers | ||
| 339 : | showHints showSolutions | ||
| 340 : | )); | ||
| 341 : | sh002i | 668 | print CGI::p(CGI::b("From:"), " ", |
| 342 : | sh002i | 675 | ($user && $user->email_address |
| 343 : | sh002i | 668 | ? CGI::tt($user->email_address) |
| 344 : | : CGI::textfield("from", "", 40)) | ||
| 345 : | ); | ||
| 346 : | print CGI::p("Use this form to report to your professor a | ||
| 347 : | problem with the WeBWorK system or an error in a problem | ||
| 348 : | you are attempting. Along with your message, additional | ||
| 349 : | information about the state of the system will be | ||
| 350 : | included."); | ||
| 351 : | print CGI::p(CGI::i($message)) if $message; | ||
| 352 : | print CGI::p( | ||
| 353 : | CGI::b("Feedback:"), CGI::br(), | ||
| 354 : | gage | 1470 | CGI::textarea("feedback", "", 20, 80), |
| 355 : | sh002i | 668 | ); |
| 356 : | print CGI::submit("sendFeedback", "Send Feedback"); | ||
| 357 : | print CGI::end_form(); | ||
| 358 : | sh002i | 2849 | print CGI::p(CGI::a({-href=>$returnURL}, "Cancel Feedback")) if $returnURL; |
| 359 : | sh002i | 668 | } |
| 360 : | |||
| 361 : | sh002i | 3623 | sub getFeedbackRecipients { |
| 362 : | my ($self) = @_; | ||
| 363 : | my $ce = $self->r->ce; | ||
| 364 : | my $db = $self->r->db; | ||
| 365 : | my $authz = $self->r->authz; | ||
| 366 : | |||
| 367 : | my @recipients; | ||
| 368 : | sh002i | 3627 | |
| 369 : | # send to all users with permission to receive_feedback and an email address | ||
| 370 : | sh002i | 4518 | # DBFIXME iterator? |
| 371 : | sh002i | 3627 | foreach my $rcptName ($db->listUsers()) { |
| 372 : | if ($authz->hasPermissions($rcptName, "receive_feedback")) { | ||
| 373 : | my $rcpt = $db->getUser($rcptName); # checked | ||
| 374 : | if ($rcpt and $rcpt->email_address) { | ||
| 375 : | sh002i | 3698 | push @recipients, $rcpt->rfc822_mailbox; |
| 376 : | sh002i | 3623 | } |
| 377 : | } | ||
| 378 : | } | ||
| 379 : | |||
| 380 : | sh002i | 3627 | if (defined $ce->{mail}->{feedbackRecipients}) { |
| 381 : | push @recipients, @{$ce->{mail}->{feedbackRecipients}}; | ||
| 382 : | } | ||
| 383 : | |||
| 384 : | sh002i | 3623 | return @recipients; |
| 385 : | } | ||
| 386 : | |||
| 387 : | sh002i | 3639 | sub format_user { |
| 388 : | my ($self, $User) = @_; | ||
| 389 : | my $ce = $self->r->ce; | ||
| 390 : | |||
| 391 : | my $result = "User ID: " . $User->user_id . "\n"; | ||
| 392 : | sh002i | 3698 | $result .= "Name: " . $User->full_name . "\n"; |
| 393 : | sh002i | 3639 | $result .= "Email: " . $User->email_address . "\n"; |
| 394 : | $result .= "Student ID: " . $User->student_id . "\n"; | ||
| 395 : | |||
| 396 : | sh002i | 3688 | my $status_name = $ce->status_abbrev_to_name($User->status); |
| 397 : | my $status_string = defined $status_name | ||
| 398 : | ? "$status_name ('" . $User->status . "')" | ||
| 399 : | : $User->status . " (unknown status abbreviation)"; | ||
| 400 : | $result .= "Status: $status_string\n"; | ||
| 401 : | sh002i | 3639 | |
| 402 : | $result .= "Section: " . $User->section . "\n"; | ||
| 403 : | $result .= "Recitation: " . $User->recitation . "\n"; | ||
| 404 : | $result .= "Comment: " . $User->comment . "\n"; | ||
| 405 : | |||
| 406 : | return $result; | ||
| 407 : | } | ||
| 408 : | |||
| 409 : | sub format_userset { | ||
| 410 : | my ($self, $Set) = @_; | ||
| 411 : | my $ce = $self->r->ce; | ||
| 412 : | |||
| 413 : | my $result = "Set ID: " . $Set->set_id . "\n"; | ||
| 414 : | $result .= "Set header file: " . $Set->set_header . "\n"; | ||
| 415 : | $result .= "Hardcopy header file: " . $Set->hardcopy_header . "\n"; | ||
| 416 : | |||
| 417 : | my $tz = $ce->{siteDefaults}{timezone}; | ||
| 418 : | $result .= "Open date: " . formatDateTime($Set->open_date, $tz) . "\n"; | ||
| 419 : | $result .= "Due date: " . formatDateTime($Set->due_date, $tz) . "\n"; | ||
| 420 : | $result .= "Answer date: " . formatDateTime($Set->answer_date, $tz) . "\n"; | ||
| 421 : | $result .= "Published: " . ($Set->published ? "yes" : "no") . "\n"; | ||
| 422 : | $result .= "Assignment type: " . $Set->assignment_type . "\n"; | ||
| 423 : | if ($Set->assignment_type =~ /gateway/) { | ||
| 424 : | $result .= "Attempts per version: " . $Set->assignment_type . "\n"; | ||
| 425 : | $result .= "Time interval: " . $Set->time_interval . "\n"; | ||
| 426 : | $result .= "Versions per interval: " . $Set->versions_per_interval . "\n"; | ||
| 427 : | $result .= "Version time limit: " . $Set->version_time_limit . "\n"; | ||
| 428 : | $result .= "Version creation time: " . formatDateTime($Set->version_creation_time, $tz) . "\n"; | ||
| 429 : | $result .= "Problem randorder: " . $Set->problem_randorder . "\n"; | ||
| 430 : | $result .= "Version last attempt time: " . $Set->version_last_attempt_time . "\n"; | ||
| 431 : | } | ||
| 432 : | |||
| 433 : | return $result; | ||
| 434 : | } | ||
| 435 : | |||
| 436 : | sub format_userproblem { | ||
| 437 : | my ($self, $Problem) = @_; | ||
| 438 : | my $ce = $self->r->ce; | ||
| 439 : | |||
| 440 : | my $result = "Problem ID: " . $Problem->problem_id . "\n"; | ||
| 441 : | $result .= "Source file: " . $Problem->source_file . "\n"; | ||
| 442 : | $result .= "Value: " . $Problem->value . "\n"; | ||
| 443 : | $result .= "Max attempts " . ($Problem->max_attempts == -1 ? "unlimited" : $Problem->max_attempts) . "\n"; | ||
| 444 : | $result .= "Random seed: " . $Problem->problem_seed . "\n"; | ||
| 445 : | $result .= "Status: " . $Problem->status . "\n"; | ||
| 446 : | $result .= "Attempted: " . ($Problem->attempted ? "yes" : "no") . "\n"; | ||
| 447 : | |||
| 448 : | my %last_answer = decodeAnswers($Problem->last_answer); | ||
| 449 : | if (%last_answer) { | ||
| 450 : | $result .= "Last answer:\n"; | ||
| 451 : | foreach my $key (sort keys %last_answer) { | ||
| 452 : | $result .= "\t$key: $last_answer{$key}\n"; | ||
| 453 : | } | ||
| 454 : | } else { | ||
| 455 : | $result .= "Last answer: none\n"; | ||
| 456 : | } | ||
| 457 : | |||
| 458 : | $result .= "Number of correct attempts: " . $Problem->num_correct . "\n"; | ||
| 459 : | $result .= "Number of incorrect attempts: " . $Problem->num_incorrect . "\n"; | ||
| 460 : | |||
| 461 : | return $result; | ||
| 462 : | } | ||
| 463 : | |||
| 464 : | sh002i | 668 | 1; |
| aubreyja at gmail dot com | ViewVC Help |
| Powered by ViewVC 1.0.9 |