Filename | /var/www/foswikidev/core/lib/Foswiki/Plugins/JHotDrawPlugin.pm |
Statements | Executed 18 statements in 1.43ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
1 | 1 | 1 | 286µs | 477µs | BEGIN@29 | Foswiki::Plugins::JHotDrawPlugin::
1 | 1 | 1 | 26µs | 6.69ms | initPlugin | Foswiki::Plugins::JHotDrawPlugin::
1 | 1 | 1 | 13µs | 26µs | BEGIN@24 | Foswiki::Plugins::JHotDrawPlugin::
1 | 1 | 1 | 10µs | 40µs | BEGIN@26 | Foswiki::Plugins::JHotDrawPlugin::
1 | 1 | 1 | 5µs | 5µs | BEGIN@30 | Foswiki::Plugins::JHotDrawPlugin::
1 | 1 | 1 | 4µs | 4µ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 | 40µ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.22 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 | 27µs | 2 | 70µs | # spent 40µs (10+30) within Foswiki::Plugins::JHotDrawPlugin::BEGIN@26 which was called:
# once (10µs+30µs) by Foswiki::Plugin::BEGIN@2.22 at line 26 # spent 40µs making 1 call to Foswiki::Plugins::JHotDrawPlugin::BEGIN@26
# spent 30µs making 1 call to Exporter::import |
27 | |||||
28 | 2 | 19µs | 1 | 4µs | # spent 4µs within Foswiki::Plugins::JHotDrawPlugin::BEGIN@28 which was called:
# once (4µs+0s) by Foswiki::Plugin::BEGIN@2.22 at line 28 # spent 4µs making 1 call to Foswiki::Plugins::JHotDrawPlugin::BEGIN@28 |
29 | 2 | 106µs | 1 | 477µs | # spent 477µs (286+191) within Foswiki::Plugins::JHotDrawPlugin::BEGIN@29 which was called:
# once (286µs+191µs) by Foswiki::Plugin::BEGIN@2.22 at line 29 # spent 477µs making 1 call to Foswiki::Plugins::JHotDrawPlugin::BEGIN@29 |
30 | 2 | 1.23ms | 1 | 5µs | # spent 5µs within Foswiki::Plugins::JHotDrawPlugin::BEGIN@30 which was called:
# once (5µs+0s) by Foswiki::Plugin::BEGIN@2.22 at line 30 # spent 5µs making 1 call to Foswiki::Plugins::JHotDrawPlugin::BEGIN@30 |
31 | |||||
32 | 1 | 600ns | our $VERSION = '$Rev$'; | ||
33 | 1 | 200ns | our $RELEASE = '29 Oct 2010'; | ||
34 | 1 | 200ns | our $SHORTDESCRIPTION = 'Java Applet based drawing editor'; | ||
35 | |||||
36 | # spent 6.69ms (26µs+6.67) within Foswiki::Plugins::JHotDrawPlugin::initPlugin which was called:
# once (26µs+6.67ms) by Foswiki::Plugin::__ANON__[/var/www/foswikidev/core/lib/Foswiki/Plugin.pm:257] at line 250 of /var/www/foswikidev/core/lib/Foswiki/Plugin.pm | ||||
37 | 1 | 2µs | 1 | 16µs | Foswiki::Func::registerTagHandler( 'DRAWING', \&_DRAWING ); # spent 16µs making 1 call to Foswiki::Func::registerTagHandler |
38 | |||||
39 | 1 | 2µs | 1 | 17µs | Foswiki::Func::registerRESTHandler( 'edit', \&_restEdit ); # spent 17µs making 1 call to Foswiki::Func::registerRESTHandler |
40 | 1 | 8µs | 1 | 6.63ms | Foswiki::Func::registerRESTHandler( 'upload', \&_restUpload ); # spent 6.63ms making 1 call to Foswiki::Func::registerRESTHandler |
41 | |||||
42 | 1 | 5µ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 ( | ||||
168 | Foswiki::Func::checkAccessPermission( | ||||
169 | 'CHANGE', Foswiki::Func::getCanonicalUserID(), | ||||
170 | undef, $topic, $web | ||||
171 | ) | ||||
172 | ) | ||||
173 | { | ||||
174 | returnRESTResult( $response, 401, "Access denied" ); | ||||
175 | return (); | ||||
176 | } | ||||
177 | $web = | ||||
178 | Foswiki::Sandbox::untaint( $web, \&Foswiki::Sandbox::validateWebName ); | ||||
179 | $topic = Foswiki::Sandbox::untaint( $topic, | ||||
180 | \&Foswiki::Sandbox::validateTopicName ); | ||||
181 | unless ( defined $web && defined $topic ) { | ||||
182 | returnRESTResult( $response, 401, "Access denied" ); | ||||
183 | return (); | ||||
184 | } | ||||
185 | unless ( | ||||
186 | Foswiki::Func::checkAccessPermission( | ||||
187 | 'CHANGE', Foswiki::Func::getWikiName(), | ||||
188 | undef, $topic, $web | ||||
189 | ) | ||||
190 | ) | ||||
191 | { | ||||
192 | returnRESTResult( $response, 401, "Access denied" ); | ||||
193 | return (); | ||||
194 | } | ||||
195 | return ( $web, $topic ); | ||||
196 | } | ||||
197 | |||||
198 | # REST handler | ||||
199 | sub _restEdit { | ||||
200 | my ( $session, $plugin, $verb, $response ) = @_; | ||||
201 | my ( $web, $topic ) = _getTopic(@_); | ||||
202 | return unless $web && $topic; | ||||
203 | |||||
204 | my $query = Foswiki::Func::getCgiQuery(); | ||||
205 | my $drawing = $query->param('drawing'); | ||||
206 | unless ($drawing) { | ||||
207 | returnRESTResult( $response, 400, "No drawing" ); | ||||
208 | return; | ||||
209 | } | ||||
210 | Foswiki::Func::setPreferencesValue( 'DRAWINGNAME', $drawing ); | ||||
211 | my $src = (DEBUG) ? '_src' : ''; | ||||
212 | Foswiki::Func::addToZone( 'script', 'JHOTDRAWPLUGIN', | ||||
213 | <<"JS", 'JQUERYPLUGIN::FOSWIKI' ); | ||||
214 | <script type="text/javascript" src="$Foswiki::cfg{PubUrlPath}/$Foswiki::cfg{SystemWebName}/JHotDrawPlugin/jhotdraw$src.js"></script> | ||||
215 | JS | ||||
216 | |||||
217 | my $template = Foswiki::Func::loadTemplate('jhotdraw'); | ||||
218 | $template = Foswiki::Func::expandCommonVariables($template); | ||||
219 | return Foswiki::Func::renderText($template); | ||||
220 | } | ||||
221 | |||||
222 | sub _unescape { | ||||
223 | my $d = shift; | ||||
224 | $d =~ s/%([\da-f]{2})/chr(hex($1))/gei; | ||||
225 | return $d; | ||||
226 | } | ||||
227 | |||||
228 | # REST handler | ||||
229 | sub _restUpload { | ||||
230 | my ( $session, $plugin, $verb, $response ) = @_; | ||||
231 | my $query = Foswiki::Func::getCgiQuery(); | ||||
232 | |||||
233 | if ( $Foswiki::cfg{Validation}{Method} eq 'strikeone' ) { | ||||
234 | require Foswiki::Validation; | ||||
235 | my $nonce = $query->param('validation_key'); | ||||
236 | if ( | ||||
237 | !defined($nonce) | ||||
238 | || !Foswiki::Validation::isValidNonce( | ||||
239 | $session->getCGISession(), $nonce | ||||
240 | ) | ||||
241 | ) | ||||
242 | { | ||||
243 | returnRESTResult( $response, 403, "Invalid validation key" ); | ||||
244 | return; | ||||
245 | } | ||||
246 | } | ||||
247 | |||||
248 | my ( $web, $topic ) = _getTopic(@_); | ||||
249 | |||||
250 | # Basename of the drawing | ||||
251 | my $fileName = $query->param('drawing'); | ||||
252 | ASSERT( $fileName, $query->Dump() ) if DEBUG; | ||||
253 | |||||
254 | my $origName = $fileName; | ||||
255 | |||||
256 | # SMELL: call to unpublished function | ||||
257 | ( $fileName, $origName ) = | ||||
258 | Foswiki::Sandbox::sanitizeAttachmentName($fileName); | ||||
259 | |||||
260 | # Save a file for each file type | ||||
261 | my @errors; | ||||
262 | foreach my $ftype (qw(draw gif map svg)) { | ||||
263 | my $content = $query->param($ftype); | ||||
264 | next unless defined $content; | ||||
265 | if ( $ftype eq 'gif' ) { | ||||
266 | |||||
267 | # GIF is passed base64 encoded | ||||
268 | $content = MIME::Base64::decode_base64($content); | ||||
269 | } | ||||
270 | my $ft = new File::Temp(); # will be unlinked on destroy | ||||
271 | my $fn = $ft->filename(); | ||||
272 | binmode($ft); | ||||
273 | print $ft $content; | ||||
274 | close($ft); | ||||
275 | |||||
276 | my $error = Foswiki::Func::saveAttachment( | ||||
277 | $web, $topic, | ||||
278 | "$fileName.$ftype", | ||||
279 | { | ||||
280 | dontlog => !$Foswiki::cfg{Log}{upload}, | ||||
281 | comment => "JHotDrawPlugin file", | ||||
282 | filedate => time(), | ||||
283 | file => $fn, | ||||
284 | } | ||||
285 | ); | ||||
286 | if ($error) { | ||||
287 | print STDERR "Attachment save error $error\n"; | ||||
288 | push( @errors, $error ); | ||||
289 | } | ||||
290 | } | ||||
291 | |||||
292 | if ( scalar(@errors) ) { | ||||
293 | print STDERR "JHotDraw SAVE FAILED\n"; | ||||
294 | returnRESTResult( $response, 500, join( ' ', @errors ) ); | ||||
295 | } | ||||
296 | else { | ||||
297 | returnRESTResult( $response, 200, 'OK' ); | ||||
298 | } | ||||
299 | |||||
300 | return undef; | ||||
301 | } | ||||
302 | |||||
303 | 1 | 3µs | 1; |