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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 970 - (view) (download) (as text)

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

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9