[system] / branches / rel-2-1-a1 / webwork2 / lib / WeBWorK / Utils.pm Repository:
ViewVC logotype

Annotation of /branches/rel-2-1-a1/webwork2/lib/WeBWorK/Utils.pm

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1095 - (view) (download) (as text)
Original Path: trunk/webwork2/lib/WeBWorK/Utils.pm

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 : malsyned 1045 use DB; # DeBug, not DataBase
20 : sh002i 412
21 : sh002i 410 our @EXPORT = ();
22 : sh002i 424 our @EXPORT_OK = qw(
23 :     runtime_use
24 : malsyned 1045 backtrace
25 : sh002i 424 readFile
26 :     formatDateTime
27 :     parseDateTime
28 : sh002i 562 writeLog
29 :     writeTimingLogEntry
30 : malsyned 970 list2hash
31 :     max
32 : malsyned 974 readDirectory
33 : sh002i 427 dbDecode
34 :     dbEncode
35 : sh002i 429 decodeAnswers
36 :     encodeAnswers
37 : sh002i 424 ref2string
38 : sh002i 646 dequoteHere
39 : sh002i 667 wrapText
40 : sh002i 424 );
41 : sh002i 410
42 :     sub runtime_use($) {
43 :     return unless @_;
44 : sh002i 424 eval "package Main; require $_[0]; import $_[0]";
45 : sh002i 410 die $@ if $@;
46 :     }
47 :    
48 : malsyned 1045 sub backtrace {
49 :     my ($style) = @_;
50 :     $style = "warn" unless $style;
51 :     my @bt = DB->backtrace;
52 :     shift @bt; # Remove "backtrace" from the backtrace;
53 :     if ($style eq "die") {
54 :     die join "\n", @bt;
55 :     } elsif ($style eq "warn") {
56 :     warn join "\n", @bt;
57 :     } elsif ($style eq "print") {
58 :     print join "\n", @bt;
59 :     } elsif ($style eq "return") {
60 :     return @bt;
61 :     }
62 :     }
63 :    
64 : sh002i 410 sub readFile($) {
65 :     my $fileName = shift;
66 : sh002i 558 local *INPUTFILE;
67 : sh002i 410 open INPUTFILE, "<", $fileName
68 :     or die "Failed to read $fileName: $!";
69 :     local $/ = undef;
70 :     my $result = <INPUTFILE>;
71 :     close INPUTFILE;
72 :     return $result;
73 :     }
74 : sh002i 412
75 : malsyned 974 sub readDirectory($) {
76 :     my ($dirname) = @_;
77 :    
78 :     opendir my $dirhandle, $dirname or die "couldn't open directory $dirname: $!";
79 :     my @contents = readdir $dirhandle;
80 :     closedir $dirhandle;
81 :     return @contents;
82 :     }
83 :    
84 : sh002i 412 sub formatDateTime($) {
85 :     my $dateTime = shift;
86 : sh002i 558 # "standard" WeBWorK date/time format (for set definition files):
87 : sh002i 412 # %m month number, starting with 01
88 :     # %d numeric day of the month, with leading zeros (eg 01..31)
89 :     # %y year (2 digits)
90 :     # %I hour, 12 hour clock, leading 0's)
91 :     # %M minute, leading 0's
92 :     # %P am or pm (Yes %p and %P are backwards :)
93 : sh002i 562 return time2str("%m/%d/%y %I:%M%P", $dateTime);
94 : sh002i 412 }
95 :    
96 :     sub parseDateTime($) {
97 : sh002i 424 my $string = shift;
98 : sh002i 737 return str2time($string);
99 : sh002i 412 }
100 : sh002i 422
101 : sh002i 562 sub writeLog($$@) {
102 :     my ($ce, $facility, @message) = @_;
103 :     unless ($ce->{webworkFiles}->{logs}->{$facility}) {
104 :     warn "There is no log file for the $facility facility defined.\n";
105 :     return;
106 :     }
107 :     my $logFile = $ce->{webworkFiles}->{logs}->{$facility};
108 :     local *LOG;
109 :     if (open LOG, ">>", $logFile) {
110 :     print LOG "[", time2str("%a %b %d %H:%M:%S %Y", time), "] @message\n";
111 :     close LOG;
112 :     } else {
113 :     warn "failed to open $logFile for writing: $!";
114 :     }
115 :     }
116 : sh002i 558
117 : sh002i 631 # $ce - a WeBWork::CourseEnvironment object
118 :     # $function - fully qualified function name
119 :     # $details - any information, do not use the characters '[' or ']'
120 : sh002i 692 # $beginEnd - the string "begin", "intermediate", or "end"
121 :     # use the intermediate step begun or completed for INTERMEDIATE
122 : sh002i 631 # use an empty string for $details when calling for END
123 : sh002i 562 sub writeTimingLogEntry($$$$) {
124 :     my ($ce, $function, $details, $beginEnd) = @_;
125 :     return unless defined $ce->{webworkFiles}->{logs}->{timing};
126 : sh002i 692 $beginEnd = ($beginEnd eq "begin") ? ">" : ($beginEnd eq "end") ? "<" : "-";
127 : sh002i 562 writeLog($ce, "timing", "$$ ".time." $beginEnd $function [$details]");
128 :     }
129 :    
130 : malsyned 970 sub list2hash {
131 :     map {$_ => "0"} @_;
132 :     }
133 :    
134 :     sub max {
135 :     my $soFar;
136 :     foreach my $item (@_) {
137 :     $soFar = $item unless defined $soFar;
138 :     if ($item > $soFar) {
139 :     $soFar = $item;
140 :     }
141 :     }
142 : malsyned 979 return defined $soFar ? $soFar : 0;
143 : malsyned 970 }
144 :    
145 : sh002i 429 # -----
146 :    
147 : sh002i 1095 #sub dbDecode($) {
148 :     # my $string = shift;
149 :     # return unless defined $string and $string;
150 :     # my %hash = $string =~ /(.*?)(?<!\\)=(.*?)(?:(?<!\\)&|$)/g;
151 :     # $hash{$_} =~ s/\\(&|=)/$1/g foreach keys %hash; # unescape & and =
152 :     # return %hash;
153 :     #}
154 :     #
155 :     #sub dbEncode(@) {
156 :     # my %hash = @_;
157 :     # my $string;
158 :     # foreach (keys %hash) {
159 :     # $hash{$_} = "" unless defined $hash{$_}; # promote undef to ""
160 :     # $hash{$_} =~ s/(=|&)/\\$1/g; # escape & and =
161 :     # $string .= "$_=$hash{$_}&";
162 :     # }
163 :     # chop $string; # remove final '&' from string for old code :p
164 :     # return $string;
165 :     #}
166 :     # moved to lib/WeBWorK/DB/Utils.pm
167 : sh002i 427
168 : sh002i 429 sub decodeAnswers($) {
169 :     my $string = shift;
170 :     return unless defined $string and $string;
171 :     my @array = split m/##/, $string;
172 :     $array[$_] =~ s/\\#\\/#/g foreach 0 .. $#array;
173 : sh002i 445 push @array, "" if @array%2;
174 : sh002i 429 return @array; # it's actually a hash ;)
175 :     }
176 :    
177 :     sub encodeAnswers(\%\@) {
178 :     my %hash = %{ shift() };
179 :     my @order = @{ shift() };
180 :     my $string;
181 :     foreach my $name (@order) {
182 :     my $value = defined $hash{$name} ? $hash{$name} : "";
183 :     $name =~ s/#/\\#\\/g; # this is a WEIRD way to escape things
184 :     $value =~ s/#/\\#\\/g; # and it's not my fault!
185 : sh002i 1095 if ($value =~ m/\\$/) {
186 :     # if the value ends with a backslash, string2hash will
187 :     # interpret that as a normal escape sequence (not part
188 :     # of the weird pound escape sequence) if the next
189 :     # character is &. So we have to protect against this.
190 :     # will adding a spcae at the end of the last answer
191 :     # hurt anything? i don't think so...
192 :     $value .= " ";
193 :     }
194 : sh002i 429 $string .= "$name##$value##"; # this is also not my fault
195 :     }
196 :     $string =~ s/##$//; # remove last pair of hashs
197 :     return $string;
198 :     }
199 :    
200 : sh002i 424 # -----
201 : sh002i 422
202 : sh002i 424 sub ref2string($;$);
203 :     sub ref2string($;$) {
204 :     my $ref = shift;
205 :     my $dontExpand = shift || {};
206 :     my $refType = ref $ref;
207 : sh002i 422 my $result;
208 : sh002i 424 if ($refType and not $dontExpand->{$refType}) {
209 :     my $baseType = refBaseType($ref);
210 :     $result .= '<font size="1" color="grey">' . $refType;
211 : sh002i 425 $result .= " ($baseType)" if $baseType and $refType ne $baseType;
212 : sh002i 424 $result .= ":</font><br>";
213 :     $result .= '<table border="1" cellpadding="2">';
214 :     if ($baseType eq "HASH") {
215 :     my %hash = %$ref;
216 :     foreach (sort keys %hash) {
217 :     $result .= '<tr valign="top">';
218 :     $result .= "<td>$_</td>";
219 :     $result .= "<td>" . ref2string($hash{$_}, $dontExpand) . "</td>";
220 :     $result .= "</tr>";
221 :     }
222 :     } elsif ($baseType eq "ARRAY") {
223 :     my @array = @$ref;
224 : sh002i 429 # special case for Problem, Set, and User objects, which are defined
225 :     # using lists and contain a @FIELDS package variable:
226 :     no strict 'refs';
227 :     my @FIELDS = eval { @{$refType."::FIELDS"} };
228 :     use strict 'refs';
229 :     undef @FIELDS unless scalar @FIELDS == scalar @array and not $@;
230 : sh002i 424 foreach (0 .. $#array) {
231 :     $result .= '<tr valign="top">';
232 :     $result .= "<td>$_</td>";
233 : sh002i 429 $result .= "<td>".$FIELDS[$_]."</td>" if @FIELDS;
234 : sh002i 424 $result .= "<td>" . ref2string($array[$_], $dontExpand) . "</td>";
235 :     $result .= "</tr>";
236 :     }
237 :     } elsif ($baseType eq "SCALAR") {
238 :     my $scalar = $$ref;
239 :     $result .= '<tr valign="top">';
240 :     $result .= "<td>$scalar</td>";
241 :     $result .= "</tr>";
242 : sh002i 422 } else {
243 : sh002i 424 # perhaps a coderef? in any case, i don't feel like dealing with it!
244 :     $result .= '<tr valign="top">';
245 :     $result .= "<td>$ref</td>";
246 :     $result .= "</tr>";
247 : sh002i 422 }
248 : sh002i 424 $result .= "</table>"
249 : sh002i 422 } else {
250 : sh002i 424 $result .= defined $ref ? $ref : '<font color="red">undef</font>';
251 :     }
252 : sh002i 422 }
253 :    
254 : sh002i 424 sub refBaseType($) {
255 :     my $ref = shift;
256 : sh002i 984 $ref =~ m/(\w+)\(/; # this might not be robust...
257 :     return $1;
258 : sh002i 422 }
259 :    
260 :     1;

aubreyja at gmail dot com
ViewVC Help
Powered by ViewVC 1.0.9