--- loncom/interface/printout.pl 2004/09/09 15:30:49 1.69 +++ loncom/interface/printout.pl 2005/05/02 22:59:11 1.78 @@ -1,7 +1,7 @@ #!/usr/bin/perl # CGI-script to run LaTeX, dvips, ps2ps, ps2pdf etc. # -# $Id: printout.pl,v 1.69 2004/09/09 15:30:49 matthew Exp $ +# $Id: printout.pl,v 1.78 2005/05/02 22:59:11 albertel Exp $ # # Copyright Michigan State University Board of Trustees # @@ -27,17 +27,156 @@ # use lib '/home/httpd/lib/perl'; -use LONCAPA::loncgi(); +use LONCAPA::loncgi; use File::Path; use IO::File; use Image::Magick; use Apache::lonhtmlcommon; +use Apache::lonnet(); use Apache::loncommon; use Apache::lonlocal; +use Apache::lonmsg; +use LONCAPA::Enrollment; use strict; + +# Get the list of course coordinators authorized on this course: +#Parameters: +# id - Course id. +# dom - Domain of course. +#Returns: +# A (possibly empty) list of course coordinators. Each course coordinator +# is given as user:domain +# +sub get_cc_list { + my ($id, $dom) = @_; + my @personel = &Apache::lonnet::getkeys('nohist_userroles', $dom, $id); + my @coordinators; + foreach my $person (@personel) { + my @info = split(/:/, $person); + my $role = $info[0]; + my $user = $info[1]; + my $udom = $info[2]; + if ($role eq 'cc') { + my $isactive = &LONCAPA::Enrollment::check_user_status($udom, $user, $dom, $id, 'cc'); + if ($isactive eq 'ok') { + push @coordinators, $user.':'.$udom; + } + } + } + return (@coordinators); +} +# +# Determine if a user is operating as a student for this course/domain. +# +# +#Parameters: +# course - The course id. +# cdom - The course domain. +# +#Implicit: +# $env{request.role} contains the role under which this user operated this +# this request. +sub is_student { + my ($course, $cdom) = @_; + my $active_role = $env{'request.role'}; + my @role_fields = split(/\//, $active_role); + + + if ( ($role_fields[0] eq 'st.') && ($role_fields[1] eq $cdom) && + ($role_fields[2] eq $course)) { + return 1; + } else { + return 0; + } + + +} + +# +# Debugging: Dump the environment for debugging. +# +sub dumpenv { + print "

-------------------

"; + foreach my $key (sort (keys %env)) { + print "
$key -> $env{$key}"; + } + print "

-------------------

"; +} + +# +# This sub sends a message to the appropriate person if there was an error +# rendering the latex At present, there's only one case to consider: +# a student printing inside a course results in messages to the course coordinator. +#Parmaeters: +# identifier - The unique identifier of this cgi request. +# logfile - The contents of the log file (included in the message). +# texfile - reference to an array containing the LaTeX input file +# (included in the message). +#Implicit inputs: +# From the environment: +# cgi.$identifier.user - User doing the printing. +# cgi.$identifier.domain - Domain the user is logged in on with printing. +# cgi.$identifier.courseid - Id of the course (if this is a course). +# cgi.$identifier.coursedom- Domain in which course was constituted. +# cgi.$identifier.resources - List of resource URL's for which the print +# was attempted. +# +sub send_error_mail { + my ($identifier,$logfile, $texfile) = @_; + my $user = $env{"cgi.$identifier.user"}; + my $domain = $env{"cgi.$identifier.domain"}; + my $courseid = $env{"cgi.$identifier.courseid"}; + my $coursedom= $env{"cgi.$identifier.coursedom"}; + my $resources= $env{"cgi.$identifier.resources"}; + + # &dumpenv(); + + + + # Only continue if there is a user, domain, courseid, course domain + # and resources: + + if(defined($user) && defined($domain) && defined($courseid) && + defined($coursedom) && defined($resources) ){ + + my @cclist = &get_cc_list($courseid, $coursedom); + + # Only mail if the conditions are ripe for it: + # The user is a student in the course: + # + + if (&is_student( $courseid, $coursedom)) { + # build the subject and message body: + print "sending message to course coordinators.
"; + + my $subject = "Print failed for $user".'@'.$domain; + my $message .= "Print failed to render LaTeX for $user".'@'."$domain\n"; + $message .= " User was attempting to print: \n"; + $message .= " $resources\n"; + $message .= "--------------------LaTeX logfile:------------ \n"; + $message .= $logfile; + $message .= "-----------------LaTeX source file: ------------\n"; + + foreach my $line (@$texfile) { + $message .= "$line\n"; + } + foreach my $dest (@cclist) { + my @destinfo = split(/:/,$dest); + my $user = $destinfo[0]; + my $dom = $destinfo[1]; + + &Apache::lonmsg::user_normal_msg($user, $dom, + $subject, $message); + + # No point in looking at the return status as there's no good + # error action I can think of right now (log maybe?). + } + } + } +} + $|=1; -my %origENV=%ENV; if (! &LONCAPA::loncgi::check_cookie_and_load_env()) { print <new($figfile) || die "Couldn't open fig file $figfile for reading: $!\n"; my @content_of_file = <$temporary_file>; @@ -95,7 +234,9 @@ END foreach my $not_eps (@content_of_file) { chomp($not_eps); if ($not_eps ne '') { + # print "Converting $not_eps"; # Debugging. my $status_statement='EPS picture for '.$not_eps; + # print "$status_statement\n"; $not_eps=~s|\/\.\/|\/|g; my $eps_f = $not_eps; $eps_f =~ s/\.[^.]*$/\.eps/i; @@ -109,26 +250,24 @@ END $eps_f=~/$Apache::lonnet::perlvar{'lonUsersDir'}\/([^\/]+)\/\w\/\w\/\w\/(.+)/; $eps_f = '/home/httpd/prtspool/'.$1.'/'.$2; } + $eps_f =~ s/ /\_/g; # Spaces are problematic for system commands and LaTeX. my $path=$eps_f; - $path=~s/\/([^\/]+)\.eps$//; + $path =~ s/\/([^\/]+)\.eps$//; + # print "Final file path: $path "; # Debugging File::Path::mkpath($path,0,0777); - my $image = Image::Magick->new; $not_eps =~ s/^\s+//; $not_eps =~ s/\s+$//; - if ( exists($done_conversion{$not_eps})) { - next; - } + $not_eps =~ s/ /\\ /g; + if ( exists($done_conversion{$not_eps})) { next; } if ($adv) { my $prettyname=$not_eps; $prettyname=~s|/home/([^/]+)/public_html|/priv/$1|; $prettyname=~s|$Apache::lonnet::perlvar{'lonDocRoot'}/|/|; - &Apache::lonhtmlcommon::Update_PrgWin('',\%prog_state,'Converting to EPS '.$prettyname); } + &Apache::lonhtmlcommon::Update_PrgWin('',\%prog_state,'Converting to EPS '.$prettyname); + } $done_conversion{$not_eps}=1; - my $status = $image->Read($not_eps); - if ($status) {print " $status ";} - $image->Set(page => '+100+200'); - $status = $image->Write($eps_f); - if ($status) {print " $status ";} + # print "Converting $not_eps -> $eps_f"; # Debugging + system("convert $not_eps $eps_f"); #check is eps exist in prtspool if(not -e $eps_f) { for (my $i=0;$i<10000;$i++) { @@ -140,7 +279,9 @@ END } } } - if ($adv) { &Apache::lonhtmlcommon::Close_PrgWin('',\%prog_state); } + if ($adv) { + &Apache::lonhtmlcommon::Close_PrgWin('',\%prog_state); + } unlink($figfile); } #print "$texfile\n"; #name of the tex file for debugging only @@ -226,7 +367,7 @@ foreach $texfile (@texfile) { if ($whereitbegins!=-1 and $whereitends!=-1) { print "With very high probability this error occured in ".substr($body_log_file,$whereitbegins+26,$whereitends-$whereitbegins-26)."

"; } - print "Here are the error messages in the LaTeX log file

"; + print "Here are the error messages in the LaTeX log file

";
 	  my $sygnal = 0;
 	  for (my $i=0;$i<=$#content_of_file;$i++) {
 	      if ($content_of_file[$i]=~m/^Runaway argument?/ or $content_of_file[$i]=~m/^!/) {
@@ -236,10 +377,12 @@ foreach $texfile (@texfile) {
 		  $sygnal = 0;
 	      } 
 	      if ($sygnal) {
-		  print "$content_of_file[$i]
"; + print "$content_of_file[$i]"; } } - if ($advans_role) { + print "
\n"; + if ($advanced_role) { + print "

Advanced role

"; print "The link to "; $logfilename=~s/\/home\/httpd//; print "Your log file "; @@ -257,6 +400,15 @@ foreach $texfile (@texfile) { $texfile=~s/\/home\/httpd//; print "Your original LaTeX file "; print "\n"; + } else { # Student role... + # at this point: + # $body_log_file - contains the log file. + # $name_file - is the name of the LaTeX file. + # $identifier - is the unique LaTeX identifier.l + + my $tex_handle = IO::File->new($name_file); + my @tex_contents = <$tex_handle>; + &send_error_mail($identifier, $body_log_file, \@tex_contents); } } elsif ($body_log_file=~m//) { @@ -318,26 +470,26 @@ foreach $texfile (@texfile) { # unlink @garb; unlink $duefile; print "Your PDF document"; - if ($advans_role) { - print "

"; - print "The link to "; - $logfilename=~s/\/home\/httpd//; - print "Your log file "; - print "\n"; - #link tooriginal LaTeX file (included according Michael Hamlin desire) - my $tex_temporary_file=IO::File->new($texfile) || die "Couldn't open tex file $texfile for reading: $!\n"; - my @tex_content_of_file = <$tex_temporary_file>; - close $tex_temporary_file; - my $body_tex_file = join(' ',@tex_content_of_file); - $texfile =~ s/\.tex$/aaaaa\.html/; - $tex_temporary_file = IO::File->new('>'.$texfile); - print $tex_temporary_file 'LOGFILE
'.$body_tex_file.'
'."\n"; - print "

"; - print "The link to "; - $texfile=~s/\/home\/httpd//; - print "Your original LaTeX file "; - print "\n"; - } + } + if ($advanced_role) { + print "

"; + print "The link to "; + $logfilename=~s/\/home\/httpd//; + print "Your log file "; + print "\n"; + #link tooriginal LaTeX file (included according Michael Hamlin desire) + my $tex_temporary_file=IO::File->new($texfile) || die "Couldn't open tex file $texfile for reading: $!\n"; + my @tex_content_of_file = <$tex_temporary_file>; + close $tex_temporary_file; + my $body_tex_file = join(' ',@tex_content_of_file); + $texfile =~ s/\.tex$/aaaaa\.html/; + $tex_temporary_file = IO::File->new('>'.$texfile); + print $tex_temporary_file 'LOGFILE
'.$body_tex_file.'
'."\n"; + print "

"; + print "The link to "; + $texfile=~s/\/home\/httpd//; + print "Your original LaTeX file "; + print "\n"; } } else { #LaTeX successfully parsed tex file