[system] / branches / rel-2-3-dev / webwork2 / lib / WeBWorK / ContentGenerator / Instructor / SendMail.pm Repository:
ViewVC logotype

Diff of /branches/rel-2-3-dev/webwork2/lib/WeBWorK/ContentGenerator/Instructor/SendMail.pm

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

Revision 2319 Revision 2320
1################################################################################ 1################################################################################
2# WeBWorK Online Homework Delivery System 2# WeBWorK Online Homework Delivery System
3# Copyright © 2000-2003 The WeBWorK Project, http://openwebwork.sf.net/ 3# Copyright © 2000-2003 The WeBWorK Project, http://openwebwork.sf.net/
4# $CVSHeader: webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor/SendMail.pm,v 1.32 2004/05/24 15:32:11 mschmitt Exp $ 4# $CVSHeader: webwork-modperl/lib/WeBWorK/ContentGenerator/Instructor/SendMail.pm,v 1.33 2004/05/24 18:05:26 mschmitt Exp $
5# 5#
6# This program is free software; you can redistribute it and/or modify it under 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 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 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. 9# version, or (b) the "Artistic License" which comes with this package.
42 42
43 my @selected_filters; 43 my @selected_filters;
44 if (defined ($r->param('classList!filter'))){ @selected_filters = $r->param('classList!filter');} 44 if (defined ($r->param('classList!filter'))){ @selected_filters = $r->param('classList!filter');}
45 else {@selected_filters = ("all");} 45 else {@selected_filters = ("all");}
46 46
47
48 # Check permissions
49 return unless $authz->hasPermissions($user, "access_instructor_tools");
47 unless ($authz->hasPermissions($user, "send_mail")) { 50 return unless $authz->hasPermissions($user, "send_mail");
48 $self->addmessage(CGI::div({class=>"ResultsWithError"}, CGI::p("You are not authorized to send mail to students."))); 51
49 return;
50 }
51############################################################################################# 52#############################################################################################
52# gather directory data 53# gather directory data
53############################################################################################# 54#############################################################################################
54 my $emailDirectory = $ce->{courseDirs}->{email}; 55 my $emailDirectory = $ce->{courseDirs}->{email};
55 my $scoringDirectory = $ce->{courseDirs}->{scoring}; 56 my $scoringDirectory = $ce->{courseDirs}->{scoring};
172 if ( defined($openfilename) ) { 173 if ( defined($openfilename) ) {
173 if ( -e "${emailDirectory}/$openfilename") { 174 if ( -e "${emailDirectory}/$openfilename") {
174 if ( -R "${emailDirectory}/$openfilename") { 175 if ( -R "${emailDirectory}/$openfilename") {
175 $input_file = $openfilename; 176 $input_file = $openfilename;
176 } else { 177 } else {
177 $self->addmessage(CGI::div({class=>"ResultsWithError"}, CGI::p(join("", 178 $self->addbadmessage(CGI::p(join("",
178 "The file ${emailDirectory}/$openfilename is not readable by the webserver.",CGI::br(), 179 "The file ${emailDirectory}/$openfilename is not readable by the webserver.",CGI::br(),
179 "Check that it's permissions are set correctly.", 180 "Check that it's permissions are set correctly.",
180 )))); 181 )));
181 } 182 }
182 } else { 183 } else {
183 $input_file = $default_msg_file; 184 $input_file = $default_msg_file;
184 $self->addmessage(CGI::div({class=>"ResultsWithError"}, CGI::p(join("", 185 $self->addbadmessage(CGI::p(join("",
185 "The file ${emailDirectory}/$openfilename cannot be found.",CGI::br(), 186 "The file ${emailDirectory}/$openfilename cannot be found.",CGI::br(),
186 "Check whether it exists and whether the directory $emailDirectory can be read by the webserver.",CGI::br(), 187 "Check whether it exists and whether the directory $emailDirectory can be read by the webserver.",CGI::br(),
187 "Using contents of the default message $default_msg_file instead.", 188 "Using contents of the default message $default_msg_file instead.",
188 )))); 189 )));
189 } 190 }
190 } else { 191 } else {
191 $input_file = $default_msg_file; 192 $input_file = $default_msg_file;
192 } 193 }
193 $self->{input_file} =$input_file; 194 $self->{input_file} =$input_file;
200 $output_file = $default_msg_file; 201 $output_file = $default_msg_file;
201 } elsif ( defined($action) and ($action =~/save/i)) { 202 } elsif ( defined($action) and ($action =~/save/i)) {
202 if (defined($savefilename) and $savefilename ) { 203 if (defined($savefilename) and $savefilename ) {
203 $output_file = $savefilename; 204 $output_file = $savefilename;
204 } else { 205 } else {
205 $self->addmessage(CGI::div({class=>"ResultsWithError"}, CGI::p("No filename was specified for saving! The message was not saved."))); 206 $self->addbadmessage(CGI::p("No filename was specified for saving! The message was not saved."));
206 } 207 }
207 } elsif ( defined($input_file) ) { 208 } elsif ( defined($input_file) ) {
208 $output_file = $input_file; 209 $output_file = $input_file;
209 } 210 }
210 211
211 ################################################################# 212 #################################################################
212 # Sanity check on save file name 213 # Sanity check on save file name
213 ################################################################# 214 #################################################################
214 215
215 if ($output_file =~ /^[~.]/ || $output_file =~ /\.\./) { 216 if ($output_file =~ /^[~.]/ || $output_file =~ /\.\./) {
216 $self->addmessage(CGI::div({class=>"ResultsWithError"},
217 CGI::p("For security reasons, you cannot specify a message file from a directory", 217 $self->addbadmessage(CGI::p("For security reasons, you cannot specify a message file from a directory",
218 "higher than the email directory (you can't use ../blah/blah for example). ", 218 "higher than the email directory (you can't use ../blah/blah for example). ",
219 "Please specify a different file or move the needed file to the email directory",))); 219 "Please specify a different file or move the needed file to the email directory",));
220 } 220 }
221 unless ($output_file =~ m|\.msg$| ) { 221 unless ($output_file =~ m|\.msg$| ) {
222 $self->addmessage(CGI::div({class=>"ResultsWithError"}, 222 $self->addbadmessage(CGI::p("Invalid file name.",
223 CGI::p("Invalid file name.",
224 "The file name \"$output_file\" does not have a \".msg\" extension", 223 "The file name \"$output_file\" does not have a \".msg\" extension",
225 "All email file names must end in the extension \".msg\"", 224 "All email file names must end in the extension \".msg\"",
226 "choose a file name with a \".msg\" extension.", 225 "choose a file name with a \".msg\" extension.",
227 "The message was not saved.",))); 226 "The message was not saved.",));
228 } 227 }
229 228
230 $self->{output_file} = $output_file; # this is ok. It will be put back in the text input box for re-editing. 229 $self->{output_file} = $output_file; # this is ok. It will be put back in the text input box for re-editing.
231 230
232 231
255 $from = $r->param('from'); 254 $from = $r->param('from');
256 $replyTo = $r->param('replyTo'); 255 $replyTo = $r->param('replyTo');
257 $subject = $r->param('subject'); 256 $subject = $r->param('subject');
258 my $body = $r->param('body'); 257 my $body = $r->param('body');
259 # Sanity check: body must contain non-white space 258 # Sanity check: body must contain non-white space
260 $self->addmessage(CGI::div({class=>"ResultsWithError"}, CGI::p('You didn\'t enter any message.'))) unless ($r->param('body') =~ /\S/); 259 $self->addbadmessage(CGI::p('You didn\'t enter any message.')) unless ($r->param('body') =~ /\S/);
261 $r_text = \$body; 260 $r_text = \$body;
262 261
263 } 262 }
264 # store data 263 # store data
265 $self->{from} = $from; 264 $self->{from} = $from;
331# warn "FIXME from $from | subject $subject |reply $replyTo|msg $temp_body"; 330# warn "FIXME from $from | subject $subject |reply $replyTo|msg $temp_body";
332 ################################################################# 331 #################################################################
333 # overwrite protection 332 # overwrite protection
334 ################################################################# 333 #################################################################
335 if ($action eq 'Save as:' and -e "$emailDirectory/$output_file") { 334 if ($action eq 'Save as:' and -e "$emailDirectory/$output_file") {
336 $self->addmessage(CGI::div({class=>"ResultsWithError"},
337 CGI::p("The file $emailDirectory/$output_file already exists and cannot be overwritten", 335 $self->addbadmessage(CGI::p("The file $emailDirectory/$output_file already exists and cannot be overwritten",
338 "The message was not saved"))); 336 "The message was not saved"));
339 return; 337 return;
340 } 338 }
341 339
342 ################################################################# 340 #################################################################
343 # Back up existing file? 341 # Back up existing file?
344 ################################################################# 342 #################################################################
345 if ($action eq 'Save as Default' and -e "$emailDirectory/$default_msg_file") { 343 if ($action eq 'Save as Default' and -e "$emailDirectory/$default_msg_file") {
346 rename("$emailDirectory/$default_msg_file","$emailDirectory/$old_default_msg_file") or 344 rename("$emailDirectory/$default_msg_file","$emailDirectory/$old_default_msg_file") or
347 die "Can't rename $emailDirectory/$default_msg_file to $emailDirectory/$old_default_msg_file ", 345 die "Can't rename $emailDirectory/$default_msg_file to $emailDirectory/$old_default_msg_file ",
348 "Check permissions for webserver on directory $emailDirectory. $!"; 346 "Check permissions for webserver on directory $emailDirectory. $!";
349 $self->addmessage(CGI::div({class=>"ResultsWithoutError"}, CGI::p("Backup file <code>$emailDirectory/$old_default_msg_file</code> created.".CGI::br()))); 347 $self->addgoodmessage(CGI::p("Backup file <code>$emailDirectory/$old_default_msg_file</code> created." . CGI::br()));
350 } 348 }
351 ################################################################# 349 #################################################################
352 # Save the message 350 # Save the message
353 ################################################################# 351 #################################################################
354 $self->saveProblem($temp_body, "${emailDirectory}/$output_file" ) unless ($output_file =~ /^[~.]/ || $output_file =~ /\.\./ || not $output_file =~ m|\.msg$|); 352 $self->saveProblem($temp_body, "${emailDirectory}/$output_file" ) unless ($output_file =~ /^[~.]/ || $output_file =~ /\.\./ || not $output_file =~ m|\.msg$|);
355 unless ( $self->{submit_message} or not -w "${emailDirectory}/$output_file" ) { # if there are no errors report success 353 unless ( $self->{submit_message} or not -w "${emailDirectory}/$output_file" ) { # if there are no errors report success
356 $self->addmessage(CGI::div({class=>"ResultsWithoutError"}, CGI::p("Message saved to file <code>${emailDirectory}/$output_file</code>."))); 354 $self->addgoodmessage(CGI::p("Message saved to file <code>${emailDirectory}/$output_file</code>."));
357 } 355 }
358 356
359 } elsif ($action eq 'Preview message') { 357 } elsif ($action eq 'Preview message') {
360 $self->{response} = 'preview'; 358 $self->{response} = 'preview';
361 359
362 } elsif ($action eq 'Send Email') { 360 } elsif ($action eq 'Send Email') {
363 $self->{response} = 'send_email'; 361 $self->{response} = 'send_email';
364 362
365 my @recipients = @{$self->{ra_send_to}}; 363 my @recipients = @{$self->{ra_send_to}};
366 $self->addmessage(CGI::div({class=>"ResultsWithError"},
367 CGI::p("No recipients selected "))) unless @recipients; 364 $self->addbadmessage(CGI::p("No recipients selected ")) unless @recipients;
368 # get merge file 365 # get merge file
369 my $merge_file = ( defined($self->{merge_file}) ) ? $self->{merge_file} : 'None'; 366 my $merge_file = ( defined($self->{merge_file}) ) ? $self->{merge_file} : 'None';
370 my $delimiter = ','; 367 my $delimiter = ',';
371 my $rh_merge_data = $self->read_scoring_file("$merge_file", "$delimiter"); 368 my $rh_merge_data = $self->read_scoring_file("$merge_file", "$delimiter");
372 unless (ref($rh_merge_data) ) { 369 unless (ref($rh_merge_data) ) {
373 $self->addmessage(CGI::div({class=>"ResultsWithError"}, CGI::p("No merge data file"))); 370 $self->addbadmessage(CGI::p("No merge data file"));
374 $self->addmessage(CGI::div({class=>"ResultsWithError"}, CGI::p("Can't read merge file $merge_file. No message sent"))); 371 $self->addbadmessage(CGI::p("Can't read merge file $merge_file. No message sent"));
375 return; 372 return;
376 } ; 373 } ;
377 374
378 375
379 foreach my $recipient (@recipients) { 376 foreach my $recipient (@recipients) {
380 #warn "FIXME sending email to $recipient"; 377 #warn "FIXME sending email to $recipient";
381 my $ur = $self->{db}->getUser($recipient); #checked 378 my $ur = $self->{db}->getUser($recipient); #checked
382 die "record for user $recipient not found" unless $ur; 379 die "record for user $recipient not found" unless $ur;
383 unless ($ur->email_address) { 380 unless ($ur->email_address) {
384 $self->addmessage(CGI::div({class=>"ResultsWithError"},
385 CGI::p("user $recipient does not have an email address -- skipping"))); 381 $self->addbadmessage(CGI::p("user $recipient does not have an email address -- skipping"));
386 next; 382 next;
387 } 383 }
388 my ($msg, $preview_header); 384 my ($msg, $preview_header);
389 eval{ ($msg,$preview_header) = $self->process_message($ur,$rh_merge_data); }; 385 eval{ ($msg,$preview_header) = $self->process_message($ur,$rh_merge_data); };
390 $self->addmessage(CGI::div({class=>"ResultsWithError"}, CGI::p("There were errors in processing user $ur, merge file $merge_file. $@"))) if $@; 386 $self->addbadmessage(CGI::p("There were errors in processing user $ur, merge file $merge_file. $@")) if $@;
391 my $mailer = Mail::Sender->new({ 387 my $mailer = Mail::Sender->new({
392 from => $from, 388 from => $from,
393 to => $ur->email_address, 389 to => $ur->email_address,
394 smtp => $ce->{mail}->{smtpServer}, 390 smtp => $ce->{mail}->{smtpServer},
395 subject => $subject, 391 subject => $subject,
396 headers => "X-Remote-Host: ".$r->get_remote_host(), 392 headers => "X-Remote-Host: ".$r->get_remote_host(),
397 }); 393 });
398 unless (ref $mailer) { 394 unless (ref $mailer) {
399 $self->addmessage(CGI::div({class=>"ResultsWithError"}, CGI::p("Failed to create a mailer for user $recipient: $Mail::Sender::Error"))); 395 $self->addbadmessage(CGI::p("Failed to create a mailer for user $recipient: $Mail::Sender::Error"));
400 next; 396 next;
401 } 397 }
402 unless (ref $mailer->Open()) { 398 unless (ref $mailer->Open()) {
403 $self->addmessage(CGI::div({class=>"ResultsWithError"}, CGI::p("Failed to open the mailer for user $recipient: $Mail::Sender::Error"))); 399 $self->addbadmessage(CGI::p("Failed to open the mailer for user $recipient: $Mail::Sender::Error"));
404 next; 400 next;
405 } 401 }
406 my $MAIL = $mailer->GetHandle() or $self->addmessage(CGI::div({class=>"ResultsWithError"}, CGI::p("Couldn't get handle"))); 402 my $MAIL = $mailer->GetHandle() or $self->addbadmessage(CGI::p("Couldn't get handle"));
407 print $MAIL $msg || $self->addmessage(CGI::div({class=>"ResultsWithError"}, CGI::p("Couldn't print to $MAIL"))); 403 print $MAIL $msg || $self->addbadmessage(CGI::p("Couldn't print to $MAIL"));
408 close $MAIL || $self->addmessage(CGI::div({class=>"ResultsWithError"}, CGI::p("Couldn't close $MAIL"))); 404 close $MAIL || $self->addbadmessage(CGI::p("Couldn't close $MAIL"));
409 #warn "FIXME mailed to ", $ur->email_address, "from $from subject $subject"; 405 #warn "FIXME mailed to ", $ur->email_address, "from $from subject $subject";
410 406
411 } 407 }
412 408
413 } else { 409 } else {
414 $self->addmessage(CGI::div({class=>"ResultsWithError"}, CGI::p("Didn't recognize button $action"))); 410 $self->addbadmessage(CGI::p("Didn't recognize button $action"));
415 } 411 }
416 412
417 413
418 414
419} #end initialize 415} #end initialize
424 420
425sub body { 421sub body {
426 my ($self) = @_; 422 my ($self) = @_;
427 my $r = $self->r; 423 my $r = $self->r;
428 my $urlpath = $r->urlpath; 424 my $urlpath = $r->urlpath;
425 my $authz = $r->authz;
429 my $setID = $urlpath->arg("setID"); 426 my $setID = $urlpath->arg("setID");
430 my $response = (defined($self->{response}))? $self->{response} : ''; 427 my $response = (defined($self->{response}))? $self->{response} : '';
428 my $user = $r->param('user');
429
430 # Check permissions
431 return CGI::div({class=>"ResultsWithError"}, CGI::p("You are not authorized to access instructor tools"))
432 unless $authz->hasPermissions($user, "access_instructor_tools");
433
434 return CGI::div({class=>"ResultsWithError"}, CGI::p("You are not authorized to send mail to students"))
435 unless $authz->hasPermissions($user, "send_mail");
436
431 if ($response eq 'preview') { 437 if ($response eq 'preview') {
432 $self->print_preview($setID); 438 $self->print_preview($setID);
433 } elsif (($response eq 'send_email')){ 439 } elsif (($response eq 'send_email')){
434 $self->addmessage(CGI::div({class=>"ResultsWithoutError"}, CGI::p("Email sent to ". scalar(@{$self->{ra_send_to}})." students."))); 440 $self->addgoodmessage(CGI::p("Email sent to ". scalar(@{$self->{ra_send_to}})." students."));
435 $self->{message} .= CGI::i("Email sent to ". scalar(@{$self->{ra_send_to}})." students."); 441 $self->{message} .= CGI::i("Email sent to ". scalar(@{$self->{ra_send_to}})." students.");
436 $self->print_form($setID); 442 $self->print_form($setID);
437 } else { 443 } else {
438 $self->print_form($setID); 444 $self->print_form($setID);
439 } 445 }
716sub saveProblem { 722sub saveProblem {
717 my $self = shift; 723 my $self = shift;
718 my ($body, $probFileName)= @_; 724 my ($body, $probFileName)= @_;
719 local(*PROBLEM); 725 local(*PROBLEM);
720 open (PROBLEM, ">$probFileName") || 726 open (PROBLEM, ">$probFileName") ||
721 $self->addmessage(CGI::div({class=>"ResultsWithError"},
722 CGI::p("Could not open $probFileName for writing. 727 $self->addbadmessage(CGI::p("Could not open $probFileName for writing.
723 Check that the permissions for this problem are 660 (-rw-rw----)"))); 728 Check that the permissions for this problem are 660 (-rw-rw----)"));
724 print PROBLEM $body if -w $probFileName; 729 print PROBLEM $body if -w $probFileName;
725 close PROBLEM; 730 close PROBLEM;
726 chmod 0660, "$probFileName" || 731 chmod 0660, "$probFileName" ||
727 $self->addmessage(CGI::div({class=>"ResultsWithError"},
728 CGI::p("
729 CAN'T CHANGE PERMISSIONS ON FILE $probFileName"))); 732 $self->addbadmessage(CGI::p("CAN'T CHANGE PERMISSIONS ON FILE $probFileName"));
730} 733}
731 734
732sub read_input_file { 735sub read_input_file {
733 my $self = shift; 736 my $self = shift;
734 my $filePath = shift; 737 my $filePath = shift;
735 my ($text, @text); 738 my ($text, @text);
736 my $header = ''; 739 my $header = '';
737 my ($subject, $from, $replyTo); 740 my ($subject, $from, $replyTo);
738 local(*FILE); 741 local(*FILE);
739 if (-e "$filePath" and -r "$filePath") { 742 if (-e "$filePath" and -r "$filePath") {
740 open FILE, "$filePath" || do { $self->addmessage(CGI::div({class=>"ResultsWithError"}, CGI::p("Can't open $filePath"))); return}; 743 open FILE, "$filePath" || do { $self->addbadmessage(CGI::p("Can't open $filePath")); return};
741 while ($header !~ s/Message:\s*$//m and not eof(FILE)) { 744 while ($header !~ s/Message:\s*$//m and not eof(FILE)) {
742 $header .= <FILE>; 745 $header .= <FILE>;
743 } 746 }
744 $text = join( '', <FILE>); 747 $text = join( '', <FILE>);
745 $text =~ s/^\s*//; # remove initial white space if any. 748 $text =~ s/^\s*//; # remove initial white space if any.
811 814
812 # get record from merge file 815 # get record from merge file
813 # FIXME this is inefficient. The info should be cached 816 # FIXME this is inefficient. The info should be cached
814 my @COL = defined($rh_merge_data->{$SID}) ? @{$rh_merge_data->{$SID} } : (); 817 my @COL = defined($rh_merge_data->{$SID}) ? @{$rh_merge_data->{$SID} } : ();
815 if ($merge_file ne 'None' && not defined($rh_merge_data->{$SID}) ) { 818 if ($merge_file ne 'None' && not defined($rh_merge_data->{$SID}) ) {
816 $self->addmessage(CGI::div({class=>"ResultsWithError"}, CGI::p("No merge data for student id:$SID; name:$FN $LN; login:$LOGIN"))); 819 $self->addbadmessage(CGI::p("No merge data for student id:$SID; name:$FN $LN; login:$LOGIN"));
817 } 820 }
818 821
819 my $endCol = @COL; 822 my $endCol = @COL;
820 # for safety, only evaluate special variables 823 # for safety, only evaluate special variables
821 my $msg = $text; 824 my $msg = $text;

Legend:
Removed from v.2319  
changed lines
  Added in v.2320

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9