Parent Directory
|
Revision Log
backups work now. The list of merge files can be found. To do: 1.. Get better list of students (with entire names) 2. Get view of merge file 3. Get preview working --Mike
1 package WeBWorK::ContentGenerator::Instructor::SendMail; 2 use base qw(WeBWorK::ContentGenerator::Instructor); 3 4 =head1 NAME 5 6 WeBWorK::ContentGenerator::Instructor::SendMail - Entry point for User-specific data editing 7 8 =cut 9 10 use strict; 11 use warnings; 12 use CGI qw(); 13 use HTML::Entities; 14 15 sub initialize { 16 my ($self) = @_; 17 my $r = $self->{r}; 18 my $db = $self->{db}; 19 my $ce = $self->{ce}; 20 my $authz = $self->{authz}; 21 my $user = $r->param('user'); 22 23 unless ($authz->hasPermissions($user, "send_mail")) { 24 $self->{submitError} = "You are not authorized to send mail to students."; 25 return; 26 } 27 ############################################################################################# 28 # gather directory data 29 ############################################################################################# 30 my $emailDirectory = $ce->{courseDirs}->{email}; 31 my $scoringDirectory = $ce->{courseDirs}->{scoring}; 32 my $templateDirectory = $ce->{courseDirs}->{templates}; 33 34 my $action = $r->param('action'); 35 my $openfilename = $r->param('openfilename'); 36 my $savefilename = $r->param('savefilename'); 37 38 39 #FIXME get these values from global course environment (see subroutines as well) 40 my $default_msg_file = 'default.msg'; 41 my $old_default_msg_file = 'old_default.msg'; 42 43 # store data 44 $self->{defaultFrom} = 'FIXME from'; 45 $self->{defaultReply} = 'FIXME reply'; 46 $self->{rows} = (defined($r->param('rows'))) ? $r->param('rows') : $ce->{mail}->{editor_window_rows}; 47 $self->{columns} = (defined($r->param('columns'))) ? $r->param('columns') : $ce->{mail}->{editor_window_columns}; 48 $self->{default_msg_file} = $default_msg_file; 49 $self->{old_default_msg_file} = $old_default_msg_file; 50 $self->{merge_file} = (defined($r->param('merge_file'))) ? $r->param('merge_file') : 'None'; 51 ################################################################# 52 # Check the validity of the input file name 53 ################################################################# 54 my $input_file = ''; 55 #make sure an input message file was submitted and exists 56 #else use the default message 57 if ( defined($openfilename) ) { 58 if ( -e "${emailDirectory}/$openfilename") { 59 if ( -R "${emailDirectory}/$openfilename") { 60 $input_file = $openfilename; 61 } else { 62 warn join("", 63 "The file ${emailDirectory}/$openfilename is not readable by the webserver.",CGI::br(), 64 "Check that it's permissions are set correctly.", 65 ); 66 } 67 } else { 68 $input_file = $default_msg_file; 69 warn join("", 70 "The file ${emailDirectory}/$openfilename cannot be found.",CGI::br(), 71 "Check whether it exists and whether the directory $emailDirectory can be read by the webserver.",CGI::br(), 72 "Using contents of the default message $default_msg_file instead.", 73 ); 74 } 75 } else { 76 $input_file = $default_msg_file; 77 } 78 $self->{input_file}=$input_file; 79 80 ################################################################# 81 # Determine the file name to save message into 82 ################################################################# 83 my $output_file = 'FIXME no output file specified'; 84 if (defined($action) and $action eq 'Save as Default') { 85 $output_file = $default_msg_file; 86 } elsif ( defined($action) and ($action =~/save/i) and defined($savefilename) ){ 87 $output_file = $savefilename; 88 } elsif ( defined($input_file) ) { 89 $output_file = $input_file; 90 } 91 # warn "FIXME savefilename $savefilename output file $output_file"; 92 ################################################################# 93 # Sanity check on save file name 94 ################################################################# 95 96 if ($output_file =~ /^[~.]/ || $output_file =~ /\.\./) { 97 $self->submission_error("For security reasons, you cannot specify a merge file from a directory", 98 "higher than the email directory (you can't use ../blah/blah). ", 99 "Please specify a different file or move the needed file to the email directory", 100 ); 101 } 102 unless ($output_file =~ m|\.msg$| ) { 103 $self->submission_error("Invalid file name.", 104 "The file name \"$output_file\" does not have a \".msg\" extension", 105 "All email file names must end in the extension \".msg\"", 106 "choose a file name with a \".msg\" extension.", 107 "The message was not saved.", 108 ); 109 } 110 $self->{output_file} = $output_file; # this is ok. It will be put back in the text input box for re-editing. 111 # FIXME $output_file can be blank if there was no savefilename 112 113 ############################################################################################# 114 # Determine input source 115 ############################################################################################# 116 my $input_source = ( defined( $r->param('body') ) and $action ne 'Open' ) ? 'form' : 'file'; 117 # warn "FIXME input source is $input_source from $input_file"; 118 ############################################################################################# 119 # Get inputs 120 ############################################################################################# 121 my($from, $replyTo, $r_text, $subject); 122 if ($input_source eq 'file') { 123 # warn "FIXME obtaining source from $emailDirectory/$input_file"; 124 ($from, $replyTo,$subject,$r_text) = $self->read_input_file("$emailDirectory/$input_file"); 125 # warn "FIXME Done reading source"; 126 127 } elsif ($input_source eq 'form') { 128 # read info from the form 129 # bail if there is no message body 130 131 $from = $r->param('from'); 132 $replyTo = $r->param('replyTo'); 133 $subject = $r->param('subject'); 134 my $body = $r->param('body'); 135 # Sanity check: body must contain non-white space 136 $self->submission_error('You didn\'t enter any message.') unless ($r->param('body') =~ /\S/); 137 $r_text = \$body; 138 139 } 140 # store data 141 $self->{from} = $from; 142 $self->{replyTo} = $replyTo; 143 $self->{subject} = $subject; 144 $self->{r_text} = $r_text; 145 146 147 ############################################################################################# 148 # if no form is submitted, gather data needed to produce the mail form and return 149 ############################################################################################# 150 151 if(not defined($action) or $action eq 'Open' or $action eq 'Resize message window' 152 or $action eq 'Choose merge file' ){ 153 # warn "FIXME action is |$action| no further initialization required"; 154 return ''; 155 } 156 157 158 159 160 161 ############################################################################################# 162 # If form is submitted deal with filled out forms 163 # and various actions resulting from different buttons 164 ############################################################################################# 165 166 167 my $to = $r->param('To'); 168 169 170 171 ################################################################################### 172 #Determine the appropriate script action from the buttons 173 ################################################################################### 174 # save actions 175 # "save" button 176 # "save as" button 177 # "save as default" button 178 # preview actions 179 # 'preview' button 180 # email actions 181 # 'entire class' 182 # 'selected studentIDs' 183 # option actions 184 # 'reset rows' 185 # error actions (various) 186 187 my $script_action = ''; 188 # user_errors 189 # save 190 # save as 191 # save as default 192 # send mail 193 # set defaults 194 195 if ($action eq 'Save' or $action eq 'Save as:' or $action eq 'Save as Default') { 196 197 # warn "FIXME Saving files action = $action outputFileName=$output_file"; 198 199 ################################################################# 200 # construct message body 201 ################################################################# 202 my $temp_body = ${ $r_text }; 203 $temp_body =~ s/\r\n/\n/g; 204 $temp_body = join("", 205 "From: $from \nReply-To: $replyTo\n" , 206 "Subject: $subject\n" , 207 "Message: \n $temp_body"); 208 # warn "FIXME from $from | subject $subject |reply $replyTo|msg $temp_body"; 209 ################################################################# 210 # overwrite protection 211 ################################################################# 212 if ($action eq 'Save as:' and -e "$emailDirectory/$output_file") { 213 $self->submission_error("The file $emailDirectory/$output_file already exists and cannot be overwritten", 214 "The message was not saved"); 215 return; 216 } 217 218 ################################################################# 219 # Back up existing file? 220 ################################################################# 221 if ($action eq 'Save as Default' and -e "$emailDirectory/$default_msg_file") { 222 rename("$emailDirectory/$default_msg_file","$emailDirectory/$old_default_msg_file") or 223 die "Can't rename $emailDirectory/$default_msg_file to $emailDirectory/$old_default_msg_file ", 224 "Check permissions for webserver on directory $emailDirectory. $!"; 225 $self->{message} .= "Backup file <code>$emailDirectory/$old_default_msg_file</code> created.".CGI::br(); 226 } 227 ################################################################# 228 # Save the message 229 ################################################################# 230 $self->saveProblem($temp_body, "${emailDirectory}/$output_file" ); 231 $self->{message} .= "Message saved to file <code>${emailDirectory}/$output_file</code>."; 232 # warn "FIXME saving to ${emailDirectory}/$output_file"; 233 } elsif ($action eq 'preview') { 234 235 236 } elsif ($action eq 'Send Email') { 237 238 239 240 241 } else { 242 warn "Don't recognize button $action"; 243 } 244 245 #if Save button was clicked 246 if (( $r->param('action') eq 'Save') && defined($r->param('body')) && defined($r->param('savefilename'))) { 247 248 # my $temp_body = $body; 249 # $temp_body =~ s/\r\n/\n/g; 250 # $temp_body = "From: " . $from . "\n" . 251 # "Reply-To: " . $replyTo . "\n" . 252 # "Subject: " . $subject . "\n" . 253 # "Message: \n" . $temp_body; 254 # 255 # saveProblem($temp_body, $savefilename); 256 # $messageFileName = $savefilename; 257 258 #if Save As button was clicked 259 } elsif (( $r->param('action') eq 'Save as:') && defined($r->param('body')) && defined($r->param('savefilename'))) { 260 261 # $messageFileName = $savefilename; 262 # 263 # if ($messageFileName =~ /^[~.]/ || $messageFileName =~ /\.\./) { 264 # $self->submission_error("For security reasons, you cannot specify a merge file from a directory higher than the email directory (you can't use ../blah/blah). Please specify a different file or move the needed file to the email directory"); 265 # } 266 # 267 # 268 # my $temp_body = $body; 269 # $temp_body =~ s/\r\n/\n/g; 270 # $temp_body = join("", 271 # "From: $from \nReply-To: $replyTo)\n" , 272 # "Subject: $subject\n" , 273 # "Message: \n $temp_body"); 274 # 275 # saveNewProblem($temp_body, $messageFileName); 276 277 #if Save As Default button was clicked 278 } elsif (( $r->param('action') eq 'save_as_default') && defined($r->param('body'))) { 279 280 # my $temp_body; 281 # $temp_body = $r->param('body'); 282 # $temp_body =~ s/\r\n/\n/g; 283 # 284 # #get default.msg and back it up in default.old.msg 285 # open DEFAULT, "$emailDirectory/$default_msg_file"; 286 # $temp_body = <DEFAULT>; 287 # close DEFAULT; 288 # 289 # if ( -e "$emailDirectory/$old_default_msg_file") { 290 # # saveProblem($temp_body, $old_default_msg_file); 291 # } else { 292 # # saveNewProblem($temp_body, $old_default_msg_file); 293 # } 294 # 295 # #save new default message as default.msg 296 # $temp_body = $body; 297 # $temp_body =~ s/\r\n/\n/g; 298 # $temp_body = join("", 299 # "From: $from \nReply-To: $replyTo)\n" , 300 # "Subject: $subject\n" , 301 # "Message: \n $temp_body"); 302 # 303 # # saveProblem($temp_body, $default_msg_file); 304 # $messageFileName = $default_msg_file; 305 306 #if Send Email button was clicked 307 } elsif ( $r->param('action') eq 'Send Email' ) { 308 309 my @studentID = (); 310 311 if ($r->param('To') eq 'classList' && defined($r->param('classList')) && $r->param('classList') ne 'None') { 312 # my $classlist = $r->param('classList'); 313 # my $classListFile = "$templateDirectory$classlist"; 314 # my @classList = (); 315 # #FIXME checkClasslistFile($Global::noOfFieldsInClasslist,$classListFile); 316 # open(FILE, "$classListFile") || die "can't open $classListFile"; 317 # @classList=<FILE>; 318 # close(FILE); 319 # 320 # foreach (@classList) { ## read through classlist and send e-mail 321 # ## message to all active students 322 # unless ($_ =~ /\S/) {next;} ## skip blank lines 323 # chomp; 324 # my @classListRecord=&getRecord($_); 325 # my ($studentID, $lastName, $firstName, $status, $comment, $section, $recitation, $email_address, $login_name) 326 # = @classListRecord; 327 # unless (&dropStatus($status)) { 328 # push (@studentID, $studentID); 329 # $fn{$studentID} = $firstName; 330 # $ln{$studentID} = $lastName; 331 # $section{$studentID} = $section; 332 # $recitation{$studentID} = $recitation; 333 # $status{$studentID} = $status; 334 # $email{$studentID} = $email_address; 335 # $login{$studentID} = $login_name; 336 # } 337 # } 338 } elsif ($r->param('To') eq 'studentID' && defined($r->param('studentID'))) { 339 @studentID = $r->param('studentID'); 340 my ($studentID, $login_name); 341 # 342 # foreach $studentID (@studentID) { 343 # $login_name = $studentID_LoginName_Hash{$studentID}; 344 # &attachCLRecord($login_name); 345 # $fn{$studentID} = CL_getStudentFirstName($login_name); 346 # $ln{$studentID} = CL_getStudentLastName($login_name); 347 # $section{$studentID} = CL_getClassSection($login_name); 348 # $recitation{$studentID} = CL_getClassRecitation($login_name); 349 # $status{$studentID} = CL_getStudentStatus($login_name); 350 # $email{$studentID} = CL_getStudentEmailAddress($login_name); 351 # $login{$studentID} = $login_name; 352 # } 353 354 } elsif ($r->param('To') eq 'all_students') { 355 @studentID = (); 356 my ($studentID, $login_name, $status); 357 358 # foreach $login_name (@availableStudents) { 359 # &attachCLRecord($login_name); 360 # $status = CL_getStudentStatus($login_name); 361 # next if &dropStatus($status); 362 # $studentID = CL_getStudentID($login_name); 363 # push(@studentID,$studentID); 364 # 365 # $fn{$studentID} = CL_getStudentFirstName($login_name); 366 # $ln{$studentID} = CL_getStudentLastName($login_name); 367 # $section{$studentID} = CL_getClassSection($login_name); 368 # $recitation{$studentID} = CL_getClassRecitation($login_name); 369 # $status{$studentID} = CL_getStudentStatus($login_name); 370 # $email{$studentID} = CL_getStudentEmailAddress($login_name); 371 # $login{$studentID} = $login_name; 372 # } 373 } else { 374 $self->submission_error('You didn\'t select any recipients. Make sure you select either all student in the course, individual students or a whole classlist.'); 375 } 376 377 my $mergeFile = ''; 378 379 #the radio button named 'merge' determines whether to take the selected mergefile 380 #or one that was typed in. A error message is given if select one and use the other 381 $mergeFile = $scoringDirectory . $r->param('mergeFiles') 382 if ($r->param('merge') eq 'mergeFiles' && defined($r->param('mergeFiles')) && $r->param('mergeFiles') ne 'None'); 383 384 $mergeFile = $templateDirectory . $r->param('mergeFile') 385 if ($r->param('merge') eq 'mergeFile' && defined($r->param('mergeFile')) && $r->param('mergeFile') !~ m|/$|); #does not end in a / 386 387 if ($mergeFile =~ /^[~.]/ || $mergeFile =~ /\.\./) { 388 $self->submission_error("For security reasons, you cannot specify a merge file from a directory higher than the email directory. Please specify a different file or move the needed file to the email directory"); 389 } 390 if ($r->param('body') =~ /(\$COL\[.*?\])/ && !(-e $mergeFile)) { 391 $self->submission_error("In order to use the \$COL[] you must specify a merge file. The file you specified does not exist. Also, make sure you selected the right checkbox."); 392 } 393 394 395 my %mergeAArray = (); 396 # unless ($mergeFile eq '') {%mergeAArray = &delim2aa($mergeFile);} 397 # 398 399 # 400 # foreach my $studentID (@studentID) { 401 # @COL =(); 402 # $SID = $studentID; 403 # $LN = defined $ln{$studentID} ? $ln{$studentID} :''; 404 # $FN = defined $fn{$studentID} ? $fn{$studentID} :''; 405 # $SECTION = defined $section{$studentID} ? $section{$studentID} :''; 406 # $RECITATION = defined $recitation{$studentID} ? $recitation{$studentID} :''; 407 # $EMAIL = defined $email{$studentID} ? $email{$studentID} :''; 408 # $STATUS =defined $status{$studentID} ? $status{$studentID} :''; 409 # $LOGIN = $login{$studentID}; 410 # 411 # next if ($LOGIN =~ /^$practiceUser/); ## skip practice users 412 # 413 # if ($timeout_attempts >= $max_timeout_attempts) { ## have attemped to connect to smtp server 414 # ## the max allowed times. Now just collect 415 # ## data on emails not sent and exit 416 # ++$emails_not_sent; 417 # &log_error(\@exceeded_max_timeout,$FN,$LN,$EMAIL); 418 # next; 419 # } 420 # 421 # unless ((defined $mergeAArray{$studentID}) or ($mergeFile eq '')) { 422 # if ($cgi->param('no_record')) { 423 # ++$emails_not_sent; 424 # &log_error(\@no_record,$FN,$LN,$EMAIL); 425 # next; 426 # } 427 # } 428 429 # my ($dbString, @dbArray); 430 # if (defined $mergeAArray{$SID}) { 431 # $dbString = $mergeAArray{$SID}; ## get sid record from merge file 432 # @dbArray = &getRecord($dbString); 433 # unshift(@dbArray,$SID); 434 # unshift(@dbArray,""); ## note COL[1] is the first column 435 # @COL= @dbArray; ## put merge fields in COL array 436 # $endCol = @COL; ## \endCol-1 gives last field, etc 437 # } 438 # my $smtp; 439 # if ($smtp = Net::SMTP->new($Global::smtpServer, Timeout => $timeout_sec)) {} else { 440 # # &internal_error("Couldn't contact SMTP server."); 441 # ++$emails_not_sent; 442 # &log_error(\@timeout_problem,$FN,$LN,$EMAIL); 443 # ++$timeout_attempts; 444 # next; 445 # } 446 # 447 # $smtp->mail($smtpSender); 448 # 449 # if ( $smtp->recipient($EMAIL)) { # this one's okay, keep going 450 # if ( $smtp->data("To: $EMAIL\n" . output() ) ) { 451 # ++$emails_sent; 452 # } else { 453 # ++$emails_not_sent; 454 # &log_error(\@unknown_problem,$FN,$LN,$EMAIL); 455 # next; 456 # } 457 # # &internal_error("Unknown problem sending message data to SMTP server."); 458 # } else { # we have a problem with this address 459 # $smtp->reset; 460 # #&internal_error("SMTP server doesn't like this address: <$EMAIL>."); 461 # ++$emails_not_sent; 462 # &log_error(\@bad_email_addresses,$FN,$LN,$EMAIL); 463 # } 464 # $smtp->quit; 465 # } 466 # &success; 467 } 468 469 470 471 472 } #end initialize 473 474 sub fieldEditHTML { 475 my ($self, $fieldName, $value, $properties) = @_; 476 my $size = $properties->{size}; 477 my $type = $properties->{type}; 478 my $access = $properties->{access}; 479 my $items = $properties->{items}; 480 my $synonyms = $properties->{synonyms}; 481 482 483 if ($access eq "readonly") { 484 return $value; 485 } 486 if ($type eq "number" or $type eq "text") { 487 return CGI::input({type=>"text", name=>$fieldName, value=>$value, size=>$size}); 488 } 489 if ($type eq "enumerable") { 490 my $matched = undef; # Whether a synonym match has occurred 491 492 # Process synonyms for enumerable objects 493 foreach my $synonym (keys %$synonyms) { 494 if ($synonym ne "*" and $value =~ m/$synonym/) { 495 $value = $synonyms->{$synonym}; 496 $matched = 1; 497 } 498 } 499 if (!$matched and exists $synonyms->{"*"}) { 500 $value = $synonyms->{"*"}; 501 } 502 return CGI::popup_menu({ 503 name => $fieldName, 504 values => [keys %$items], 505 default => $value, 506 labels => $items, 507 }); 508 } 509 } 510 511 sub title { 512 my $self = shift; 513 return 'Send mail to ' .$self->{ce}->{courseName}; 514 } 515 516 sub path { 517 my $self = shift; 518 my $args = $_[-1]; 519 520 my $ce = $self->{ce}; 521 my $root = $ce->{webworkURLs}->{root}; 522 my $courseName = $ce->{courseName}; 523 return $self->pathMacro($args, 524 "Home" => "$root", 525 $courseName => "$root/$courseName", 526 'instructor' => "$root/$courseName/instructor", 527 "Send Mail to: $courseName" => '', 528 ); 529 } 530 531 sub body { 532 my ($self, $setID) = @_; 533 my $r = $self->{r}; 534 my $authz = $self->{authz}; 535 my $user = $r->param('user'); 536 my $db = $self->{db}; 537 my $ce = $self->{ce}; 538 my $root = $ce->{webworkURLs}->{root}; 539 my $courseName = $ce->{courseName}; 540 541 return CGI::em("You are not authorized to access the Instructor tools.") unless $authz->hasPermissions($user, "access_instructor_tools"); 542 543 my $userTemplate = $db->newUser; 544 my $permissionLevelTemplate = $db->newPermissionLevel; 545 546 # This code will require changing if the permission and user tables ever have different keys. 547 my @users = $db->listUsers; 548 549 # This table can be consulted when display-ready forms of field names are needed. 550 # my %prettyFieldNames = map {$_ => $_} ($userTemplate->FIELDS(), $permissionLevelTemplate->FIELDS()); 551 # @prettyFieldNames{qw( 552 # user_id 553 # first_name 554 # last_name 555 # email_address 556 # student_id 557 # status 558 # section 559 # recitation 560 # comment 561 # permission 562 # )} = ( 563 # "User ID", 564 # "First Name", 565 # "Last Name", 566 # "E-mail", 567 # "Student ID", 568 # "Status", 569 # "Section", 570 # "Recitation", 571 # "Comment", 572 # "Perm. Level" 573 # ); 574 575 # my %fieldProperties = ( 576 # user_id => { 577 # type => "text", 578 # size => 8, 579 # access => "readonly", 580 # }, 581 # first_name => { 582 # type => "text", 583 # size => 10, 584 # access => "readwrite", 585 # }, 586 # last_name => { 587 # type => "text", 588 # size => 10, 589 # access => "readwrite", 590 # }, 591 # email_address => { 592 # type => "text", 593 # size => 20, 594 # access => "readwrite", 595 # }, 596 # student_id => { 597 # type => "text", 598 # size => 11, 599 # access => "readwrite", 600 # }, 601 # status => { 602 # type => "enumerable", 603 # size => 4, 604 # access => "readwrite", 605 # items => { 606 # "C" => "Enrolled", 607 # "D" => "Drop", 608 # "A" => "Audit", 609 # }, 610 # synonyms => { 611 # qr/^[ce]/i => "C", 612 # qr/^[dw]/i => "D", 613 # qr/^a/i => "A", 614 # "*" => "C", 615 # } 616 # }, 617 # section => { 618 # type => "text", 619 # size => 4, 620 # access => "readwrite", 621 # }, 622 # recitation => { 623 # type => "text", 624 # size => 4, 625 # access => "readwrite", 626 # }, 627 # comment => { 628 # type => "text", 629 # size => 20, 630 # access => "readwrite", 631 # }, 632 # permission => { 633 # type => "number", 634 # size => 2, 635 # access => "readwrite", 636 # } 637 # ); 638 639 640 641 ############################################################################################################## 642 643 # my ($ar_sortedNames, $hr_classlistLabels) = getClasslistFilesAndLabels($course); 644 # my @sortedNames = @$ar_sortedNames; 645 my %classlistLabels = ();# %$hr_classlistLabels; 646 unshift(@users, "Yourself"); 647 $classlistLabels{None} = 'Yourself'; 648 my $from = $self->{from}; 649 my $subject = $self->{subject}; 650 my $replyTo = $self->{replyTo}; 651 my $columns = $self->{columns}; 652 my $rows = $self->{rows}; 653 my $text = defined($self->{r_text}) ? ${ $self->{r_text} }: 'FIXME no text was produced by initialization!!'; 654 my $input_file = $self->{input_file}; 655 my $output_file = $self->{output_file}; 656 my @sorted_messages = $self->get_message_file_names; 657 my @sorted_merge_files = $self->get_merge_file_names; 658 my $merge_file = ( defined($self->{merge_file}) ) ? $self->{merge_file} : 'None'; 659 660 661 print CGI::start_form({method=>"post", action=>$r->uri()}); 662 #create list of sudents 663 # show professors's name and email address 664 # show replyTo field and From field 665 print CGI::start_table({-border=>'2', -cellpadding=>'4'}); 666 print CGI::Tr({-align=>'left',-valign=>'VCENTER'}, 667 CGI::td("Message file: $input_file","\n",CGI::br(), 668 CGI::submit(-name=>'action', -value=>'Open'), ' ',"\n", 669 #CGI::textfield(-name=>'openfilename', -size => 20, -value=> "$input_file", -override=>1), "\n",CGI::br(), 670 CGI::popup_menu(-name=>'openfilename', 671 -values=>\@sorted_messages, 672 -default=>$input_file 673 ), "\n",CGI::br(), 674 675 "Save file to: $output_file","\n",CGI::br(), 676 "\n", 'From:',' ', CGI::textfield(-name=>"from", -size=>30, -value=>$from, -override=>1), 677 "\n", CGI::br(),'Reply-To: ', CGI::textfield(-name=>"replyTo", -size=>30, -value=>$replyTo, -override=>1), 678 "\n", CGI::br(),'Subject: ', CGI::br(), CGI::textarea(-name=>'subject', -default=>$subject, -rows=>3,-columns=>40, -override=>1), 679 ), 680 CGI::td({-align=>'left'}, 681 CGI::radio_group(-name=>'radio', -values=>['all_students','studentID'], 682 -labels=>{all_students=>'All active students',studentID => 'Select recipients'}, 683 -default=>'studentID', 684 -linebreak=>1), 685 CGI::br(), 686 CGI::popup_menu(-name=>'classList', 687 -values=>\@users, 688 -labels=>\%classlistLabels, 689 -size => 10, 690 -multiple => 1, 691 -default=>'Yourself' 692 ), 693 694 695 ), 696 CGI::td({align=>'left'}, 697 CGI::submit(-name=>'action', -value=>'Choose merge file'), 698 CGI::popup_menu(-name=>'merge_file', 699 -values=>\@sorted_merge_files, 700 -default=>$merge_file, 701 ), "\n",CGI::br(), 702 CGI::submit(-name=>'preview', -value=>'preview',-label=>'Preview')," email to ", 703 CGI::popup_menu(-name=>'classList', 704 -values=>\@users, 705 -labels=>\%classlistLabels, 706 -default=>'Yourself' 707 ), 708 CGI::br(),CGI::br(), 709 CGI::submit(-name=>'action', -value=>'resize', -label=>'Resize message window'),CGI::br(), 710 " Rows: ", CGI::textfield(-name=>'rows', -size=>3, -value=>$rows), 711 " Columns: ", CGI::textfield(-name=>'columns', -size=>3, -value=>$columns), 712 CGI::br(),CGI::br(), 713 #show available macros 714 CGI::popup_menu( 715 -name=>'dummyName', 716 -values=>['', '$SID', '$FN', '$LN', '$SECTION', '$RECITATION','$STATUS', '$EMAIL', '$LOGIN', '$COL[3]', '$COL[-1]'], 717 -labels=>{''=>'list of insertable macros', 718 '$SID'=>'$SID - Student ID', 719 '$FN'=>'$FN - First name', 720 '$LN'=>'$LN - Last name', 721 '$SECTION'=>'$SECTION - Student\'s Section', 722 '$RECITATION'=>'$RECITATION', 723 '$STATUS'=>'$STATUS - C, Audit, Drop, etc.', 724 '$EMAIL'=>'$EMAIL - Email address', 725 '$LOGIN'=>'$LOGIN - Login', 726 '$COL[3]'=>'$COL[3] - 3rd column in merge file', 727 '$COL[-1]'=>'$COL[-1] - Last column' 728 } 729 ), "\n", 730 ), 731 732 ); # end Tr 733 print CGI::end_table(); 734 #create a textbox with the subject and a textarea with the message 735 736 #print actual body of message 737 738 print "\n", CGI::p( $self->{message}) if defined($self->{message}); 739 print "\n", CGI::p( CGI::textarea(-name=>'body', -default=>$text, -rows=>$rows, -columns=>$columns, -override=>1)); 740 741 #create all necessary action buttons 742 print CGI::table( { -border=>2,-cellpadding=>4}, 743 CGI::Tr( 744 CGI::td( CGI::submit(-name=>'action', -value=>'Send Email') ), "\n", 745 CGI::td(CGI::submit(-name=>'action', -value=>'Save')," to $output_file"), " \n", 746 CGI::td(CGI::submit(-name=>'action', -value=>'Save as:'), 747 CGI::textfield(-name=>'savefilename', -size => 20, -value=> "$output_file", -override=>1) 748 ), "\n", 749 CGI::td(CGI::submit(-name=>'action', -value=>'Save as Default')), 750 ) 751 ); 752 753 ############################################################################################################## 754 755 print $self->hidden_authen_fields(); 756 # print CGI::submit({name=>"save_classlist", value=>"Save Changes to Users"}); 757 print CGI::end_form(); 758 return ""; 759 } 760 761 ############################################################################## 762 # Utility methods 763 ############################################################################## 764 sub submission_error { 765 my $self = shift; 766 my $msg = join( " ", @_); 767 $self->{submitError}= $msg; #CGI::b(HTML::Entities::encode($msg)); 768 # qq{Please hit the "<B>Back</B>" button on your browser to 769 # try again, or notify your web master 770 # if you believe this message is in error. 771 # }; 772 return; 773 } 774 775 sub saveProblem { 776 my $self = shift; 777 my ($body, $probFileName)= @_; 778 local(*PROBLEM); 779 open (PROBLEM, ">$probFileName") || 780 $self->submission_error("Could not open $probFileName for writing. 781 Check that the permissions for this problem are 660 (-rw-rw----)"); 782 print PROBLEM $body; 783 close PROBLEM; 784 chmod 0660, "$probFileName" || 785 $self->submission_error(" 786 CAN'T CHANGE PERMISSIONS ON FILE $probFileName"); 787 } 788 789 sub read_input_file { 790 my $self = shift; 791 my $filePath = shift; 792 my ($text, @text); 793 my $header = ''; 794 my ($subject, $from, $replyTo); 795 local(*FILE); 796 if (-e "$filePath" and -r "$filePath") { 797 open FILE, "$filePath" || do { $self->submission_error("Can't open $filePath"); return}; 798 while ($header !~ s/Message:\s*$//m and not eof(FILE)) { 799 $header .= <FILE>; 800 } 801 $text = join( '', <FILE>); 802 $text =~ s/^\s*//; # remove initial white space if any. 803 $header =~ /^From:\s(.*)$/m; 804 $from = $1 or $from = $self->{defaultFrom}; 805 806 $header =~ /^Reply-To:\s(.*)$/m; 807 $replyTo = $1 or $replyTo = $self->{defaultReply}; 808 809 $header =~ /^Subject:\s(.*)$/m; 810 $subject = $1; 811 812 } else { 813 $from = $self->{defaultFrom}; 814 $replyTo = $self->{defaultReply}; 815 $text = (-e "$filePath") ? "FIXME file $filePath can't be read" :"FIXME file $filePath doesn't exist"; 816 $subject = "FIXME default subject"; 817 } 818 return ($from, $replyTo, $subject, \$text); 819 } 820 821 sub get_message_file_names { 822 my $self = shift; 823 my $emailDirectory = $self->{ce}->{courseDirs}->{email}; 824 #get all message files and create a list 825 local(*EMAILDIR); 826 opendir( EMAILDIR, $emailDirectory )|| die "Can't access directory $emailDirectory. Please check that webserver has permission to read this directory."; 827 my @messageFiles = grep /\.msg$/, readdir EMAILDIR; #all message files 828 closedir EMAILDIR; 829 830 return sort @messageFiles; 831 } 832 sub get_merge_file_names { 833 my $self = shift; 834 my $scoringDirectory = $self->{ce}->{courseDirs}->{scoring}; 835 #get all message files and create a list 836 local(*SCORINGDIR); 837 opendir( SCORINGDIR, $scoringDirectory )|| die "Can't access directory $scoringDirectory.", 838 "Please check that webserver has permission to read this directory."; 839 my @mergeFiles = grep( /\.csv$/, readdir SCORINGDIR); #all message files 840 closedir SCORINGDIR; 841 @mergeFiles = sort @mergeFiles; 842 # warn "FIXME scoring directory $scoringDirectory merge Files", join(" ", @mergeFiles); 843 unshift(@mergeFiles, 'None'); 844 return @mergeFiles; 845 } 846 1;
| aubreyja at gmail dot com | ViewVC Help |
| Powered by ViewVC 1.0.9 |