Filename | /var/www/foswiki11/lib/Foswiki/Plugins/JHotDrawPlugin.pm |
Statements | Executed 18 statements in 1.53ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 2.74ms | 5.87ms | BEGIN@30 | Foswiki::Plugins::JHotDrawPlugin::
1 | 1 | 1 | 286µs | 486µs | BEGIN@29 | Foswiki::Plugins::JHotDrawPlugin::
1 | 1 | 1 | 28µs | 106µs | initPlugin | Foswiki::Plugins::JHotDrawPlugin::
1 | 1 | 1 | 13µs | 26µs | BEGIN@24 | Foswiki::Plugins::JHotDrawPlugin::
1 | 1 | 1 | 10µs | 29µs | BEGIN@26 | Foswiki::Plugins::JHotDrawPlugin::
1 | 1 | 1 | 3µs | 3µs | BEGIN@28 | Foswiki::Plugins::JHotDrawPlugin::
0 | 0 | 0 | 0s | 0s | _DRAWING | Foswiki::Plugins::JHotDrawPlugin::
0 | 0 | 0 | 0s | 0s | _getTopic | Foswiki::Plugins::JHotDrawPlugin::
0 | 0 | 0 | 0s | 0s | _processHref | Foswiki::Plugins::JHotDrawPlugin::
0 | 0 | 0 | 0s | 0s | _restEdit | Foswiki::Plugins::JHotDrawPlugin::
0 | 0 | 0 | 0s | 0s | _restUpload | Foswiki::Plugins::JHotDrawPlugin::
0 | 0 | 0 | 0s | 0s | _unescape | Foswiki::Plugins::JHotDrawPlugin::
0 | 0 | 0 | 0s | 0s | returnRESTResult | Foswiki::Plugins::JHotDrawPlugin::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | # Plugin for Foswiki - The Free and Open Source Wiki, http://foswiki.org/ | ||||
2 | # | ||||
3 | # Copyright (C) 2000-2001 Andrea Sterbini, a.sterbini@flashnet.it | ||||
4 | # Copyright (C) 2001-2006 Peter Thoeny, Peter@Thoeny.org | ||||
5 | # Copyright (C) 2002-2006 Crawford Currie, cc@c-dot.co.uk | ||||
6 | # Copyright (C) 2008-2009 Foswiki Contributors | ||||
7 | # | ||||
8 | # For licensing info read LICENSE file in the Foswiki root. | ||||
9 | # This program is free software; you can redistribute it and/or | ||||
10 | # modify it under the terms of the GNU General Public License | ||||
11 | # as published by the Free Software Foundation; either version 2 | ||||
12 | # of the License, or (at your option) any later version. | ||||
13 | # | ||||
14 | # This program is distributed in the hope that it will be useful, | ||||
15 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
16 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
17 | # GNU General Public License for more details, published at | ||||
18 | # http://www.gnu.org/copyleft/gpl.html | ||||
19 | # | ||||
20 | # As per the GPL, removal of this notice is prohibited. | ||||
21 | |||||
22 | package Foswiki::Plugins::JHotDrawPlugin; | ||||
23 | |||||
24 | 2 | 27µs | 2 | 39µs | # spent 26µs (13+13) within Foswiki::Plugins::JHotDrawPlugin::BEGIN@24 which was called:
# once (13µs+13µs) by Foswiki::Plugin::BEGIN@2.19 at line 24 # spent 26µs making 1 call to Foswiki::Plugins::JHotDrawPlugin::BEGIN@24
# spent 13µs making 1 call to strict::import |
25 | |||||
26 | 2 | 25µs | 2 | 48µs | # spent 29µs (10+19) within Foswiki::Plugins::JHotDrawPlugin::BEGIN@26 which was called:
# once (10µs+19µs) by Foswiki::Plugin::BEGIN@2.19 at line 26 # spent 29µs making 1 call to Foswiki::Plugins::JHotDrawPlugin::BEGIN@26
# spent 19µs making 1 call to Assert::import |
27 | |||||
28 | 2 | 19µs | 1 | 3µs | # spent 3µs within Foswiki::Plugins::JHotDrawPlugin::BEGIN@28 which was called:
# once (3µs+0s) by Foswiki::Plugin::BEGIN@2.19 at line 28 # spent 3µs making 1 call to Foswiki::Plugins::JHotDrawPlugin::BEGIN@28 |
29 | 2 | 101µs | 1 | 486µs | # spent 486µs (286+200) within Foswiki::Plugins::JHotDrawPlugin::BEGIN@29 which was called:
# once (286µs+200µs) by Foswiki::Plugin::BEGIN@2.19 at line 29 # spent 486µs making 1 call to Foswiki::Plugins::JHotDrawPlugin::BEGIN@29 |
30 | 2 | 1.12ms | 1 | 5.87ms | # spent 5.87ms (2.74+3.13) within Foswiki::Plugins::JHotDrawPlugin::BEGIN@30 which was called:
# once (2.74ms+3.13ms) by Foswiki::Plugin::BEGIN@2.19 at line 30 # spent 5.87ms making 1 call to Foswiki::Plugins::JHotDrawPlugin::BEGIN@30 |
31 | |||||
32 | 1 | 600ns | our $VERSION = '$Rev: 9801 (2010-10-29) $'; | ||
33 | 1 | 200ns | our $RELEASE = '29 Oct 2010'; | ||
34 | 1 | 200ns | our $SHORTDESCRIPTION = 'Java Applet based drawing editor'; | ||
35 | |||||
36 | # spent 106µs (28+79) within Foswiki::Plugins::JHotDrawPlugin::initPlugin which was called:
# once (28µs+79µs) by Foswiki::Plugin::__ANON__[/var/www/foswiki11/lib/Foswiki/Plugin.pm:241] at line 234 of /var/www/foswiki11/lib/Foswiki/Plugin.pm | ||||
37 | 1 | 3µs | 1 | 30µs | Foswiki::Func::registerTagHandler( 'DRAWING', \&_DRAWING ); # spent 30µs making 1 call to Foswiki::Func::registerTagHandler |
38 | |||||
39 | 1 | 4µs | 1 | 27µs | Foswiki::Func::registerRESTHandler( 'edit', \&_restEdit ); # spent 27µs making 1 call to Foswiki::Func::registerRESTHandler |
40 | 1 | 5µs | 1 | 22µs | Foswiki::Func::registerRESTHandler( 'upload', \&_restUpload ); # spent 22µs making 1 call to Foswiki::Func::registerRESTHandler |
41 | |||||
42 | 1 | 6µs | return 1; | ||
43 | } | ||||
44 | |||||
45 | # Tag handler | ||||
46 | sub _DRAWING { | ||||
47 | my ( $session, $attributes, $topic, $web ) = @_; | ||||
48 | |||||
49 | my $drawingName = $attributes->{_DEFAULT} || 'untitled'; | ||||
50 | $drawingName = ( Foswiki::Func::sanitizeAttachmentName($drawingName) )[0]; | ||||
51 | |||||
52 | my ($imgTime) = | ||||
53 | Foswiki::Func::getRevisionInfo($web, $topic, 0, "$drawingName.gif"); | ||||
54 | my $imgParams = { src => "%ATTACHURLPATH%/$drawingName.gif?t=$imgTime" }; | ||||
55 | |||||
56 | # The edit URL is a rest handler, but we still like | ||||
57 | # to be sure we can change the topic before we can offer to edit | ||||
58 | my $canEdit = Foswiki::Func::getContext()->{authenticated} | ||||
59 | && Foswiki::Func::checkAccessPermission( 'CHANGE', | ||||
60 | Foswiki::Func::getCanonicalUserID(), | ||||
61 | undef, $topic, $web ); | ||||
62 | |||||
63 | my $editUrl = ''; | ||||
64 | my $editLinkParams = {}; | ||||
65 | my $edittext = 'Edit access denied'; | ||||
66 | if ($canEdit) { | ||||
67 | $editUrl = Foswiki::Func::getScriptUrl( | ||||
68 | 'JHotDrawPlugin', 'edit', 'rest', | ||||
69 | topic => "$web.$topic", | ||||
70 | drawing => $drawingName | ||||
71 | ); | ||||
72 | $editLinkParams->{href} = $editUrl; | ||||
73 | $edittext = | ||||
74 | Foswiki::Func::getPreferencesValue("JHOTDRAWPLUGIN_EDIT_TEXT") | ||||
75 | || "Edit drawing using Java applet (requires a Java enabled browser)"; | ||||
76 | $edittext =~ s/%F%/$drawingName/g; | ||||
77 | } | ||||
78 | |||||
79 | my $result = ''; | ||||
80 | my $mapFile = "$drawingName.map"; | ||||
81 | if ( Foswiki::Func::attachmentExists( $web, $topic, $mapFile ) ) { | ||||
82 | my $map = Foswiki::Func::readAttachment( $web, $topic, $mapFile ); | ||||
83 | |||||
84 | my $mapname = $drawingName; | ||||
85 | $imgParams->{usemap} = "#$mapname"; | ||||
86 | |||||
87 | # Unashamed hack to handle Web.TopicName links | ||||
88 | $map =~ s!href=(["'])(.*?)\1!_processHref($2, $web)!ge; | ||||
89 | |||||
90 | Foswiki::Func::setPreferencesValue( 'MAPNAME', $mapname ); | ||||
91 | Foswiki::Func::setPreferencesValue( 'FOSWIKIDRAW', $editUrl ); | ||||
92 | Foswiki::Func::setPreferencesValue( 'EDITTEXT', $edittext ); | ||||
93 | |||||
94 | # Handle if drawing is imported from a T*iki installation | ||||
95 | if ( $map =~ /%TWIKIDRAW%/ ) { | ||||
96 | Foswiki::Func::setPreferencesValue( 'TWIKIDRAW', $editUrl ); | ||||
97 | } | ||||
98 | |||||
99 | $map = Foswiki::Func::expandCommonVariables( $map, $topic ); | ||||
100 | |||||
101 | # Add an edit link just above the image if required | ||||
102 | my $editButton = | ||||
103 | Foswiki::Func::getPreferencesValue("JHOTDRAWPLUGIN_EDIT_BUTTON"); | ||||
104 | |||||
105 | if ( $canEdit && $editButton ) { | ||||
106 | $result = CGI::br() . CGI::a( $editLinkParams, 'Edit' ) . CGI::br(); | ||||
107 | } | ||||
108 | $result .= CGI::img($imgParams) . $map; | ||||
109 | } | ||||
110 | else { | ||||
111 | |||||
112 | # insensitive drawing; the whole image gets a rather more | ||||
113 | # decorative version of the edit URL | ||||
114 | $imgParams->{alt} = $edittext; | ||||
115 | $imgParams->{title} = $edittext; | ||||
116 | $result = CGI::img($imgParams); | ||||
117 | if ($canEdit) { | ||||
118 | $result = | ||||
119 | CGI::a( { href => $editUrl, title => $edittext }, $result ); | ||||
120 | } | ||||
121 | } | ||||
122 | return $result; | ||||
123 | } | ||||
124 | |||||
125 | sub _processHref { | ||||
126 | my ( $link, $defweb ) = @_; | ||||
127 | |||||
128 | # Skip processing naked anchor links, protocol links, and special macros | ||||
129 | unless ( $link =~ | ||||
130 | m/^(%FOSWIKIDRAW%|%TWIKIDRAW%|#|$Foswiki::cfg{LinkProtocolPattern})/ ) | ||||
131 | { | ||||
132 | |||||
133 | my $anchor = ''; | ||||
134 | if ( $link =~ s/(#.*)$// ) { | ||||
135 | $anchor = $1; | ||||
136 | } | ||||
137 | |||||
138 | my ( $web, $topic ) = | ||||
139 | Foswiki::Func::normalizeWebTopicName( $defweb, $link ); | ||||
140 | |||||
141 | $link = "%SCRIPTURLPATH{view}%/$web/$topic$anchor"; | ||||
142 | } | ||||
143 | |||||
144 | return "href=\"$link\""; | ||||
145 | } | ||||
146 | |||||
147 | sub returnRESTResult { | ||||
148 | my ( $response, $status, $text ) = @_; | ||||
149 | |||||
150 | $response->header( | ||||
151 | -status => $status, | ||||
152 | -type => 'text/plain', | ||||
153 | -charset => 'UTF-8' | ||||
154 | ); | ||||
155 | $response->print($text); | ||||
156 | |||||
157 | print STDERR $text if ( $status >= 400 ); | ||||
158 | } | ||||
159 | |||||
160 | sub _getTopic { | ||||
161 | my ( $session, $plugin, $verb, $response ) = @_; | ||||
162 | my $query = Foswiki::Func::getCgiQuery(); | ||||
163 | my ( $web, $topic ) = | ||||
164 | Foswiki::Func::normalizeWebTopicName( undef, $query->param('topic') ); | ||||
165 | |||||
166 | # Check that we have access to the topic | ||||
167 | unless (Foswiki::Func::checkAccessPermission( | ||||
168 | 'CHANGE', Foswiki::Func::getCanonicalUserID(), undef, $topic, $web )) { | ||||
169 | returnRESTResult( $response, 401, "Access denied"); | ||||
170 | return (); | ||||
171 | } | ||||
172 | $web = Foswiki::Sandbox::untaint( | ||||
173 | $web, \&Foswiki::Sandbox::validateWebName ); | ||||
174 | $topic = Foswiki::Sandbox::untaint( $topic, | ||||
175 | \&Foswiki::Sandbox::validateTopicName ); | ||||
176 | unless ( defined $web && defined $topic ) { | ||||
177 | returnRESTResult( $response, 401, "Access denied" ); | ||||
178 | return (); | ||||
179 | } | ||||
180 | unless ( Foswiki::Func::checkAccessPermission( | ||||
181 | 'CHANGE', Foswiki::Func::getWikiName(), undef, $topic, $web )) { | ||||
182 | returnRESTResult( $response, 401, "Access denied" ); | ||||
183 | return (); | ||||
184 | } | ||||
185 | return ($web, $topic); | ||||
186 | } | ||||
187 | |||||
188 | # REST handler | ||||
189 | sub _restEdit { | ||||
190 | my ( $session, $plugin, $verb, $response ) = @_; | ||||
191 | my ($web, $topic) = _getTopic( @_ ); | ||||
192 | return unless $web && $topic; | ||||
193 | |||||
194 | my $query = Foswiki::Func::getCgiQuery(); | ||||
195 | my $drawing = $query->param('drawing'); | ||||
196 | unless ($drawing) { | ||||
197 | returnRESTResult( $response, 400, "No drawing" ); | ||||
198 | return; | ||||
199 | } | ||||
200 | Foswiki::Func::setPreferencesValue('DRAWINGNAME', $drawing); | ||||
201 | my $src = (DEBUG) ? '_src' : ''; | ||||
202 | Foswiki::Func::addToZone( 'script', 'JHOTDRAWPLUGIN', <<"JS", 'JQUERYPLUGIN::FOSWIKI'); | ||||
203 | <script type="text/javascript" src="$Foswiki::cfg{PubUrlPath}/$Foswiki::cfg{SystemWebName}/JHotDrawPlugin/jhotdraw$src.js"></script> | ||||
204 | JS | ||||
205 | |||||
206 | my $template = Foswiki::Func::loadTemplate('jhotdraw'); | ||||
207 | $template = Foswiki::Func::expandCommonVariables($template); | ||||
208 | return Foswiki::Func::renderText($template); | ||||
209 | } | ||||
210 | |||||
211 | sub _unescape { | ||||
212 | my $d = shift; | ||||
213 | $d =~ s/%([\da-f]{2})/chr(hex($1))/gei; | ||||
214 | return $d; | ||||
215 | } | ||||
216 | |||||
217 | # REST handler | ||||
218 | sub _restUpload { | ||||
219 | my ( $session, $plugin, $verb, $response ) = @_; | ||||
220 | my $query = Foswiki::Func::getCgiQuery(); | ||||
221 | |||||
222 | if ( $Foswiki::cfg{Validation}{Method} eq 'strikeone' ) { | ||||
223 | require Foswiki::Validation; | ||||
224 | my $nonce = $query->param('validation_key'); | ||||
225 | if ( !defined($nonce) | ||||
226 | || !Foswiki::Validation::isValidNonce( $session->getCGISession(), | ||||
227 | $nonce ) ) | ||||
228 | { | ||||
229 | returnRESTResult( $response, 403, "Invalid validation key" ); | ||||
230 | return; | ||||
231 | } | ||||
232 | } | ||||
233 | |||||
234 | my ($web, $topic) = _getTopic( @_ ); | ||||
235 | |||||
236 | # Basename of the drawing | ||||
237 | my $fileName = $query->param('drawing'); | ||||
238 | ASSERT($fileName, $query->Dump()) if DEBUG; | ||||
239 | |||||
240 | my $origName = $fileName; | ||||
241 | |||||
242 | # SMELL: call to unpublished function | ||||
243 | ( $fileName, $origName ) = | ||||
244 | Foswiki::Sandbox::sanitizeAttachmentName($fileName); | ||||
245 | |||||
246 | # Save a file for each file type | ||||
247 | my @errors; | ||||
248 | 1 | 215µs | 1 | 169µs | foreach my $ftype qw(draw gif map svg) { # spent 169µs making 1 call to CGI::Carp::warn |
249 | my $content = $query->param($ftype); | ||||
250 | next unless defined $content; | ||||
251 | if ($ftype eq 'gif') { | ||||
252 | # GIF is passed base64 encoded | ||||
253 | $content = MIME::Base64::decode_base64($content); | ||||
254 | } | ||||
255 | my $ft = new File::Temp(); # will be unlinked on destroy | ||||
256 | my $fn = $ft->filename(); | ||||
257 | binmode($ft); | ||||
258 | print $ft $content; | ||||
259 | close($ft); | ||||
260 | |||||
261 | my $error = Foswiki::Func::saveAttachment( | ||||
262 | $web, $topic, | ||||
263 | "$fileName.$ftype", | ||||
264 | { | ||||
265 | dontlog => !$Foswiki::cfg{Log}{upload}, | ||||
266 | comment => "!JHotDrawPlugin file", | ||||
267 | hide => 1, | ||||
268 | filedate => time(), | ||||
269 | file => $fn, | ||||
270 | }); | ||||
271 | if ($error) { | ||||
272 | print STDERR "Attachment save error $error\n"; | ||||
273 | push(@errors, $error ); | ||||
274 | } | ||||
275 | } | ||||
276 | |||||
277 | if (scalar(@errors)) { | ||||
278 | print STDERR "JHotDraw SAVE FAILED\n"; | ||||
279 | returnRESTResult( $response, 500, join(' ', @errors )); | ||||
280 | } else { | ||||
281 | returnRESTResult( $response, 200, 'OK'); | ||||
282 | } | ||||
283 | |||||
284 | return undef; | ||||
285 | } | ||||
286 | |||||
287 | 1 | 3µs | 1; |