| … | |
… | |
| 9 | |
9 | |
| 10 | WeBWorK - Dispatch requests to the appropriate ContentGenerator. |
10 | WeBWorK - Dispatch requests to the appropriate ContentGenerator. |
| 11 | |
11 | |
| 12 | =cut |
12 | =cut |
| 13 | |
13 | |
|
|
14 | BEGIN { $main::VERSION = "2.0"; } |
|
|
15 | |
| 14 | use strict; |
16 | use strict; |
| 15 | use warnings; |
17 | use warnings; |
| 16 | use Apache::Constants qw(:common REDIRECT); |
18 | use Apache::Constants qw(:common REDIRECT DONE); |
| 17 | use Apache::Request; |
19 | use Apache::Request; |
| 18 | use WeBWorK::Authen; |
20 | use WeBWorK::Authen; |
| 19 | use WeBWorK::Authz; |
21 | use WeBWorK::Authz; |
| 20 | use WeBWorK::ContentGenerator::Feedback; |
22 | use WeBWorK::ContentGenerator::Feedback; |
|
|
23 | use WeBWorK::ContentGenerator::GatewayQuiz; |
| 21 | use WeBWorK::ContentGenerator::Hardcopy; |
24 | use WeBWorK::ContentGenerator::Hardcopy; |
|
|
25 | use WeBWorK::ContentGenerator::Instructor::Assigner; |
| 22 | use WeBWorK::ContentGenerator::Instructor::Index; |
26 | use WeBWorK::ContentGenerator::Instructor::Index; |
|
|
27 | use WeBWorK::ContentGenerator::Instructor::Index2; |
| 23 | use WeBWorK::ContentGenerator::Instructor::PGProblemEditor; |
28 | use WeBWorK::ContentGenerator::Instructor::PGProblemEditor; |
|
|
29 | use WeBWorK::ContentGenerator::Instructor::ProblemList; |
| 24 | use WeBWorK::ContentGenerator::Instructor::ProblemSetEditor; |
30 | use WeBWorK::ContentGenerator::Instructor::ProblemSetEditor; |
| 25 | use WeBWorK::ContentGenerator::Instructor::ProblemSetList; |
31 | use WeBWorK::ContentGenerator::Instructor::ProblemSetList; |
| 26 | use WeBWorK::ContentGenerator::Instructor::UserList; |
32 | use WeBWorK::ContentGenerator::Instructor::UserList; |
| 27 | use WeBWorK::ContentGenerator::Instructor::ProblemList; |
33 | use WeBWorK::ContentGenerator::Instructor::SendMail; |
| 28 | use WeBWorK::ContentGenerator::Instructor::UserList; |
34 | use WeBWorK::ContentGenerator::Instructor::ShowAnswers; |
|
|
35 | use WeBWorK::ContentGenerator::Instructor::Scoring; |
|
|
36 | use WeBWorK::ContentGenerator::Instructor::ScoringDownload; |
|
|
37 | use WeBWorK::ContentGenerator::Instructor::ScoringTotals; |
|
|
38 | use WeBWorK::ContentGenerator::Instructor::Stats; |
| 29 | use WeBWorK::ContentGenerator::Login; |
39 | use WeBWorK::ContentGenerator::Login; |
| 30 | use WeBWorK::ContentGenerator::Logout; |
40 | use WeBWorK::ContentGenerator::Logout; |
| 31 | use WeBWorK::ContentGenerator::Options; |
41 | use WeBWorK::ContentGenerator::Options; |
| 32 | use WeBWorK::ContentGenerator::Problem; |
42 | use WeBWorK::ContentGenerator::Problem; |
| 33 | use WeBWorK::ContentGenerator::ProblemSet; |
43 | use WeBWorK::ContentGenerator::ProblemSet; |
| 34 | use WeBWorK::ContentGenerator::GatewayQuiz; |
|
|
| 35 | use WeBWorK::ContentGenerator::ProblemSets; |
44 | use WeBWorK::ContentGenerator::ProblemSets; |
| 36 | use WeBWorK::ContentGenerator::Test; |
45 | use WeBWorK::ContentGenerator::Test; |
| 37 | use WeBWorK::CourseEnvironment; |
46 | use WeBWorK::CourseEnvironment; |
| 38 | use WeBWorK::DB; |
47 | use WeBWorK::DB; |
| 39 | |
48 | use WeBWorK::Timing; |
| 40 | #sub dispatch($) { |
|
|
| 41 | # print STDERR "Executing &WeBWorK::dispatch\n"; |
|
|
| 42 | # return DECLINED; |
|
|
| 43 | #} |
|
|
| 44 | #1; |
|
|
| 45 | #__END__ |
|
|
| 46 | |
49 | |
| 47 | sub dispatch($) { |
50 | sub dispatch($) { |
| 48 | my ($apache) = @_; |
51 | my ($apache) = @_; |
| 49 | my $r = Apache::Request->new($apache); |
52 | my $r = Apache::Request->new($apache); |
| 50 | # have to deal with unpredictable GET or POST data, and sift |
53 | # have to deal with unpredictable GET or POST data, and sift |
| … | |
… | |
| 65 | unless (substr($current_uri,-1) eq '/') { |
68 | unless (substr($current_uri,-1) eq '/') { |
| 66 | $r->header_out(Location => "$current_uri/" . ($args ? "?$args" : "")); |
69 | $r->header_out(Location => "$current_uri/" . ($args ? "?$args" : "")); |
| 67 | return REDIRECT; |
70 | return REDIRECT; |
| 68 | # *** any post data gets lost here -- fix that. |
71 | # *** any post data gets lost here -- fix that. |
| 69 | # (actually, it's not a problem, since all URLs generated |
72 | # (actually, it's not a problem, since all URLs generated |
| 70 | # from within the system have trailing slashes, and we don't |
73 | # from within the system have trailing slashes, and we don't |
| 71 | # need POST data from outside the system anyway!) |
74 | # need POST data from outside the system anyway!) |
| 72 | } |
75 | } |
| 73 | |
76 | |
| 74 | # Create the @components array, which contains the path specified in the URL |
77 | # Create the @components array, which contains the path specified in the URL |
| 75 | my($junk, @components) = split "/", $path_info; |
78 | my($junk, @components) = split "/", $path_info; |
| … | |
… | |
| 100 | # to be passed to content generators, when we clean this file up). |
103 | # to be passed to content generators, when we clean this file up). |
| 101 | my $db = WeBWorK::DB->new($ce); |
104 | my $db = WeBWorK::DB->new($ce); |
| 102 | |
105 | |
| 103 | ### Begin dispatching ### |
106 | ### Begin dispatching ### |
| 104 | |
107 | |
|
|
108 | #my $dispatchTimer = WeBWorK::Timing->new(__PACKAGE__."::dispatch"); |
|
|
109 | #$dispatchTimer->start; |
|
|
110 | |
|
|
111 | my $result; |
| 105 | # WeBWorK::Authen::verify erases the passwd field and sets the key field |
112 | # WeBWorK::Authen::verify erases the passwd field and sets the key field |
| 106 | # if login is successful. |
113 | # if login is successful. |
| 107 | if (!WeBWorK::Authen->new($r, $ce, $db)->verify) { |
114 | if (!WeBWorK::Authen->new($r, $ce, $db)->verify) { |
| 108 | return WeBWorK::ContentGenerator::Login->new($r, $ce, $db)->go; |
115 | $result = WeBWorK::ContentGenerator::Login->new($r, $ce, $db)->go; |
| 109 | } else { |
116 | } else { |
| 110 | # After we are authenticated, there are some things that need to be |
117 | # After we are authenticated, there are some things that need to be |
| 111 | # sorted out, Authorization-wize, before we start dispatching to individual |
118 | # sorted out, Authorization-wize, before we start dispatching to individual |
| 112 | # content generators. |
119 | # content generators. |
| 113 | my $user = $r->param("user"); |
120 | my $user = $r->param("user"); |
| … | |
… | |
| 116 | $effectiveUser = $user unless $su_authorized; |
123 | $effectiveUser = $user unless $su_authorized; |
| 117 | $r->param("effectiveUser", $effectiveUser); |
124 | $r->param("effectiveUser", $effectiveUser); |
| 118 | |
125 | |
| 119 | my $arg = shift @components; |
126 | my $arg = shift @components; |
| 120 | if (!defined $arg) { # We want the list of problem sets |
127 | if (!defined $arg) { # We want the list of problem sets |
| 121 | return WeBWorK::ContentGenerator::ProblemSets->new($r, $ce, $db)->go; |
128 | $result = WeBWorK::ContentGenerator::ProblemSets->new($r, $ce, $db)->go; |
| 122 | } elsif ($arg eq "hardcopy") { |
129 | } elsif ($arg eq "hardcopy") { |
|
|
130 | |
| 123 | my $hardcopyArgument = shift @components; |
131 | my $hardcopyArgument = shift @components; |
| 124 | $hardcopyArgument = "" unless defined $hardcopyArgument; |
132 | $hardcopyArgument = "" unless defined $hardcopyArgument; |
|
|
133 | $WeBWorK::timer1 = WeBWorK::Timing->new("hardcopy: $hardcopyArgument"); |
|
|
134 | $WeBWorK::timer1->start; |
|
|
135 | |
| 125 | return WeBWorK::ContentGenerator::Hardcopy->new($r, $ce, $db)->go($hardcopyArgument); |
136 | my $result = WeBWorK::ContentGenerator::Hardcopy->new($r, $ce, $db)->go($hardcopyArgument); |
|
|
137 | $WeBWorK::timer1 ->stop; |
|
|
138 | $WeBWorK::timer1 ->save; |
|
|
139 | return $result; |
|
|
140 | } elsif ($arg eq "instructor2") { |
|
|
141 | my $instructorArgument = shift @components; |
|
|
142 | if (!defined $instructorArgument) { |
|
|
143 | $result = WeBWorK::ContentGenerator::Instructor::Index2->new($r, $ce, $db)->go; |
|
|
144 | } |
| 126 | } elsif ($arg eq "instructor") { |
145 | } elsif ($arg eq "instructor") { |
| 127 | my $instructorArgument = shift @components; |
146 | my $instructorArgument = shift @components; |
| 128 | if (!defined $instructorArgument) { |
147 | if (!defined $instructorArgument) { |
| 129 | return WeBWorK::ContentGenerator::Instructor::Index->new($r, $ce, $db)->go; |
148 | $result = WeBWorK::ContentGenerator::Instructor::Index->new($r, $ce, $db)->go; |
|
|
149 | } elsif ($instructorArgument eq "scoring") { |
|
|
150 | $result = WeBWorK::ContentGenerator::Instructor::Scoring->new($r, $ce, $db)->go; #FIXME!!!! |
|
|
151 | } elsif ($instructorArgument eq "scoringDownload") { |
|
|
152 | $result = WeBWorK::ContentGenerator::Instructor::ScoringDownload->new($r, $ce, $db)->go; |
|
|
153 | } elsif ($instructorArgument eq "scoring_totals") { |
|
|
154 | $result = WeBWorK::ContentGenerator::Instructor::ScoringTotals->new($r, $ce, $db)->go; |
| 130 | } elsif ($instructorArgument eq "users") { |
155 | } elsif ($instructorArgument eq "users") { |
| 131 | return WeBWorK::ContentGenerator::Instructor::UserList->new($r, $ce, $db)->go; |
156 | $result = WeBWorK::ContentGenerator::Instructor::UserList->new($r, $ce, $db)->go; |
| 132 | } elsif ($instructorArgument eq "sets") { |
157 | } elsif ($instructorArgument eq "sets") { |
| 133 | my $setID = shift @components; |
158 | my $setID = shift @components; |
| 134 | if (defined $setID) { |
159 | if (defined $setID) { |
| 135 | my $setArg = shift @components; |
160 | my $setArg = shift @components; |
| 136 | if (!defined $setArg) { |
161 | if (!defined $setArg) { |
| 137 | return WeBWorK::ContentGenerator::Instructor::ProblemSetEditor->new($r, $ce, $db)->go($setID); |
162 | $result = WeBWorK::ContentGenerator::Instructor::ProblemSetEditor->new($r, $ce, $db)->go($setID); |
| 138 | } elsif ($setArg eq "problems") { |
163 | } elsif ($setArg eq "problems") { |
| 139 | return WeBWorK::ContentGenerator::Instructor::ProblemList->new($r, $ce, $db)->go($setID); |
164 | $result = WeBWorK::ContentGenerator::Instructor::ProblemList->new($r, $ce, $db)->go($setID); |
| 140 | } elsif ($setArg eq "users") { |
165 | } elsif ($setArg eq "users") { |
| 141 | return WeBWorK::ContentGenerator::Instructor::UserList->new($r, $ce, $db)->go($setID); |
166 | $result = WeBWorK::ContentGenerator::Instructor::Assigner->new($r, $ce, $db)->go($setID); |
| 142 | } |
167 | } |
| 143 | } else { |
168 | } else { |
| 144 | return WeBWorK::ContentGenerator::Instructor::ProblemSetList->new($r, $ce, $db)->go; |
169 | $result = WeBWorK::ContentGenerator::Instructor::ProblemSetList->new($r, $ce, $db)->go; |
| 145 | } |
170 | } |
| 146 | } elsif ($instructorArgument eq "pgProblemEditor") { |
171 | } elsif ($instructorArgument eq "pgProblemEditor") { |
| 147 | return WeBWorK::ContentGenerator::Instructor::PGProblemEditor->new($r, $ce, $db)->go(@components); |
172 | $result = WeBWorK::ContentGenerator::Instructor::PGProblemEditor->new($r, $ce, $db)->go(@components); |
|
|
173 | } elsif ($instructorArgument eq "send_mail") { |
|
|
174 | $result = WeBWorK::ContentGenerator::Instructor::SendMail->new($r, $ce, $db)->go(@components); |
|
|
175 | } elsif ($instructorArgument eq "show_answers") { |
|
|
176 | $result = WeBWorK::ContentGenerator::Instructor::ShowAnswers->new($r, $ce, $db)->go(@components); |
|
|
177 | } elsif ($instructorArgument eq "stats") { |
|
|
178 | $result = WeBWorK::ContentGenerator::Instructor::Stats->new($r, $ce, $db)->go(@components); |
| 148 | } |
179 | } |
| 149 | } elsif ($arg eq "options") { |
180 | } elsif ($arg eq "options") { |
| 150 | return WeBWorK::ContentGenerator::Options->new($r, $ce, $db)->go; |
181 | $result = WeBWorK::ContentGenerator::Options->new($r, $ce, $db)->go; |
| 151 | } elsif ($arg eq "feedback") { |
182 | } elsif ($arg eq "feedback") { |
| 152 | return WeBWorK::ContentGenerator::Feedback->new($r, $ce, $db)->go; |
183 | $result = WeBWorK::ContentGenerator::Feedback->new($r, $ce, $db)->go; |
| 153 | } elsif ($arg eq "logout") { |
184 | } elsif ($arg eq "logout") { |
| 154 | return WeBWorK::ContentGenerator::Logout->new($r, $ce, $db)->go; |
185 | $result = WeBWorK::ContentGenerator::Logout->new($r, $ce, $db)->go; |
| 155 | } elsif ($arg eq "test") { |
186 | } elsif ($arg eq "test") { |
| 156 | return WeBWorK::ContentGenerator::Test->new($r, $ce, $db)->go; |
187 | $result = WeBWorK::ContentGenerator::Test->new($r, $ce, $db)->go; |
| 157 | } elsif ($arg eq "quiz_mode" ) { |
188 | } elsif ($arg eq "quiz_mode" ) { |
| 158 | # Gateway quiz capability -- very similar to problem set (initially) |
189 | # Gateway quiz capability -- very similar to problem set (initially) |
| 159 | return WeBWorK::ContentGenerator::GatewayQuiz->new($r, $ce, $db)->go(@components); |
190 | $result = WeBWorK::ContentGenerator::GatewayQuiz->new($r, $ce, $db)->go(@components); |
| 160 | } else { # We've got the name of a problem set. |
191 | } else { # We've got the name of a problem set. |
| 161 | my $problem_set = $arg; |
192 | my $problem_set = $arg; |
| 162 | my $ps_arg = shift @components; |
193 | my $ps_arg = shift @components; |
| 163 | |
194 | |
| 164 | if (!defined $ps_arg) { |
195 | if (!defined $ps_arg) { |
| 165 | # list the problems in the problem set |
196 | # list the problems in the problem set |
|
|
197 | $WeBWorK::timer0 = WeBWorK::Timing->new("Problem $course:$problem_set"); |
|
|
198 | $WeBWorK::timer0->start; |
| 166 | return WeBWorK::ContentGenerator::ProblemSet->new($r, $ce, $db)->go($problem_set); |
199 | $result = WeBWorK::ContentGenerator::ProblemSet->new($r, $ce, $db)->go($problem_set); |
|
|
200 | $WeBWorK::timer0->continue("problem set listing is done"); |
|
|
201 | $WeBWorK::timer0->stop; |
|
|
202 | $WeBWorK::timer0->save; |
| 167 | } else { |
203 | } else { |
| 168 | # We've got the name of a problem |
204 | # We've got the name of a problem |
| 169 | my $problem = $ps_arg; |
205 | my $problem = $ps_arg; |
|
|
206 | |
|
|
207 | $WeBWorK::timer0 = WeBWorK::Timing->new("Problem $course:$problem_set/$problem"); |
|
|
208 | $WeBWorK::timer0->start; |
|
|
209 | # my $pid = fork(); |
|
|
210 | # if ($pid) { |
|
|
211 | # wait; |
|
|
212 | # } else { |
| 170 | return WeBWorK::ContentGenerator::Problem->new($r, $ce, $db)->go($problem_set, $problem); |
213 | my $result = WeBWorK::ContentGenerator::Problem->new($r, $ce, $db)->go($problem_set, $problem); |
|
|
214 | # $WeBWorK::timer0->continue("Exiting child process"); |
|
|
215 | # #$WeBWorK::timer0->stop; |
|
|
216 | # #$WeBWorK::timer0->save; |
|
|
217 | # eval{ APACHE::exit(0);} || warn "Error in leaving child |$@|"; |
|
|
218 | # # We REALLY REALLY want this grandchild to exit. But not the child. How to do this |
|
|
219 | # # cleanly???? FIXME |
|
|
220 | # } |
|
|
221 | $WeBWorK::timer0->continue("Problem done)"); |
|
|
222 | $WeBWorK::timer0->stop; |
|
|
223 | $WeBWorK::timer0->save; |
|
|
224 | return $result; |
|
|
225 | |
|
|
226 | |
| 171 | } |
227 | } |
| 172 | } |
228 | } |
| 173 | |
|
|
| 174 | } |
229 | } |
| 175 | |
230 | |
| 176 | # If the dispatcher doesn't know any modules that want to handle |
231 | #$dispatchTimer->stop; |
| 177 | # the current path, it'll claim that the path does not exist by |
232 | |
| 178 | # declining the request. |
233 | return $result; |
| 179 | return DECLINED; |
|
|
| 180 | } |
234 | } |
| 181 | |
235 | |
| 182 | 1; |
236 | 1; |