[system] / trunk / webwork2 / lib / WeBWorK / Utils.pm Repository:
ViewVC logotype

View of /trunk/webwork2/lib/WeBWorK/Utils.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 979 - (download) (as text) (annotate)
Mon Jun 2 22:28:08 2003 UTC (9 years, 11 months ago) by malsyned
File size: 6099 byte(s)
Fix max in Util.pm
did some UI refactoring.
-Dennis

    1 ################################################################################
    2 # WeBWorK mod_perl (c) 2000-2002 WeBWorK Project
    3 # $Id$
    4 ################################################################################
    5 
    6 package WeBWorK::Utils;
    7 use base qw(Exporter);
    8 
    9 =head1 NAME
   10 
   11 WeBWorK::Utils - useful utilities used by other WeBWorK modules.
   12 
   13 =cut
   14 
   15 use strict;
   16 use warnings;
   17 use Date::Format;
   18 use Date::Parse;
   19 
   20 our @EXPORT    = ();
   21 our @EXPORT_OK = qw(
   22   runtime_use
   23   readFile
   24   formatDateTime
   25   parseDateTime
   26   writeLog
   27   writeTimingLogEntry
   28   list2hash
   29   max
   30   readDirectory
   31   dbDecode
   32   dbEncode
   33   decodeAnswers
   34   encodeAnswers
   35   ref2string
   36   dequoteHere
   37   wrapText
   38 );
   39 
   40 sub runtime_use($) {
   41   return unless @_;
   42   eval "package Main; require $_[0]; import $_[0]";
   43   die $@ if $@;
   44 }
   45 
   46 sub readFile($) {
   47   my $fileName = shift;
   48   local *INPUTFILE;
   49   open INPUTFILE, "<", $fileName
   50     or die "Failed to read $fileName: $!";
   51   local $/ = undef;
   52   my $result = <INPUTFILE>;
   53   close INPUTFILE;
   54   return $result;
   55 }
   56 
   57 sub readDirectory($) {
   58   my ($dirname) = @_;
   59 
   60   opendir my $dirhandle, $dirname or die "couldn't open directory $dirname: $!";
   61   my @contents = readdir $dirhandle;
   62   closedir $dirhandle;
   63   return @contents;
   64 }
   65 
   66 sub formatDateTime($) {
   67   my $dateTime = shift;
   68   # "standard" WeBWorK date/time format (for set definition files):
   69   # %m  month number, starting with 01
   70   # %d  numeric day of the month, with leading zeros (eg 01..31)
   71   # %y  year (2 digits)
   72   # %I  hour, 12 hour clock, leading 0's)
   73   # %M  minute, leading 0's
   74   # %P  am or pm (Yes %p and %P are backwards :)
   75   return time2str("%m/%d/%y %I:%M%P", $dateTime);
   76 }
   77 
   78 sub parseDateTime($) {
   79   my $string = shift;
   80   return str2time($string);
   81 }
   82 
   83 sub writeLog($$@) {
   84   my ($ce, $facility, @message) = @_;
   85   unless ($ce->{webworkFiles}->{logs}->{$facility}) {
   86     warn "There is no log file for the $facility facility defined.\n";
   87     return;
   88   }
   89   my $logFile = $ce->{webworkFiles}->{logs}->{$facility};
   90   local *LOG;
   91   if (open LOG, ">>", $logFile) {
   92     print LOG "[", time2str("%a %b %d %H:%M:%S %Y", time), "] @message\n";
   93     close LOG;
   94   } else {
   95     warn "failed to open $logFile for writing: $!";
   96   }
   97 }
   98 
   99 # $ce - a WeBWork::CourseEnvironment object
  100 # $function - fully qualified function name
  101 # $details - any information, do not use the characters '[' or ']'
  102 # $beginEnd - the string "begin", "intermediate", or "end"
  103 # use the intermediate step begun or completed for INTERMEDIATE
  104 # use an empty string for $details when calling for END
  105 sub writeTimingLogEntry($$$$) {
  106   my ($ce, $function, $details, $beginEnd) = @_;
  107   return unless defined $ce->{webworkFiles}->{logs}->{timing};
  108   $beginEnd = ($beginEnd eq "begin") ? ">" : ($beginEnd eq "end") ? "<" : "-";
  109   writeLog($ce, "timing", "$$ ".time." $beginEnd $function [$details]");
  110 }
  111 
  112 sub list2hash {
  113   map {$_ => "0"} @_;
  114 }
  115 
  116 sub max {
  117   my $soFar;
  118   foreach my $item (@_) {
  119     $soFar = $item unless defined $soFar;
  120     if ($item > $soFar) {
  121       $soFar = $item;
  122     }
  123   }
  124   return defined $soFar ? $soFar : 0;
  125 }
  126 
  127 # -----
  128 
  129 sub dbDecode($) {
  130   my $string = shift;
  131   return unless defined $string and $string;
  132   my %hash = $string =~ /(.*?)(?<!\\)=(.*?)(?:(?<!\\)&|$)/g;
  133   $hash{$_} =~ s/\\(&|=)/$1/g foreach keys %hash; # unescape & and =
  134   return %hash;
  135 }
  136 
  137 sub dbEncode(@) {
  138   my %hash = @_;
  139   my $string;
  140   foreach (keys %hash) {
  141     $hash{$_} = "" unless defined $hash{$_}; # promote undef to ""
  142     $hash{$_} =~ s/(=|&)/\\$1/g; # escape & and =
  143     $string .= "$_=$hash{$_}&";
  144   }
  145   chop $string; # remove final '&' from string for old code :p
  146   return $string;
  147 }
  148 
  149 sub decodeAnswers($) {
  150   my $string = shift;
  151   return unless defined $string and $string;
  152   my @array = split m/##/, $string;
  153   $array[$_] =~ s/\\#\\/#/g foreach 0 .. $#array;
  154   push @array, "" if @array%2;
  155   return @array; # it's actually a hash ;)
  156 }
  157 
  158 sub encodeAnswers(\%\@) {
  159   my %hash = %{ shift() };
  160   my @order = @{ shift() };
  161   my $string;
  162   foreach my $name (@order) {
  163     my $value = defined $hash{$name} ? $hash{$name} : "";
  164     $name  =~ s/#/\\#\\/g; # this is a WEIRD way to escape things
  165     $value =~ s/#/\\#\\/g; # and it's not my fault!
  166     $string .= "$name##$value##"; # this is also not my fault
  167   }
  168   $string =~ s/##$//; # remove last pair of hashs
  169   return $string;
  170 }
  171 
  172 # -----
  173 
  174 sub ref2string($;$);
  175 sub ref2string($;$) {
  176   my $ref = shift;
  177   my $dontExpand = shift || {};
  178   my $refType = ref $ref;
  179   my $result;
  180   if ($refType and not $dontExpand->{$refType}) {
  181     my $baseType = refBaseType($ref);
  182     $result .= '<font size="1" color="grey">' . $refType;
  183     $result .= " ($baseType)" if $baseType and $refType ne $baseType;
  184     $result .= ":</font><br>";
  185     $result .= '<table border="1" cellpadding="2">';
  186     if ($baseType eq "HASH") {
  187       my %hash = %$ref;
  188       foreach (sort keys %hash) {
  189         $result .= '<tr valign="top">';
  190         $result .= "<td>$_</td>";
  191         $result .= "<td>" . ref2string($hash{$_}, $dontExpand) . "</td>";
  192         $result .= "</tr>";
  193       }
  194     } elsif ($baseType eq "ARRAY") {
  195       my @array = @$ref;
  196       # special case for Problem, Set, and User objects, which are defined
  197       # using lists and contain a @FIELDS package variable:
  198       no strict 'refs';
  199       my @FIELDS = eval { @{$refType."::FIELDS"} };
  200       use strict 'refs';
  201       undef @FIELDS unless scalar @FIELDS == scalar @array and not $@;
  202       foreach (0 .. $#array) {
  203         $result .= '<tr valign="top">';
  204         $result .= "<td>$_</td>";
  205         $result .= "<td>".$FIELDS[$_]."</td>" if @FIELDS;
  206         $result .= "<td>" . ref2string($array[$_], $dontExpand) . "</td>";
  207         $result .= "</tr>";
  208       }
  209     } elsif ($baseType eq "SCALAR") {
  210       my $scalar = $$ref;
  211       $result .= '<tr valign="top">';
  212       $result .= "<td>$scalar</td>";
  213       $result .= "</tr>";
  214     } else {
  215       # perhaps a coderef? in any case, i don't feel like dealing with it!
  216       $result .= '<tr valign="top">';
  217       $result .= "<td>$ref</td>";
  218       $result .= "</tr>";
  219     }
  220     $result .= "</table>"
  221   } else {
  222     $result .= defined $ref ? $ref : '<font color="red">undef</font>';
  223   }
  224 }
  225 
  226 sub refBaseType($) {
  227   my $ref = shift;
  228   local $SIG{__DIE__} = 'IGNORE';
  229   return "HASH"   if eval { $_ = %$ref; 1 };
  230   return "ARRAY"  if eval { $_ = @$ref; 1 };
  231   return "SCALAR" if eval { $_ = $$ref; 1 };
  232   return 0;
  233 }
  234 
  235 1;

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9