[system] / trunk / webwork2 / lib / WeBWorK / ContentGenerator / Instructor / SendMail.pm Repository:
ViewVC logotype

View of /trunk/webwork2/lib/WeBWorK/ContentGenerator/Instructor/SendMail.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1375 - (download) (as text) (annotate)
Sun Jul 13 18:56:27 2003 UTC (9 years, 10 months ago) by gage
File size: 29819 byte(s)
Fixed some bugs where defaults were not always initialized.
--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 use Mail::Sender;
   15 
   16 sub initialize {
   17   my ($self) = @_;
   18   my $r = $self->{r};
   19   my $db = $self->{db};
   20   my $ce = $self->{ce};
   21   my $authz = $self->{authz};
   22   my $user = $r->param('user');
   23 
   24   unless ($authz->hasPermissions($user, "send_mail")) {
   25     $self->{submitError} = "You are not authorized to send mail to students.";
   26     return;
   27   }
   28 #############################################################################################
   29 # gather directory data
   30 #############################################################################################
   31   my $emailDirectory    =    $ce->{courseDirs}->{email};
   32   my $scoringDirectory  =    $ce->{courseDirs}->{scoring};
   33   my $templateDirectory =    $ce->{courseDirs}->{templates};
   34 
   35   my $action            =    $r->param('action');
   36   my $openfilename      =    $r->param('openfilename');
   37   my $savefilename      =    $r->param('savefilename');
   38 
   39 
   40   #FIXME  get these values from global course environment (see subroutines as well)
   41   my $default_msg_file       =    'default.msg';
   42   my $old_default_msg_file   =    'old_default.msg';
   43 
   44 
   45   # store data
   46   $self->{defaultFrom}            =   'FIXME from';
   47   $self->{defaultReply}           =   'FIXME reply';
   48   $self->{rows}                   =   (defined($r->param('rows'))) ? $r->param('rows') : $ce->{mail}->{editor_window_rows};
   49   $self->{columns}                =   (defined($r->param('columns'))) ? $r->param('columns') : $ce->{mail}->{editor_window_columns};
   50   $self->{default_msg_file}     =   $default_msg_file;
   51   $self->{old_default_msg_file}   =   $old_default_msg_file;
   52   $self->{merge_file}             =   (defined($r->param('merge_file'  )))    ? $r->param('merge_file')   : 'None';
   53   $self->{preview_user}           =   (defined($r->param('preview_user')))    ? $r->param('preview_user') : 'Yourself';
   54 
   55 
   56 #############################################################################################
   57 # gather database data
   58 #############################################################################################
   59   # FIXME  this might be better done in body? We don't always need all of this data. or do we?
   60   my @users = sort $db->listUsers;
   61   my @user_records = ();
   62   push(@user_records,$db->getUser($_)) foreach  (@users);
   63 
   64   # store data
   65   $self->{ra_users}              =   \@users;
   66   $self->{ra_user_records}       =   \@user_records;
   67 
   68 #############################################################################################
   69 # gather list of recipients
   70 #############################################################################################
   71   my @send_to                    =   ();
   72   #FIXME  this (radio) is a lousy name
   73   my $recipients                 = $r->param('radio');
   74   if (defined($recipients) and $recipients eq 'all_students') {  #only active students #FIXME status check??
   75     foreach my $ur (@user_records) {
   76       push(@send_to,$ur->user_id) if $ur->status eq 'C' and not($ur->user_id =~ /practice/);
   77     }
   78   } elsif (defined($recipients) and $recipients eq 'studentID' ) {
   79     @send_to                   = $r->param('classList');
   80   } else {
   81     # no recipients have been defined -- probably the first time on the page
   82   }
   83   $self->{ra_send_to}               = \@send_to;
   84 #################################################################
   85 # Check the validity of the input file name
   86 #################################################################
   87   my $input_file = '';
   88   #make sure an input message file was submitted and exists
   89   #else use the default message
   90   if ( defined($openfilename) ) {
   91     if ( -e "${emailDirectory}/$openfilename") {
   92       if ( -R "${emailDirectory}/$openfilename") {
   93         $input_file = $openfilename;
   94       } else {
   95         warn join("",
   96           "The file ${emailDirectory}/$openfilename is not readable by the webserver.",CGI::br(),
   97           "Check that it's permissions are set correctly.",
   98         );
   99       }
  100     } else {
  101       $input_file = $default_msg_file;
  102       warn join("",
  103           "The file ${emailDirectory}/$openfilename cannot be found.",CGI::br(),
  104           "Check whether it exists and whether the directory $emailDirectory can be read by the webserver.",CGI::br(),
  105           "Using contents of the default message $default_msg_file instead.",
  106       );
  107     }
  108   } else {
  109     $input_file     = $default_msg_file;
  110   }
  111   $self->{input_file} =$input_file;
  112 
  113 #################################################################
  114 # Determine the file name to save message into
  115 #################################################################
  116   my $output_file      = 'FIXME no output file specified';
  117   if (defined($action) and $action eq 'Save as Default') {
  118     $output_file  = $default_msg_file;
  119   } elsif ( defined($action) and ($action =~/save/i) and defined($savefilename) ){
  120     $output_file  = $savefilename;
  121   } elsif ( defined($input_file) ) {
  122     $output_file  = $input_file;
  123   }
  124 # warn "FIXME savefilename $savefilename  output file $output_file";
  125   #################################################################
  126   # Sanity check on save file name
  127   #################################################################
  128 
  129   if ($output_file =~ /^[~.]/ || $output_file =~ /\.\./) {
  130     $self->submission_error("For security reasons, you cannot specify a merge file from a directory",
  131                 "higher than the email directory (you can't use ../blah/blah). ",
  132                 "Please specify a different file or move the needed file to the email directory",
  133     );
  134   }
  135   unless ($output_file =~ m|\.msg$| ) {
  136     $self->submission_error("Invalid file name.",
  137                             "The file name \"$output_file\" does not have a \".msg\" extension",
  138                 "All email file names must end in the extension \".msg\"",
  139                 "choose a file name with a \".msg\" extension.",
  140                 "The message was not saved.",
  141     );
  142   }
  143   $self->{output_file} = $output_file;  # this is ok.  It will be put back in the text input box for re-editing.
  144     # FIXME $output_file can be blank if there was no savefilename
  145 
  146 #############################################################################################
  147 # Determine input source
  148 #############################################################################################
  149   my $input_source =  ( defined( $r->param('body') ) and $action ne 'Open' ) ? 'form' : 'file';
  150 # warn "FIXME input source is $input_source from $input_file";
  151 #############################################################################################
  152 # Get inputs
  153 #############################################################################################
  154   my($from, $replyTo, $r_text, $subject);
  155   if ($input_source eq 'file') {
  156 #   warn "FIXME obtaining source from $emailDirectory/$input_file";
  157     ($from, $replyTo,$subject,$r_text) = $self->read_input_file("$emailDirectory/$input_file");
  158 #   warn "FIXME Done reading source";
  159 
  160   } elsif ($input_source eq 'form') {
  161     # read info from the form
  162     # bail if there is no message body
  163 
  164     $from              =    $r->param('from');
  165     $replyTo           =    $r->param('replyTo');
  166     $subject           =    $r->param('subject');
  167     my $body              =    $r->param('body');
  168     # Sanity check: body must contain non-white space
  169     $self->submission_error('You didn\'t enter any message.') unless ($r->param('body') =~ /\S/);
  170     $r_text               =    \$body;
  171 
  172   }
  173   # store data
  174   $self->{from}                   =    $from;
  175   $self->{replyTo}                =    $replyTo;
  176   $self->{subject}                =    $subject;
  177   $self->{r_text}                 =    $r_text;
  178 
  179 
  180 
  181 ###################################################################################
  182 #Determine the appropriate script action from the buttons
  183 ###################################################################################
  184 #     first time actions
  185 #          open new file
  186 #          open default file
  187 #     choose merge file actions
  188 #          chose merge button
  189 #     option actions
  190 #       'reset rows'
  191 
  192 #     save actions
  193 #   "save" button
  194 #   "save as" button
  195 #   "save as default" button
  196 #     preview actions
  197 #   'preview' button
  198 #     email actions
  199 #   'entire class'
  200 #   'selected studentIDs'
  201 #     error actions (various)
  202 
  203 
  204 #############################################################################################
  205 # if no form is submitted, gather data needed to produce the mail form and return
  206 #############################################################################################
  207   my $to                =    $r->param('To');
  208   my $script_action     = '';
  209 
  210 
  211   if(not defined($action) or $action eq 'Open' or $action eq 'Resize message window'
  212      or $action eq 'Set merge file to:' ){
  213 #   warn "FIXME action is |$action| no further initialization required";
  214     return '';
  215   }
  216 
  217 
  218 
  219 
  220 
  221 #############################################################################################
  222 # If form is submitted deal with filled out forms
  223 # and various actions resulting from different buttons
  224 #############################################################################################
  225 
  226 
  227 
  228   # user_errors
  229   # save
  230   # save as
  231   # save as default
  232   # send mail
  233   # set defaults
  234 
  235   if ($action eq 'Save' or $action eq 'Save as:' or $action eq 'Save as Default') {
  236 
  237 #   warn "FIXME Saving files  action = $action  outputFileName=$output_file";
  238 
  239     #################################################################
  240     # construct message body
  241     #################################################################
  242     my $temp_body = ${ $r_text };
  243     $temp_body =~ s/\r\n/\n/g;
  244     $temp_body = join("",
  245            "From: $from \nReply-To: $replyTo\n" ,
  246            "Subject: $subject\n" ,
  247            "Message: \n    $temp_body");
  248 #   warn "FIXME from $from | subject $subject |reply $replyTo|msg $temp_body";
  249     #################################################################
  250     # overwrite protection
  251     #################################################################
  252     if ($action eq 'Save as:' and -e "$emailDirectory/$output_file") {
  253       $self->submission_error("The file $emailDirectory/$output_file already exists and cannot be overwritten",
  254                                "The message was not saved");
  255       return;
  256     }
  257 
  258     #################################################################
  259       # Back up existing file?
  260       #################################################################
  261       if ($action eq 'Save as Default' and -e "$emailDirectory/$default_msg_file") {
  262         rename("$emailDirectory/$default_msg_file","$emailDirectory/$old_default_msg_file") or
  263                die "Can't rename $emailDirectory/$default_msg_file to $emailDirectory/$old_default_msg_file ",
  264                    "Check permissions for webserver on directory $emailDirectory. $!";
  265         $self->{message} .= "Backup file <code>$emailDirectory/$old_default_msg_file</code> created.".CGI::br();
  266       }
  267       #################################################################
  268       # Save the message
  269     #################################################################
  270     $self->saveProblem($temp_body, "${emailDirectory}/$output_file" );
  271     $self->{message}         .= "Message saved to file <code>${emailDirectory}/$output_file</code>.";
  272 #   warn "FIXME saving to ${emailDirectory}/$output_file";
  273   } elsif ($action eq 'Preview') {
  274     $self->{response}         = 'preview';
  275 
  276   } elsif ($action eq 'Send Email') {
  277     $self->{response}         = 'send_email';
  278 
  279     my @recipients            = @{$self->{ra_send_to}};
  280     warn "No recipients selected " unless @recipients;
  281     #  get merge file
  282     my $merge_file      = ( defined($self->{merge_file}) ) ? $self->{merge_file} : 'None';
  283     my $delimiter       = ',';
  284     my $rh_merge_data   = $self->read_merge_file("$merge_file", "$delimiter");
  285     warn "No data for merge file $merge_file" unless ref($rh_merge_data);
  286 
  287     foreach my $recipient (@recipients) {
  288       #warn "FIXME sending email to $recipient";
  289       my $ur      = $self->{db}->getUser($recipient);
  290       my ($msg, $preview_header);
  291       eval{ ($msg,$preview_header) = $self->process_message($ur,$rh_merge_data); };
  292       warn "There were errors in processing user $ur, merge file $merge_file. $@" if $@;
  293       my $mailer = Mail::Sender->new({
  294         from    =>   $from,
  295         to      =>   $ur->email_address,
  296         smtp    =>   $ce->{mail}->{smtpServer},
  297         subject =>   $subject,
  298         headers =>   "X-Remote-Host: ".$r->get_remote_host(),
  299       });
  300       unless (ref $mailer) {
  301         warn "Failed to create a mailer: $Mail::Sender::Error";
  302         next;
  303       }
  304       unless (ref $mailer->Open()) {
  305         warn "Failed to open the mailer: $Mail::Sender::Error";
  306         next;
  307       }
  308       my $MAIL = $mailer->GetHandle() or warn "Couldn't get handle";
  309       $msg = 'Hi ' . $msg;
  310       print $MAIL  $msg || warn "Couldn't print to $MAIL";
  311       close $MAIL || warn "Couldn't close $MAIL";
  312         #warn "FIXME mailed to ", $ur->email_address, "from $from subject $subject";
  313 
  314     }
  315 
  316 
  317 #&success;
  318 
  319 
  320   } else {
  321     warn "Didn't recognize button $action";
  322   }
  323 
  324 
  325 
  326 }  #end initialize
  327 
  328 
  329 sub title {
  330   my $self = shift;
  331   return 'Send mail to ' .$self->{ce}->{courseName};
  332 }
  333 
  334 sub path {
  335   my $self          = shift;
  336   my $args          = $_[-1];
  337 
  338   my $ce = $self->{ce};
  339   my $root = $ce->{webworkURLs}->{root};
  340   my $courseName = $ce->{courseName};
  341   return $self->pathMacro($args,
  342     "Home"          => "$root",
  343     $courseName     => "$root/$courseName",
  344     'instructor'    => "$root/$courseName/instructor",
  345     "Send Mail to: $courseName"      => '',
  346   );
  347 }
  348 
  349 sub body {
  350   my ($self, $setID)  = @_;
  351   my $response        = (defined($self->{response}))? $self->{response} : '';
  352   if ($response eq 'preview') {
  353     $self->print_preview($setID);
  354   } elsif (($response eq 'send_email')){
  355     $self->{message} .= CGI::h3("Email sent to "). join(" ", @{$self->{ra_send_to}});
  356     $self->print_form($setID);
  357   } else {
  358     $self->print_form($setID);
  359   }
  360 
  361 }
  362 sub print_preview {
  363   my ($self, $setID)  = @_;
  364   #  get preview user
  365   my $ur      = $self->{db}->getUser($self->{preview_user});
  366 
  367   #  get merge file
  368   my $merge_file      = ( defined($self->{merge_file}) ) ? $self->{merge_file} : 'None';
  369   my $delimiter       = ',';
  370   my $rh_merge_data   = $self->read_merge_file("$merge_file", "$delimiter");
  371 
  372   my ($msg, $preview_header) = $self->process_message($ur,$rh_merge_data);
  373 
  374   my $recipients  = join(" ",@{$self->{ra_send_to} });
  375   my $errorMessage =  defined($self->{submitError}) ?  CGI::h3($self->{submitError} ) : '' ;
  376   $msg = join("",
  377      $errorMessage,
  378      $preview_header,
  379      "To: "             , $ur->email_address,"\n",
  380        "From: "           , $self->{from} , "\n" ,
  381        "Reply-To: "       , $self->{replyTo} , "\n" ,
  382        "Subject:  "       , $self->{subject} , "\n" ,"\n" ,
  383      $msg , "\n"
  384   );
  385 
  386   return join("", '<pre>',$msg,"\n","\n",
  387            '</pre>',
  388            CGI::p('Use browser back button to return from preview mode'),
  389            CGI::h3('Emails to be sent to the following:'),
  390            $recipients, "\n",
  391 
  392   );
  393 
  394 }
  395 sub print_form {
  396   my ($self, $setID) = @_;
  397   my $r = $self->{r};
  398   my $authz = $self->{authz};
  399   my $user = $r->param('user');
  400   my $db = $self->{db};
  401   my $ce = $self->{ce};
  402   my $root = $ce->{webworkURLs}->{root};
  403   my $courseName = $ce->{courseName};
  404 
  405         return CGI::em("You are not authorized to access the Instructor tools.") unless $authz->hasPermissions($user, "access_instructor_tools");
  406 
  407   my $userTemplate = $db->newUser;
  408   my $permissionLevelTemplate = $db->newPermissionLevel;
  409 
  410   # This code will require changing if the permission and user tables ever have different keys.
  411   my @users                 = @{ $self->{ra_users} };
  412   my $ra_user_records       = $self->{ra_user_records};
  413   my %classlistLabels       = ();#  %$hr_classlistLabels;
  414   foreach my $ur (@{ $ra_user_records }) {
  415     $classlistLabels{$ur->user_id} = $ur->user_id.' '.$ur->last_name. ', '. $ur->first_name.' - '.$ur->section;
  416   }
  417 
  418 
  419 ##############################################################################################################
  420 
  421 
  422   my $from            = $self->{from};
  423   my $subject         = $self->{subject};
  424   my $replyTo         = $self->{replyTo};
  425   my $columns         = $self->{columns};
  426   my $rows            = $self->{rows};
  427   my $text            = defined($self->{r_text}) ? ${ $self->{r_text} }: 'FIXME no text was produced by initialization!!';
  428   my $input_file      = $self->{input_file};
  429   my $output_file     = $self->{output_file};
  430   my @sorted_messages = $self->get_message_file_names;
  431   my @sorted_merge_files = $self->get_merge_file_names;
  432   my $merge_file      = ( defined($self->{merge_file}) ) ? $self->{merge_file} : 'None';
  433   my $delimiter       = ',';
  434   my $rh_merge_data   = $self->read_merge_file("$merge_file", "$delimiter");
  435   my @merge_keys      = keys %$rh_merge_data;
  436   my $preview_user    = $self->{preview_user};
  437   my $preview_record   = $db->getUser($preview_user);
  438 
  439 #############################################################################################
  440 
  441   print CGI::start_form({method=>"post", action=>$r->uri()});
  442   print $self->hidden_authen_fields();
  443 #############################################################################################
  444 # begin upper table
  445 #############################################################################################
  446 
  447     print CGI::start_table({-border=>'2', -cellpadding=>'4'});
  448   print CGI::Tr({-align=>'left',-valign=>'VCENTER'},
  449 #############################################################################################
  450 # first column
  451 #############################################################################################
  452 
  453        CGI::td("Message file: $input_file","\n",CGI::br(),
  454          CGI::submit(-name=>'action', -value=>'Open'), '&nbsp;&nbsp;&nbsp;&nbsp;',"\n",
  455          CGI::popup_menu(-name=>'openfilename',
  456                          -values=>\@sorted_messages,
  457                          -default=>$input_file
  458          ), "\n",CGI::br(),
  459 
  460          "Save file to: $output_file","\n",CGI::br(),
  461          "\n", 'From:','&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;',  CGI::textfield(-name=>"from", -size=>30, -value=>$from, -override=>1),
  462          "\n", CGI::br(),'Reply-To: ', CGI::textfield(-name=>"replyTo", -size=>30, -value=>$replyTo, -override=>1),
  463          "\n", CGI::br(),'Subject:  ', CGI::br(), CGI::textarea(-name=>'subject', -default=>$subject, -rows=>3,-columns=>35, -override=>1),
  464       ),
  465 #############################################################################################
  466 # second column
  467 #############################################################################################
  468       CGI::td({-align=>'left'},
  469         CGI::radio_group(-name=>'radio', -values=>['all_students','studentID'],
  470           -labels=>{all_students=>'All active students',studentID => 'Select recipients'},
  471           -default=>'studentID',
  472           -linebreak=>1),
  473           CGI::br(),
  474           CGI::popup_menu(-name=>'classList',
  475                  -values=>\@users,
  476                  -labels=>\%classlistLabels,
  477                  -size  => 10,
  478                  -multiple => 1,
  479                  -default=>$user
  480           ),
  481 
  482 
  483       ),
  484 #############################################################################################
  485 # third column
  486 #############################################################################################
  487       CGI::td({align=>'left'},
  488            "Merge file is: $merge_file", CGI::br(),
  489          CGI::submit(-name=>'action', -value=>'Set merge file to:'),CGI::br(),
  490          CGI::popup_menu(-name=>'merge_file',
  491                          -values=>\@sorted_merge_files,
  492                          -default=>$merge_file,
  493          ), "\n",CGI::hr(),CGI::br(),
  494         CGI::submit(-name=>'action', -value=>'preview',-label=>'Preview')," email to ",
  495         CGI::popup_menu(-name=>'preview_user',
  496                  -values=>\@users,
  497                  #-labels=>\%classlistLabels,
  498                  -default=>$preview_user,
  499         ),
  500         CGI::hr(),
  501         CGI::submit(-name=>'action', -value=>'resize', -label=>'Resize message window'),CGI::br(),
  502         " Rows: ", CGI::textfield(-name=>'rows', -size=>3, -value=>$rows),
  503         " Columns: ", CGI::textfield(-name=>'columns', -size=>3, -value=>$columns),
  504         CGI::br(),CGI::br(),
  505       #show available macros
  506         CGI::popup_menu(
  507             -name=>'dummyName',
  508             -values=>['', '$SID', '$FN', '$LN', '$SECTION', '$RECITATION','$STATUS', '$EMAIL', '$LOGIN', '$COL[3]', '$COL[-1]'],
  509             -labels=>{''=>'list of insertable macros',
  510               '$SID'=>'$SID - Student ID',
  511               '$FN'=>'$FN - First name',
  512               '$LN'=>'$LN - Last name',
  513               '$SECTION'=>'$SECTION',
  514               '$RECITATION'=>'$RECITATION',
  515               '$STATUS'=>'$STATUS - C, Audit, Drop, etc.',
  516               '$EMAIL'=>'$EMAIL - Email address',
  517               '$LOGIN'=>'$LOGIN - Login',
  518               '$COL[3]'=>'$COL[3] - 3rd col',
  519               '$COL[-1]'=>'$COL[-1] - Last column'
  520               }
  521         ), "\n",
  522       ),
  523 
  524   ); # end Tr
  525   print CGI::end_table();
  526 #############################################################################################
  527 # end upper table
  528 #############################################################################################
  529 
  530 # show merge file
  531 #         print  "<pre>",(map {$_ =~s/\s/\./g;$_}     map {sprintf('%-8.8s',$_);}  0..8),"</pre>";
  532 #     print  CGI::popup_menu(
  533 #             -name=>'dummyName2',
  534 #             -values=>\@merge_keys,
  535 #             -labels=>$rh_merge_data,
  536 #             -multiple=>1,
  537 #             -size    =>2,
  538 #
  539 #         ), "\n",CGI::br();
  540 #       warn "merge keys ", join( " ",@merge_keys);
  541 #############################################################################################
  542 # merge file fragment and message text area field
  543 #############################################################################################
  544     my @tmp2;
  545         eval{  @tmp2= @{$rh_merge_data->{ $db->getUser($preview_user)->student_id  }  };};
  546         if ($@) {
  547           print CGI::p( "Couldn't get merge data for $preview_user", CGI::br(), $@) ;
  548         } else {
  549       print CGI::pre("",data_format(0..($#tmp2)),"\n", data_format(@tmp2));
  550     }
  551 #create a textbox with the subject and a textarea with the message
  552 #print actual body of message
  553 
  554   print  "\n", CGI::p( $self->{message}) if defined($self->{message});
  555     print  "\n", CGI::p( CGI::textarea(-name=>'body', -default=>$text, -rows=>$rows, -columns=>$columns, -override=>1));
  556 
  557 #############################################################################################
  558 # action button table
  559 #############################################################################################
  560   print    CGI::table( { -border=>2,-cellpadding=>4},
  561          CGI::Tr(
  562            CGI::td( CGI::submit(-name=>'action', -value=>'Send Email') ), "\n",
  563            CGI::td(CGI::submit(-name=>'action', -value=>'Save')," to $output_file"), " \n",
  564            CGI::td(CGI::submit(-name=>'action', -value=>'Save as:'),
  565                    CGI::textfield(-name=>'savefilename', -size => 20, -value=> "$output_file", -override=>1)
  566            ), "\n",
  567            CGI::td(CGI::submit(-name=>'action', -value=>'Save as Default')),
  568         )
  569   );
  570 
  571 ##############################################################################################################
  572 
  573   print CGI::end_form();
  574   return "";
  575 }
  576 
  577 ##############################################################################
  578 # Utility methods
  579 ##############################################################################
  580 sub submission_error {
  581   my $self = shift;
  582     my $msg = join( " ", @_);
  583   $self->{submitError}= $msg; #CGI::b(HTML::Entities::encode($msg));
  584 #     qq{Please hit the &quot;<B>Back</B>&quot; button on your browser to
  585 #     try again, or notify your web master
  586 #     if you believe this message is in error.
  587 #     };
  588     return;
  589 }
  590 
  591 sub saveProblem {
  592     my $self      = shift;
  593   my ($body, $probFileName)= @_;
  594   local(*PROBLEM);
  595   open (PROBLEM, ">$probFileName") ||
  596     $self->submission_error("Could not open $probFileName for writing.
  597     Check that the  permissions for this problem are 660 (-rw-rw----)");
  598   print PROBLEM $body;
  599   close PROBLEM;
  600   chmod 0660, "$probFileName" ||
  601                $self->submission_error("
  602                       CAN'T CHANGE PERMISSIONS ON FILE $probFileName");
  603 }
  604 
  605 sub read_input_file {
  606   my $self         = shift;
  607   my $filePath     = shift;
  608   my ($text, @text);
  609   my $header = '';
  610   my ($subject, $from, $replyTo);
  611   local(*FILE);
  612   if (-e "$filePath" and -r "$filePath") {
  613     open FILE, "$filePath" || do { $self->submission_error("Can't open $filePath"); return};
  614     while ($header !~ s/Message:\s*$//m and not eof(FILE)) {
  615       $header .= <FILE>;
  616     }
  617     $text = join( '', <FILE>);
  618     $text =~ s/^\s*//; # remove initial white space if any.
  619     $header         =~ /^From:\s(.*)$/m;
  620     $from           = $1 or $from = $self->{defaultFrom};
  621 
  622     $header         =~ /^Reply-To:\s(.*)$/m;
  623     $replyTo        = $1 or $replyTo = $self->{defaultReply};
  624 
  625     $header         =~ /^Subject:\s(.*)$/m;
  626     $subject        = $1;
  627 
  628   } else {
  629     $from           = $self->{defaultFrom};
  630     $replyTo        = $self->{defaultReply};
  631     $text           =  (-e "$filePath") ? "FIXME file $filePath can't be read" :"FIXME file $filePath doesn't exist";
  632     $subject        = "FIXME default subject";
  633   }
  634   return ($from, $replyTo, $subject, \$text);
  635 }
  636 
  637 sub get_message_file_names {
  638   my $self             = shift;
  639   my $emailDirectory   = $self->{ce}->{courseDirs}->{email};
  640   #get all message files and create a list
  641   local(*EMAILDIR);
  642   opendir( EMAILDIR, $emailDirectory )|| die "Can't access directory $emailDirectory. Please check that webserver has permission to read this directory.";
  643     my @messageFiles = grep /\.msg$/, readdir EMAILDIR; #all message files
  644   closedir EMAILDIR;
  645 
  646   return sort @messageFiles;
  647 }
  648 sub get_merge_file_names {
  649   my $self             = shift;
  650   my $scoringDirectory   = $self->{ce}->{courseDirs}->{scoring};
  651   #get all message files and create a list
  652   local(*SCORINGDIR);
  653   opendir( SCORINGDIR, $scoringDirectory )|| die "Can't access directory $scoringDirectory.",
  654                                              "Please check that webserver has permission to read this directory.";
  655   my @mergeFiles = grep( /\.csv$/, readdir SCORINGDIR); #all message files
  656   closedir SCORINGDIR;
  657   @mergeFiles    = sort @mergeFiles;
  658 # warn "FIXME scoring directory $scoringDirectory merge Files", join(" ", @mergeFiles);
  659   unshift(@mergeFiles, 'None');
  660   return @mergeFiles;
  661 }
  662 
  663 sub read_merge_file    {
  664   my $self            = shift;
  665   my $fileName        = shift;
  666   my $delimiter       = shift;
  667   $delimiter          = ',' unless defined($delimiter);
  668   my $scoringDirectory= $self->{ce}->{courseDirs}->{scoring};
  669   my $filePath        = "$scoringDirectory/$fileName";
  670         #       Takes a delimited file as a parameter and returns an
  671         #       associative array with the first field as the key.
  672         #       Blank lines are skipped. White space is removed
  673     my(@dbArray,$key,$dbString);
  674     my %assocArray = ();
  675     return
  676     local(*FILE);
  677     if ($fileName eq 'None') {
  678       # do nothing
  679     }elsif ( open(FILE, "$filePath")  )   {
  680     my $index=0;
  681     while (<FILE>){
  682       unless ($_ =~ /\S/)  {next;}               ## skip blank lines
  683       chomp;
  684       @{$dbArray[$index]} =$self->getRecord($_,$delimiter);
  685       $key    =$dbArray[$index][0];
  686       #@dbArray    =  map {$_ =~s/\s/\./g;$_}     map {sprintf('%-8.8s',$_);}  @dbArray;
  687       #$dbString   = join(" | ",@dbArray);
  688       $assocArray{$key}=$dbArray[$index];
  689       $index++;
  690     }
  691     close(FILE);
  692      } else {
  693       warn "Couldn't read file $filePath";
  694      }
  695      return \%assocArray;
  696 }
  697 sub getRecord {
  698   my $self    = shift;
  699   my $line    = shift;
  700   my $delimiter   = shift;
  701   $delimiter       = ',' unless defined($delimiter);
  702 
  703         #       Takes a delimited line as a parameter and returns an
  704         #       array.  Note that all white space is removed.  If the
  705         #       last field is empty, the last element of the returned
  706         #       array is also empty (unlike what the perl split command
  707         #       would return).  E.G. @lineArray=&getRecord(\$delimitedLine).
  708 
  709         my(@lineArray);
  710         $line.=$delimiter;                              # add 'A' to end of line so that
  711                                                         # last field is never empty
  712         @lineArray = split(/\s*${delimiter}\s*/,$line);
  713         $lineArray[0] =~s/^\s*//;                       # remove white space from first element
  714         @lineArray;
  715 }
  716 
  717 sub process_message {
  718   my $self          = shift;
  719   my $ur            = shift;
  720   my $rh_merge_data = shift;
  721   my $text          = defined($self->{r_text}) ? ${ $self->{r_text} }:
  722                           'FIXME no text was produced by initialization!!';
  723   #user macros that can be used in the email message
  724   my $SID           = $ur->student_id;
  725   my $FN            = $ur->first_name;
  726   my $LN            = $ur->last_name;
  727   my $SECTION       = $ur->section;
  728   my $RECITATION    = $ur->recitation;
  729   my $STATUS        = $ur->status;
  730   my $EMAIL         = $ur->email_address;
  731   my $LOGIN         = $ur->user_id;
  732   # get record from merge file
  733   # FIXME this is inefficient.  The info should be cached
  734   my @COL            = defined($rh_merge_data->{$SID}) ? @{$rh_merge_data->{$SID} } : ();
  735   $self->submission_error( "No merge data for $SID $FN $LN $LOGIN") unless defined($rh_merge_data->{$SID});
  736 
  737   my $endCol = @COL;
  738   # for safety, only evaluate special variables
  739   my $msg = $text;
  740   $msg =~ s/(\$SID)/eval($1)/ge;
  741   $msg =~ s/(\$LN)/eval($1)/ge;
  742   $msg =~ s/(\$FN)/eval($1)/ge;
  743   $msg =~ s/(\$STATUS)/eval($1)/ge;
  744   $msg =~ s/(\$SECTION)/eval($1)/ge;
  745   $msg =~ s/(\$RECITATION)/eval($1)/ge;
  746   $msg =~ s/(\$EMAIL)/eval($1)/ge;
  747   $msg =~ s/(\$LOGIN)/eval($1)/ge;
  748   $msg =~ s/\$COL\[ *-/\$COL\[$endCol-/g;
  749   $msg =~ s/(\$COL\[.*?\])/eval($1)/ge;
  750 
  751   $msg =~ s/\r//g;
  752 
  753   my $preview_header =  CGI::pre("",data_format(0..($#COL)),"\n", data_format(@COL)).
  754                         CGI::h3( "This sample mail would be sent to $EMAIL");
  755 
  756 
  757   return $msg, $preview_header;
  758 }
  759  sub data_format {
  760   map {$_ =~s/\s/\./g;$_}     map {sprintf('%-8.8s',$_);}  @_;
  761  }
  762 1;

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9