[system] / trunk / webwork / system / cgi / cgi-scripts / profSendMail.pl Repository:
ViewVC logotype

View of /trunk/webwork/system/cgi/cgi-scripts/profSendMail.pl

Parent Directory Parent Directory | Revision Log Revision Log


Revision 215 - (download) (as text) (annotate)
Fri Sep 21 12:54:46 2001 UTC (11 years, 9 months ago) by apizer
File size: 28955 byte(s)
profSendMail now always ends with a message listing all email that was
not sent and the reason. It will no longer just die with an internal error message.

    1 #!/usr/local/bin/webwork-perl
    2 
    3 ## This file is profSendMail.pl
    4 ## It provides a utility for professors to send mail to one or more students
    5 ## using individualized emails or mass emails
    6 
    7 use lib '.'; use webworkInit; # WeBWorKInitLine
    8 
    9 use Global;
   10 use CGI qw(:standard);
   11 use Auth;
   12 use Net::SMTP;
   13 use HTML::Entities;
   14 use strict;
   15 
   16 #begin Timing code
   17 use Benchmark;
   18 my $beginTime = new Benchmark;
   19 #end Timing code
   20 
   21 my $cgi = new CGI;
   22 my %inputs = $cgi->Vars();
   23 
   24 #for use in strings where $cgi->param is not interpolated correctly or at all
   25 my $course = $cgi->param('course');
   26 my $user = $cgi->param('user');
   27 my $session_key = $cgi->param('key');
   28 my $openfilename = $cgi->param('openfilename');
   29 
   30 &Global::getCourseEnvironment($course);
   31 
   32 my $scriptDirectory     = $Global::scriptDirectory;
   33 my $databaseDirectory   = $Global::databaseDirectory;
   34 my $htmlURL         = $Global::htmlURL;
   35 my $cgiURL          = $Global::cgiWebworkURL;
   36 my $courseScriptsDirectory  = $Global::courseScriptsDirectory;
   37 my $templateDirectory   = getCourseTemplateDirectory;
   38 my $emailDirectory      = getCourseEmailDirectory;
   39 my $scoringDirectory    = getCourseScoringDirectory;
   40 my $feedbackAddress     = $Global::feedbackAddress;
   41 my $defaultFrom       = $Global::defaultFrom;
   42 my $defaultReply      = $Global::defaultReply;
   43 my $smtpSender        = $Global::smtpSender;
   44 my $defaultClasslistFile  = getCourseClasslistFile($course);
   45 my $default_msg       = 'default.msg';
   46 my $old_default_msg     = 'default_old.msg';
   47 my $practiceUser      = $Global::practiceUser;
   48 
   49 require "${scriptDirectory}$Global::classlist_DBglue_pl";
   50 require "${scriptDirectory}$Global::HTMLglue_pl";
   51 require "${scriptDirectory}$Global::FILE_pl";
   52 
   53 # log access
   54 &Global::log_info('', query_string);
   55 
   56 my $permissionsFile = &Global::getCoursePermissionsFile($course);
   57 my $permissions = &get_permissions($user, $permissionsFile);
   58 my $keyFile = &Global::getCourseKeyFile($course);
   59 
   60 
   61 #verify session key
   62 &verify_key($user, $session_key, "$keyFile", $course);
   63 
   64 #verify permissions are correct
   65 if (($permissions != $Global::instructor_permissions) and ($permissions != $Global::TA_permissions) ) {
   66   print "permissions = $permissions instructor_permissions = $Global::instructor_permissions\n";
   67   print &html_NO_PERMISSION;
   68   exit(0);
   69   }
   70 
   71 #user macros that can be used in the email message
   72 my $SID = '';
   73 my $FN = '';
   74 my $LN = '';
   75 my $SECTION = '';
   76 my $RECITATION = '';
   77 my $STATUS = '';
   78 my $EMAIL = '';
   79 my $LOGIN = '';
   80 my @COL = ();
   81 
   82 my $endCol;
   83 
   84 #hashes to hold student info
   85 my %fn = ();
   86 my %ln = ();
   87 my %section = ();
   88 my %recitation = ();
   89 my %status = ();
   90 my %email = ();
   91 my %login = ();
   92 
   93 #timeout parameters
   94 my $timeout_sec = 15;
   95 my $max_timeout_attempts = 3;
   96 my $timeout_attempts = 0;
   97 
   98 
   99 #keep track of email sent and not sent
  100 my $emails_sent = 0;
  101 my $emails_not_sent = 0;
  102 
  103 #array for bad email addresses
  104 my @bad_email_addresses = ();
  105 my @unknown_problem = ();
  106 my @timeout_problem = ();
  107 my @exceeded_max_timeout = ();
  108 my @no_record = ();
  109 
  110 # get format information
  111 
  112 my $format = (defined($cgi->param('format'))) ? $cgi->param('format') : 'alph';
  113 
  114 #get information from the classlist data base
  115 my $availableStudents_ref;
  116 if ((defined $format) and ($format eq 'section')) {
  117     $availableStudents_ref = getAllLoginNamesSortedBySectionThenByName();
  118 }
  119 elsif ((defined $format) and ($format eq 'recitation')) {
  120     $availableStudents_ref = getAllLoginNamesSortedByRecitationThenByName();
  121 }
  122 else {
  123     $availableStudents_ref = getAllLoginNamesSortedByName();
  124 }
  125 
  126 my @availableStudents = @$availableStudents_ref;
  127 
  128 #my %loginName_StudentID_Hash   = %{getLoginName_StudentID_Hash()};
  129 my %studentID_LoginName_Hash  = %{getStudentID_LoginName_Hash()};
  130 
  131 
  132 
  133 #make sure message file was submitted and exists
  134   my $messageFileName;
  135   if (defined($openfilename) && -e "${emailDirectory}$openfilename") {
  136     if ( -R "${emailDirectory}$openfilename") {
  137       $messageFileName = $openfilename;
  138     } else {
  139       wwerror ('File is not readable', "The file
  140 ${emailDirectory}$openfilename
  141 is not readable by the webserver. Check that it's permissions are set correctly.");
  142     }
  143   } else {
  144     $messageFileName = $default_msg;
  145   }
  146 
  147 
  148 #get row and column info if submitted
  149   my $rows = (defined($cgi->param('rows'))) ? $cgi->param('rows') : $Global::editor_window_rows;
  150   my $columns = (defined($cgi->param('columns'))) ? $cgi->param('columns') : $Global::editor_window_columns;
  151 
  152 #Deal with filled out forms and various actions resulting from different buttons
  153   if ( defined($cgi->param('action')) ) {
  154     if (defined($cgi->param('savefilename'))) {
  155       &user_error("For security reasons, you cannot save a message in any directory higher than the email directory.  Please specify a   file name to save under.") if ($cgi->param('savefilename') =~ /^[~.]/ || $cgi->param('savefilename') =~ /\.\./);
  156     }
  157 
  158     #if Save button was clicked
  159     if (( $cgi->param('action') eq 'Save') && defined($cgi->param('body')) && defined($cgi->param('savefilename'))) {
  160 
  161       my $temp_body = $cgi->param('body');
  162       $temp_body =~ s/\r\n/\n/g;
  163       $temp_body = "From: " . $cgi->param('from') . "\n" .
  164              "Reply-To: " . $cgi->param('replyTo') . "\n" .
  165              "Subject: " . $cgi->param('subject') . "\n" .
  166              "Message: \n" . $temp_body;
  167 
  168       saveProblem($temp_body, $cgi->param('savefilename'));
  169       $messageFileName = $cgi->param('savefilename');
  170 
  171     #if Save As button was clicked
  172     } elsif (( $cgi->param('action') eq 'Save as') && defined($cgi->param('body')) && defined($cgi->param('savefilename'))) {
  173 
  174       $messageFileName = $cgi->param('savefilename');
  175 
  176       if ($messageFileName =~ /^[~.]/ || $messageFileName =~ /\.\./) {
  177         &user_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");
  178       }
  179 
  180 
  181       my $temp_body = $cgi->param('body');
  182       $temp_body =~ s/\r\n/\n/g;
  183       $temp_body = "From: " . $cgi->param('from') . "\n" .
  184              "Reply-To: " . $cgi->param('replyTo') . "\n" .
  185              "Subject: " . $cgi->param('subject') . "\n" .
  186              "Message: \n" . $temp_body;
  187 
  188       saveNewProblem($temp_body, $messageFileName);
  189 
  190     #if Save As Default button was clicked
  191     } elsif (( $cgi->param('action') eq 'Save as Default') && defined($cgi->param('body'))) {
  192 
  193       my $temp_body;
  194       $temp_body = $cgi->param('body');
  195       $temp_body =~ s/\r\n/\n/g;
  196 
  197       #get default.msg and back it up in default.old.msg
  198       open DEFAULT, "$emailDirectory$default_msg";
  199         $temp_body = <DEFAULT>;
  200       close DEFAULT;
  201 
  202       if ( -e "$emailDirectory$old_default_msg") {
  203         saveProblem($temp_body, $old_default_msg);
  204       } else {
  205         saveNewProblem($temp_body, $old_default_msg);
  206       }
  207 
  208       #save new default message as default.msg
  209       $temp_body = $cgi->param('body');
  210       $temp_body =~ s/\r\n/\n/g;
  211       $temp_body = "From: " . $cgi->param('from') . "\n" .
  212              "Reply-To: " . $cgi->param('replyTo') . "\n" .
  213              "Subject: " . $cgi->param('subject') . "\n" .
  214              "Message: \n" . $temp_body;
  215 
  216       saveProblem($temp_body, $default_msg);
  217       $messageFileName = $default_msg;
  218 
  219     #if Send Email button was clicked
  220     } elsif ( $cgi->param('action') eq 'Send Email' ) {
  221 
  222       my @studentID = ();
  223 
  224       if ($cgi->param('To') eq 'classList' && defined($cgi->param('classList')) && $cgi->param('classList') ne 'None') {
  225         my $classlist = $cgi->param('classList');
  226         my $classListFile = "$templateDirectory$classlist";
  227         my @classList = ();
  228         checkClasslistFile($Global::noOfFieldsInClasslist,$classListFile);
  229         open(FILE, "$classListFile") || die "can't open $classListFile";
  230         @classList=<FILE>;
  231         close(FILE);
  232 
  233         foreach (@classList)   {                        ## read through classlist and send e-mail
  234                                                        ## message to all active students
  235             unless ($_ =~ /\S/)  {next;}                    ## skip blank lines
  236             chomp;
  237             my @classListRecord=&getRecord($_);
  238             my ($studentID, $lastName, $firstName, $status, $comment,  $section, $recitation, $email_address, $login_name)
  239                 = @classListRecord;
  240             unless (&dropStatus($status)) {
  241               push (@studentID, $studentID);
  242               $fn{$studentID} = $firstName;
  243             $ln{$studentID} = $lastName;
  244             $section{$studentID} = $section;
  245             $recitation{$studentID} = $recitation;
  246             $status{$studentID} = $status;
  247             $email{$studentID} = $email_address;
  248             $login{$studentID} = $login_name;
  249             }
  250         }
  251       }
  252       elsif ($cgi->param('To') eq 'studentID' && defined($cgi->param('studentID'))) {
  253         @studentID = $cgi->param('studentID');
  254         my ($studentID, $login_name);
  255 
  256         foreach $studentID (@studentID) {
  257           $login_name = $studentID_LoginName_Hash{$studentID};
  258           &attachCLRecord($login_name);
  259           $fn{$studentID}     = CL_getStudentFirstName($login_name);
  260           $ln{$studentID}     = CL_getStudentLastName($login_name);
  261           $section{$studentID}  = CL_getClassSection($login_name);
  262           $recitation{$studentID} = CL_getClassRecitation($login_name);
  263           $status{$studentID}   = CL_getStudentStatus($login_name);
  264           $email{$studentID}    = CL_getStudentEmailAddress($login_name);
  265           $login{$studentID}    = $login_name;
  266         }
  267 
  268       }
  269       elsif ($cgi->param('To') eq 'all_students') {
  270         @studentID = ();
  271         my ($studentID, $login_name, $status);
  272 
  273         foreach $login_name (@availableStudents) {
  274           &attachCLRecord($login_name);
  275           $status     = CL_getStudentStatus($login_name);
  276           next if &dropStatus($status);
  277           $studentID    = CL_getStudentID($login_name);
  278           push(@studentID,$studentID);
  279 
  280           $fn{$studentID}     = CL_getStudentFirstName($login_name);
  281           $ln{$studentID}     = CL_getStudentLastName($login_name);
  282           $section{$studentID}  = CL_getClassSection($login_name);
  283           $recitation{$studentID} = CL_getClassRecitation($login_name);
  284           $status{$studentID}   = CL_getStudentStatus($login_name);
  285           $email{$studentID}    = CL_getStudentEmailAddress($login_name);
  286           $login{$studentID}    = $login_name;
  287         }
  288       }
  289       else {
  290         &user_error('You didn\'t select any recipients.  Make sure you select either all student in the course, individual students or a whole classlist.');
  291       }
  292 
  293       my $mergeFile = '';
  294 
  295       #the radio button named 'merge' determines whether to take the selected mergefile
  296       #or one that was typed in.  A error message is given if select one and use the other
  297       $mergeFile = $scoringDirectory . $cgi->param('mergeFiles')
  298         if ($cgi->param('merge') eq 'mergeFiles' && defined($cgi->param('mergeFiles')) && $cgi->param('mergeFiles') ne 'None');
  299 
  300       $mergeFile = $templateDirectory . $cgi->param('mergeFile')
  301         if ($cgi->param('merge') eq 'mergeFile' && defined($cgi->param('mergeFile')) && $cgi->param('mergeFile') !~ m|/$|); #does not end in a /
  302 
  303       if ($mergeFile =~ /^[~.]/ || $mergeFile =~ /\.\./) {
  304         &user_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");
  305       }
  306       if ($cgi->param('body') =~ /(\$COL\[.*?\])/ && !(-e $mergeFile)) {
  307         &user_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.");
  308       }
  309 
  310 
  311       my %mergeAArray = ();
  312       unless ($mergeFile eq '') {%mergeAArray = &delim2aa($mergeFile);}
  313 
  314       &user_error('You didn\'t enter any message.') if ($cgi->param('body') eq '');
  315 
  316       foreach  my $studentID (@studentID) {
  317         @COL =();
  318         $SID = $studentID;
  319         $LN = defined $ln{$studentID} ? $ln{$studentID} :'';
  320         $FN = defined $fn{$studentID} ? $fn{$studentID} :'';
  321         $SECTION = defined $section{$studentID} ? $section{$studentID} :'';
  322         $RECITATION = defined $recitation{$studentID} ? $recitation{$studentID} :'';
  323         $EMAIL = defined $email{$studentID} ? $email{$studentID} :'';
  324         $STATUS =defined $status{$studentID} ?  $status{$studentID} :'';
  325         $LOGIN = $login{$studentID};
  326 
  327         next if ($LOGIN =~ /^$practiceUser/); ## skip practice users
  328 
  329         if ($timeout_attempts >= $max_timeout_attempts) {   ## have attemped to connect to smtp server
  330                                   ## the max allowed times.  Now just collect
  331                                   ## data on emails not sent and exit
  332           ++$emails_not_sent;
  333           &log_error(\@exceeded_max_timeout,$FN,$LN,$EMAIL);
  334           next;
  335         }
  336 
  337         unless ((defined $mergeAArray{$studentID}) or ($mergeFile eq '')) {
  338           if ($cgi->param('no_record')) {
  339             ++$emails_not_sent;
  340             &log_error(\@no_record,$FN,$LN,$EMAIL);
  341             next;
  342           }
  343         }
  344 
  345         my ($dbString, @dbArray);
  346         if (defined $mergeAArray{$SID}) {
  347           $dbString = $mergeAArray{$SID}; ## get sid record from merge file
  348           @dbArray = &getRecord($dbString);
  349           unshift(@dbArray,$SID);
  350           unshift(@dbArray,"");     ## note COL[1] is the first column
  351           @COL= @dbArray;       ## put merge fields in COL array
  352           $endCol = @COL;       ## \endCol-1 gives last field, etc
  353         }
  354         my $smtp;
  355         if ($smtp = Net::SMTP->new($Global::smtpServer, Timeout => $timeout_sec)) {} else {
  356 #         &internal_error("Couldn't contact SMTP server.");
  357           ++$emails_not_sent;
  358           &log_error(\@timeout_problem,$FN,$LN,$EMAIL);
  359           ++$timeout_attempts;
  360           next;
  361         }
  362 
  363         $smtp->mail($smtpSender);
  364 
  365         if ( $smtp->recipient($EMAIL)) {  # this one's okay, keep going
  366           if ( $smtp->data("To: $EMAIL\n" . output() ) ) {
  367             ++$emails_sent;
  368           } else {
  369             ++$emails_not_sent;
  370             &log_error(\@unknown_problem,$FN,$LN,$EMAIL);
  371             next;
  372           }
  373 #         &internal_error("Unknown problem sending message data to SMTP server.");
  374         } else {      # we have a problem with this address
  375           $smtp->reset;
  376           #&internal_error("SMTP server doesn't like this address: <$EMAIL>.");
  377           ++$emails_not_sent;
  378           &log_error(\@bad_email_addresses,$FN,$LN,$EMAIL);
  379         }
  380         $smtp->quit;
  381       }
  382       &success;
  383     }
  384   }
  385 
  386 
  387 
  388 #Begin Page
  389   print &htmlTOP("Send Mail for " . $course),
  390     $cgi->a( { -href=>"${cgiURL}login.pl?user=$user&key=$session_key&course=$course" },
  391 
  392       $cgi->img({ -name=>'upImg',
  393             -src=>"${Global::upImgUrl}",
  394             -align=>'right',
  395             -border=>'1',
  396             -alt=>'[Up]'
  397           })
  398       ),
  399   $cgi->p;
  400 
  401   print "\n",
  402    $cgi->hr, $cgi->br,
  403    "\n\n", $cgi->h3({ -align=>'left' }, "WeBWorK Send Mail Page for $course"), "\n",
  404    $cgi->p,
  405    "From this page, you can send email to students.  You can opt to send email to only specific
  406    students or to entire groups of students based on classlists that can be created from the
  407    professor's page.  Any email can contain various macros to refer to information specific to
  408    each student.  In particular, a merge file can be specified so that outside information, such
  409    as students grades can be placed in an email.  This is most easily done by selecting the file
  410    titled ${course}_totals.csv from the drop down list.  The information in this file is
  411    obtained by specifying \$COL[n] with the number in the brackets indicating the data item from
  412    the nth column of the merge file or, if n is negative, the nth column from the last column.
  413    (e.g. \$COL[3] is the third column and \$COL[-2] is the <U>second</U> to last column in the merge file.
  414    Messages can be saved and retrieved for later use.  Save as Default will cause the current message
  415    to be the one that is loadedd when first coming to this page.  (The old default message will be
  416    saved as default.old so that the last default can be restored manually by changing its name to
  417    default.msg)",
  418    $cgi->hr, "\n";
  419 
  420 
  421 my %labels =();
  422 $labels{alph} = 'Alphabetically';
  423 $labels{section} = 'by section';
  424 $labels{recitation} = 'by recitation';
  425 
  426 # start form with hidden entries to pass info back to profSendMail.pl
  427   print $cgi->startform(-action=>"${cgiURL}profSendMail.pl"), "\n",
  428      $cgi->hidden(-name=>"user", -value=>$user), "\n",
  429      $cgi->hidden(-name=>"key", -value=>$session_key), "\n",
  430      $cgi->hidden(-name=>"course", -value=>$course), "\n",
  431      $cgi->hidden(-name=>"filename", -value=>$openfilename), "\n";
  432 
  433 # # get all student emails and create a list
  434   print $cgi->p, $cgi->b('Send Email To: '), "\n", $cgi->br,
  435      $cgi->input({-type=>'radio', -name=>'To', -value=>'all_students'}), " \n",
  436      "Send e-mail to all current students in $course",
  437     $cgi->br, "or",$cgi->br;
  438   print  $cgi->input({-type=>'radio', -name=>'To', -value=>'studentID'}), " \n",
  439      "Send e-mail to individual students (select as many as you like)<BR>";
  440 
  441 
  442   my ($lastName, $firstName, $studentID, $login_name, $section, $recitation, $label, $status, @all_sids, %fullnames, );
  443   @all_sids = ();
  444   foreach $login_name (@availableStudents) {
  445     &attachCLRecord($login_name);
  446     $status     = CL_getStudentStatus($login_name);
  447     next if &dropStatus($status);
  448     $lastName   = CL_getStudentLastName($login_name);
  449     $firstName    = CL_getStudentFirstName($login_name);
  450     $studentID    = CL_getStudentID($login_name);
  451     $section    = CL_getClassSection($login_name);
  452     $recitation   = CL_getClassRecitation($login_name);
  453 
  454     if ($format eq 'section') {
  455     $label = ", $section";
  456     }
  457     elsif ($format eq 'recitation') {
  458     $label = ", $recitation";
  459     }
  460     else {
  461     $label = '';
  462     }
  463     $label = "$lastName, $firstName, $studentID, $login_name". $label;
  464     push (@all_sids, $studentID); #array for values of popup_menu
  465     $fullnames{$studentID} = $label;
  466   }
  467 
  468   print $cgi->popup_menu(-name=>'studentID',
  469              -size=>'5',
  470              -multiple=>undef,
  471              -values=>\@all_sids,
  472              -labels=>\%fullnames),
  473      "\n",
  474   $cgi->br,
  475   "Order students \n",
  476   $cgi->radio_group(
  477     -name=>'format',
  478     -values=>['alph','section','recitation'],
  479     -default=>'alph',
  480     -labels=>\%labels
  481   ),
  482   $cgi->br,
  483   $cgi->submit(-value=>'Reorder list now'),
  484     $cgi->br, "or",$cgi->br;
  485 
  486   print $cgi->input({-type=>'radio', -name=>'To', -value=>'classList'}), " \n",
  487      "Select a classlist to send a message to: \n", $cgi->br,
  488      "(Classlist files can be created from the Professor's Page)\n", $cgi->br;
  489 
  490 
  491 # get all classlist files
  492 #
  493 # opendir CLASSLISTDIR, $templateDirectory; # or wwerror($0, "Can't open directory $templateDirectory","","");
  494 #   my @allFiles = grep !/^\./, readdir CLASSLISTDIR;
  495 # closedir CLASSLISTDIR;
  496 #
  497 # my @classlistFiles = grep /\.lst$/, @allFiles; #all classlist files
  498 # my @sortedNames = sort @classlistFiles;
  499 #
  500 # my $shortFileName = $defaultClasslistFile;
  501 #
  502 # if ($shortFileName =~ m|/| ) {
  503 #   $shortFileName =~ m|/([^/]*)$|; ## extract filename from full path name
  504 #   $shortFileName = $1;
  505 # }
  506 #
  507 # my @newSortedNames = grep !/^$shortFileName$/, @sortedNames;
  508 #
  509 # if ($#newSortedNames != $#sortedNames) {
  510 #   unshift @newSortedNames, $shortFileName;
  511 #   @sortedNames = @newSortedNames;
  512 # }
  513   my ($ar_sortedNames, $hr_classlistLabels) = getClasslistFilesAndLabels($course);
  514   my @sortedNames = @$ar_sortedNames;
  515   my %classlistLabels = %$hr_classlistLabels;
  516   unshift(@sortedNames, "None");
  517   $classlistLabels{None} = 'None';
  518 
  519 #create list of classlists
  520   print $cgi->popup_menu(-name=>'classList',
  521              -values=>\@sortedNames,
  522              -labels=>\%classlistLabels,
  523              -default=>'None');
  524 
  525 print $cgi->hr, $cgi->p, $cgi->b('Enter Message: '), "\n", $cgi->br;
  526 #get message from given messageFileName
  527   my ($text, @text);
  528   my $header = '';
  529   my ($subject, $from, $replyTo);
  530   if (-e "$emailDirectory$messageFileName") {
  531     open FILE, "$emailDirectory$messageFileName";
  532     while ($header !~ s/Message:\s*$//m) { $header .= <FILE>; }
  533     $text = join '', <FILE>;
  534     $header =~ /^From:\s(.*)$/m;
  535     $from = $1 or $from = $defaultFrom; #given email address or default feedback address
  536     $header =~ /^Reply-To:\s(.*)$/m;
  537     $replyTo = $1 or $replyTo = $defaultReply;
  538     $header =~ /^Subject:\s(.*)$/m;
  539     $subject = $1;
  540 
  541   } else {
  542     # wwerror($0, "Message File $emailDirectory$messageFileName does not exist!");
  543   }
  544 
  545 # show professors's name and email address
  546   print "\n", $cgi->p, $cgi->b('From:     '), $cgi->textfield(-name=>"from", -size=>40, -value=>$from, -override=>1),
  547      "\n", $cgi->p, $cgi->b('Reply-To: '), $cgi->textfield(-name=>"replyTo", -size=>40, -value=>$replyTo, -override=>1);
  548 
  549 #create a textbox with the subject and a textarea with the message
  550 
  551   print "\n", $cgi->p, $cgi->b('Subject:  '), $cgi->textfield(-name=>'subject', -default=>$subject, -size=>40, -override=>1),
  552     $cgi->p,
  553     "\n", $cgi->p, $cgi->b('Message: ');
  554 
  555 #show available macros
  556   print $cgi->br, $cgi->popup_menu(
  557             -name=>'dummyName',
  558             -values=>['', '$SID', '$FN', '$LN', '$SECTION', '$RECITATION','$STATUS', '$EMAIL', '$LOGIN', '$COL[3]', '$COL[-1]'],
  559             -labels=>{''=>'These macros can be used to insert student specific data:',
  560               '$SID'=>'$SID - Student ID',
  561               '$FN'=>'$FN - First name',
  562               '$LN'=>'$LN - Last name',
  563               '$SECTION'=>'$SECTION - Student\'s Section',
  564               '$RECITATION'=>'$RECITATION - Student\'s Recitation',
  565               '$STATUS'=>'$STATUS - C, Audit, Drop, etc.',
  566               '$EMAIL'=>'$EMAIL - Email address',
  567               '$LOGIN'=>'$LOGIN - Login',
  568               '$COL[3]'=>'$COL[3] - Third column in merge file',
  569               '$COL[-1]'=>'$COL[-1] - Last column in merge file'
  570               }
  571                   ), "\n";
  572 
  573   opendir SCORINGDIR, $scoringDirectory; # or wwerror($0, "Can't open directory $scoringDirectory","","");
  574   my @allFiles = grep !/^\./, readdir SCORINGDIR;
  575   closedir SCORINGDIR;
  576 
  577   my @mergeFiles = grep /\.csv$/, @allFiles; #all classlist files
  578   @sortedNames = sort @mergeFiles;
  579   unshift(@sortedNames, "None");
  580 
  581 #print a merge file popup list
  582   print $cgi->br, "\nSelect a merge file: ",
  583      $cgi->input({-type=>'radio', -name=>'merge', -value=>'mergeFiles', -checked=>undef}), ' ',
  584      $cgi->popup_menu(-name=>'mergeFiles',
  585              -values=>\@sortedNames,
  586              -default=>"None"),
  587      "or type in your own &nbsp;";
  588 
  589   my $shortDirectory = $emailDirectory;
  590   $shortDirectory =~ s|.*/(\w*/)$|$1|;
  591 #and a textbox to type in your own merge file
  592   print $cgi->input({-type=>'radio', -name=>'merge', -value=>'mergeFile'}), ' ',
  593      $cgi->textfield(-name=>'mergeFile',
  594             -value=>$shortDirectory);
  595   print "\n", $cgi->br, $cgi->input({-type=>'checkbox', -name=>'no_record', -value=>1, }),
  596   'Do not send email if there is no record in merge file.',$cgi->br;
  597 
  598 #print actual body of message
  599   print "\n", $cgi->br, $cgi->textarea(-name=>'body', -default=>$text, -rows=>$rows, -columns=>$columns, -override=>1);
  600 
  601 
  602 #get all message files and create a list
  603   opendir EMAILDIR, $emailDirectory; # or wwerror($0, "Can't open directory $emailDirectory","","");
  604     my @messageFiles = grep /\.msg$/, readdir EMAILDIR; #all message files
  605   closedir EMAILDIR;
  606 
  607   my @sortedMessages = sort @messageFiles;
  608 
  609   print $cgi->p, $cgi->popup_menu(-name=>'openfilename', -values=>\@sortedMessages, -default=>$messageFileName);
  610 
  611 
  612 #create all necessary action buttons
  613   print $cgi->submit(-name=>'action', -value=>'Open'), "\n", $cgi->br,
  614      $cgi->textfield(-name=>'savefilename', -size => 20, -value=> "$messageFileName", -override=>1), ' ',
  615      $cgi->submit(-name=>'action', -value=>'Save'), " \n",
  616      $cgi->submit(-name=>'action', -value=>'Save as'), " \n",
  617      $cgi->submit(-name=>'action', -value=>'Save as Default'), "\n", $cgi->br,
  618      'For "Save As" choose a new filename.', $cgi->br, $cgi->br,
  619      $cgi->submit(-name=>'action', -value=>'Send Email'), "\n",
  620      $cgi->p, $cgi->submit(-name=>'action', -value=>'Revert to original and Resize message window'),
  621      " Rows: ", $cgi->textfield(-name=>'rows', -size=>3, -value=>$rows),
  622      " Columns: ", $cgi->textfield(-name=>'columns', -size=>3, -value=>$columns),
  623      $cgi->br, "If you resize the message window, you will lose all unsaved changes.",
  624      $cgi->end_form,
  625      &htmlBOTTOM("profSendMail", \%inputs, 'profSendMailHelp.html');
  626 
  627 # End of HTML
  628 
  629 
  630 ###### SUBROUTINES ######
  631 sub saveProblem {
  632   my ($body, $probFileName)= @_;
  633 
  634   open (PROBLEM, ">${emailDirectory}$probFileName") ||
  635     wwerror($0, "Could not open ${emailDirectory}$probFileName for writing.
  636     Check that the  permissions for this problem are 660 (-rw-rw----)");
  637   print PROBLEM $body;
  638   close PROBLEM;
  639   chmod 0660, "${emailDirectory}${probFileName}" ||
  640                print "Content-type: text/html\n\n
  641                       CAN'T CHANGE PERMISSIONS ON FILE ${templateDirectory}${probFileName}";
  642 
  643 }
  644 
  645 sub saveNewProblem {
  646   my ($body, $new_file_name)= @_;
  647  #######check that the new file name doesn't exist
  648   if (-e "${emailDirectory}$new_file_name" ) {
  649     wwerror("Can not use this file name", "The file\n".
  650     "${emailDirectory}$new_file_name\n".
  651     "already exists.\n" .
  652     "<b>The new version was not saved.</b>\n" .
  653     "Go back and choose a different file name or\, if you really want to edit\n".
  654     "${templateDirectory}$new_file_name\,\n".
  655     "go back and hit the \&quot;Save updated version\&quot; button.");
  656   }
  657 
  658   wwerror ("Invalid file name", "The file name \"$new_file_name\" does not have a \".msg\" extension.
  659 All email file names must end in the extension \".msg\"
  660 <b>The file was not saved.</b>
  661 Go back and choose a file name with a \".msg\" extension.") unless
  662     $new_file_name =~ m|\.msg$|;
  663  #######copy new version to the file new_file_name
  664   open (PROBLEM, ">${emailDirectory}$new_file_name") ||
  665     wwerror($0, "Could not open ${emailDirectory}$new_file_name for writing.
  666     Check that the  permissions for the directory ${emailDirectory} are 770 (drwxrwx---)");
  667   print PROBLEM $body;
  668   close PROBLEM;
  669   chmod 0660, "${emailDirectory}$new_file_name" ||
  670                print "Content-type: text/html\n\n
  671                       CAN'T CHANGE PERMISSIONS ON FILE ${emailDirectory}$new_file_name";
  672 
  673 }
  674 
  675 sub internal_error {
  676     my $msg = join " ", @_;
  677     print $cgi->header,
  678       $cgi->start_html('-title' => "Internal Error"),
  679   $cgi->h1('Internal Error'),
  680   $cgi->b(HTML::Entities::encode($msg)),
  681   $cgi->p,
  682   "Your message could not be sent.  Please notify ",
  683   "&lt;", $cgi->a({href=>"mailto:$Global::webmaster"}, $Global::webmaster), "&gt;. ",
  684   $cgi->br,
  685   "We apologize for the inconvenience.",
  686   $cgi->end_html;
  687     exit(1);
  688 }
  689 
  690 sub user_error {
  691     my $msg = join " ", @_;
  692     print $cgi->header,
  693   $cgi->start_html('-title' => 'User error'),
  694   $cgi->h1('User error'),
  695   $cgi->p,
  696   $cgi->b(HTML::Entities::encode($msg)),
  697   $cgi->p,
  698         "Please hit the &quot;<B>Back</B>&quot; button on your browser to ",
  699   "try again, or notify ", $cgi->br,
  700   "&lt;", $cgi->a({href=>"mailto:$Global::webmaster"}, $Global::webmaster), "&gt; ",
  701   "if you believe this message is in error.",
  702   $cgi->end_html;
  703     exit(1);
  704 }
  705 
  706 sub check_destination {
  707     my($address_list) = @_;
  708 
  709     my (@address) = split(/\+*,\+*/, $address_list);
  710     for (@address) {
  711        &internal_error("Sorry, I'm not allowed to send mail to <$_>.")
  712            if !/$Global::legalAddress/;
  713     }
  714 }
  715 
  716 sub output {
  717   my ($msg, $body, $tmp);
  718 
  719   $body = $cgi->param('body');
  720 
  721   $tmp = $body;
  722   $tmp =~ s/(\$SID)/eval($1)/ge;
  723   $tmp =~ s/(\$LN)/eval($1)/ge;
  724   $tmp =~ s/(\$FN)/eval($1)/ge;
  725   $tmp =~ s/(\$STATUS)/eval($1)/ge;
  726   $tmp =~ s/(\$SECTION)/eval($1)/ge;
  727   $tmp =~ s/(\$RECITATION)/eval($1)/ge;
  728   $tmp =~ s/(\$EMAIL)/eval($1)/ge;
  729   $tmp =~ s/(\$LOGIN)/eval($1)/ge;
  730   $tmp =~ s/\$COL\[ *-/\$COL\[$endCol-/g;
  731   $tmp =~ s/(\$COL\[.*?\])/eval($1)/ge;
  732 
  733 
  734   $msg =
  735        # message header
  736        "From: "           . $cgi->param('from') . "\n" .
  737        "Reply-To: "       . $cgi->param('replyTo')   . "\n" .
  738        "Subject:  ". $cgi->param('subject') . "\n" .
  739     "\n" . $tmp . "\n";
  740 
  741   $msg =~ s/\r//g;
  742   return $msg;
  743 }
  744 
  745 sub success {
  746     print $cgi->header,
  747     $cgi->start_html( '-title'=>'Email Sent'),"\n",
  748     $cgi->h1("Your message has been sent to $emails_sent users."),"\n",
  749     $cgi->br;
  750 
  751     if  ($emails_not_sent > 0) {
  752       print $cgi->h1("However, emails were not sent to the following $emails_not_sent users:"),"\n",
  753       $cgi->br,
  754       $cgi->h2('The format below is &quot;FirstName LastName &lt;EmailAddress&gt;&quot;');
  755 
  756       if (scalar(@no_record) > 0) {
  757         print "\n", $cgi->br,
  758         $cgi->h3('The following have no record in the merge file'),"\n";
  759         foreach my $line (@no_record) {print "\n$line <BR>";}
  760       }
  761       if (scalar(@unknown_problem) > 0) {
  762         print "\n", $cgi->br,
  763         $cgi->h3('The following have an unknown problem');
  764         foreach my $line (@unknown_problem) {print "\n$line <BR>";}
  765       }
  766       if (scalar(@bad_email_addresses) > 0) {
  767         print "\n", $cgi->br,
  768         $cgi->h3('The following have a bad email address');
  769         foreach my $line (@bad_email_addresses) {print "\n$line <BR>";}
  770       }
  771       if (scalar(@timeout_problem) > 0) {
  772         print "\n", $cgi->br,
  773         $cgi->h3('Connecting to the SMTP server timed out for the following');
  774         foreach my $line (@timeout_problem) {print "\n$line <BR>";}
  775       }
  776       if (scalar(@exceeded_max_timeout) > 0) {
  777         print "\n", $cgi->br,
  778         $cgi->h3("Connecting to the SMTP server failed $max_timeout_attempts times. No attempt was made to send emails to the following");
  779         foreach my $line (@exceeded_max_timeout) {print "\n$line <BR>";}
  780       }
  781     }
  782     print "\n", $cgi->end_html;
  783     exit(0);
  784 }
  785 
  786 sub log_error {
  787   my ($ra_addresses,$FN,$LN,$EMAIL) = @_;
  788   my $line = "$FN $LN &lt;${EMAIL}&gt;";
  789   push @$ra_addresses, $line;
  790 }

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9