← Index
NYTProf Performance Profile   « line view »
For ./view
  Run on Fri Jul 31 18:42:36 2015
Reported on Fri Jul 31 18:48:15 2015

Filename/var/www/foswikidev/core/lib/Foswiki/Contrib/MailerContrib/WebNotify.pm
StatementsExecuted 3402 statements in 7.57ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
2112.71ms74.2msFoswiki::Contrib::MailerContrib::WebNotify::::_loadFoswiki::Contrib::MailerContrib::WebNotify::_load
1111.02ms1.10msFoswiki::Contrib::MailerContrib::WebNotify::::BEGIN@22Foswiki::Contrib::MailerContrib::WebNotify::BEGIN@22
6211990µs4.82msFoswiki::Contrib::MailerContrib::WebNotify::::subscribeFoswiki::Contrib::MailerContrib::WebNotify::subscribe
18011958µs2.15msFoswiki::Contrib::MailerContrib::WebNotify::::_subscribeTopicFoswiki::Contrib::MailerContrib::WebNotify::_subscribeTopic
111891µs1.06msFoswiki::Contrib::MailerContrib::WebNotify::::BEGIN@23Foswiki::Contrib::MailerContrib::WebNotify::BEGIN@23
6211574µs9.27msFoswiki::Contrib::MailerContrib::WebNotify::::parsePageSubscriptionsFoswiki::Contrib::MailerContrib::WebNotify::parsePageSubscriptions
6422550µs763µsFoswiki::Contrib::MailerContrib::WebNotify::::getSubscriberFoswiki::Contrib::MailerContrib::WebNotify::getSubscriber
21155µs74.5msFoswiki::Contrib::MailerContrib::WebNotify::::newFoswiki::Contrib::MailerContrib::WebNotify::new
11116µs30µsFoswiki::Contrib::MailerContrib::WebNotify::::BEGIN@15Foswiki::Contrib::MailerContrib::WebNotify::BEGIN@15
11110µs14µsFoswiki::Contrib::MailerContrib::WebNotify::::BEGIN@16Foswiki::Contrib::MailerContrib::WebNotify::BEGIN@16
11110µs42µsFoswiki::Contrib::MailerContrib::WebNotify::::BEGIN@25Foswiki::Contrib::MailerContrib::WebNotify::BEGIN@25
11110µs36µsFoswiki::Contrib::MailerContrib::WebNotify::::BEGIN@18Foswiki::Contrib::MailerContrib::WebNotify::BEGIN@18
1114µs4µsFoswiki::Contrib::MailerContrib::WebNotify::::BEGIN@20Foswiki::Contrib::MailerContrib::WebNotify::BEGIN@20
1113µs3µsFoswiki::Contrib::MailerContrib::WebNotify::::BEGIN@21Foswiki::Contrib::MailerContrib::WebNotify::BEGIN@21
0000s0sFoswiki::Contrib::MailerContrib::WebNotify::::_emailWarnFoswiki::Contrib::MailerContrib::WebNotify::_emailWarn
0000s0sFoswiki::Contrib::MailerContrib::WebNotify::::_optimiseFoswiki::Contrib::MailerContrib::WebNotify::_optimise
0000s0sFoswiki::Contrib::MailerContrib::WebNotify::::getSubscribersFoswiki::Contrib::MailerContrib::WebNotify::getSubscribers
0000s0sFoswiki::Contrib::MailerContrib::WebNotify::::isEmptyFoswiki::Contrib::MailerContrib::WebNotify::isEmpty
0000s0sFoswiki::Contrib::MailerContrib::WebNotify::::processChangeFoswiki::Contrib::MailerContrib::WebNotify::processChange
0000s0sFoswiki::Contrib::MailerContrib::WebNotify::::processCompulsoryFoswiki::Contrib::MailerContrib::WebNotify::processCompulsory
0000s0sFoswiki::Contrib::MailerContrib::WebNotify::::stringifyFoswiki::Contrib::MailerContrib::WebNotify::stringify
0000s0sFoswiki::Contrib::MailerContrib::WebNotify::::unsubscribeFoswiki::Contrib::MailerContrib::WebNotify::unsubscribe
0000s0sFoswiki::Contrib::MailerContrib::WebNotify::::writeWebNotifyFoswiki::Contrib::MailerContrib::WebNotify::writeWebNotify
Call graph for these subroutines as a Graphviz dot language file.
Line State
ments
Time
on line
Calls Time
in subs
Code
1# See bottom of file for license and copyright information
2
3=begin TML
4
5---+ package Foswiki::Contrib::MailerContrib::WebNotify
6Object that represents the contents of a %NOTIFYTOPIC% topic in a Foswiki web.
7
8Note that =$Foswiki::Plugins::SESSION= is used to find the Foswiki session, and
9must be set up before this class is used.
10
11=cut
12
13package Foswiki::Contrib::MailerContrib::WebNotify;
14
15229µs243µs
# spent 30µs (16+13) within Foswiki::Contrib::MailerContrib::WebNotify::BEGIN@15 which was called: # once (16µs+13µs) by Foswiki::Contrib::MailerContrib::BEGIN@27 at line 15
use strict;
# spent 30µs making 1 call to Foswiki::Contrib::MailerContrib::WebNotify::BEGIN@15 # spent 13µs making 1 call to strict::import
16225µs218µs
# spent 14µs (10+4) within Foswiki::Contrib::MailerContrib::WebNotify::BEGIN@16 which was called: # once (10µs+4µs) by Foswiki::Contrib::MailerContrib::BEGIN@27 at line 16
use warnings;
# spent 14µs making 1 call to Foswiki::Contrib::MailerContrib::WebNotify::BEGIN@16 # spent 4µs making 1 call to warnings::import
17
18228µs261µs
# spent 36µs (10+26) within Foswiki::Contrib::MailerContrib::WebNotify::BEGIN@18 which was called: # once (10µs+26µs) by Foswiki::Contrib::MailerContrib::BEGIN@27 at line 18
use Assert;
# spent 36µs making 1 call to Foswiki::Contrib::MailerContrib::WebNotify::BEGIN@18 # spent 26µs making 1 call to Exporter::import
19
20220µs14µs
# spent 4µs within Foswiki::Contrib::MailerContrib::WebNotify::BEGIN@20 which was called: # once (4µs+0s) by Foswiki::Contrib::MailerContrib::BEGIN@27 at line 20
use Foswiki::Func ();
21219µs13µs
# spent 3µs within Foswiki::Contrib::MailerContrib::WebNotify::BEGIN@21 which was called: # once (3µs+0s) by Foswiki::Contrib::MailerContrib::BEGIN@27 at line 21
use Foswiki::Contrib::MailerContrib ();
222104µs11.10ms
# spent 1.10ms (1.02+89µs) within Foswiki::Contrib::MailerContrib::WebNotify::BEGIN@22 which was called: # once (1.02ms+89µs) by Foswiki::Contrib::MailerContrib::BEGIN@27 at line 22
use Foswiki::Contrib::MailerContrib::Subscriber ();
232108µs11.06ms
# spent 1.06ms (891µs+164µs) within Foswiki::Contrib::MailerContrib::WebNotify::BEGIN@23 which was called: # once (891µs+164µs) by Foswiki::Contrib::MailerContrib::BEGIN@27 at line 23
use Foswiki::Contrib::MailerContrib::Subscription ();
24
2521.92ms273µs
# spent 42µs (10+31) within Foswiki::Contrib::MailerContrib::WebNotify::BEGIN@25 which was called: # once (10µs+31µs) by Foswiki::Contrib::MailerContrib::BEGIN@27 at line 25
use constant TRACE => 0;
# spent 42µs making 1 call to Foswiki::Contrib::MailerContrib::WebNotify::BEGIN@25 # spent 31µs making 1 call to constant::import
26
27=begin TML
28
29---++ ClassMethod new($web, $topic)
30 * =$web= - web name
31 * =$topic= - topic name
32 * =$noexpandgroups= - True will prevent expansion of group subscriptions
33 (False is best for checking subscriptions, but True is best for
34 writing results back to $topic)
35
36Create a new object by parsing the content of the given topic in the
37given web. This is the normal way to load a %NOTIFYTOPIC% topic. If the
38topic does not exist, it will create an empty object.
39
40=cut
41
42
# spent 74.5ms (55µs+74.5) within Foswiki::Contrib::MailerContrib::WebNotify::new which was called 2 times, avg 37.3ms/call: # 2 times (55µs+74.5ms) by Foswiki::Contrib::MailerContrib::_isSubscribedToTopic at line 159 of /var/www/foswikidev/core/lib/Foswiki/Contrib/MailerContrib.pm, avg 37.3ms/call
sub new {
4324µs my ( $class, $web, $topic, $noexpandgroups ) = @_;
44
4529µs my $this = bless( {}, $class );
46
47 # Ensure the contrib is initialised
4825µs210µs Foswiki::Contrib::MailerContrib::initContrib();
# spent 10µs making 2 calls to Foswiki::Contrib::MailerContrib::initContrib, avg 5µs/call
49
5022µs $this->{web} = $web;
5121µs $this->{topic} = $topic || $Foswiki::cfg{NotifyTopicName} || 'WebNotify';
5222µs $this->{pretext} = '';
5321µs $this->{posttext} = '';
5421µs $this->{noexpandgroups} = $noexpandgroups;
55
56216µs474.5ms if ( Foswiki::Func::topicExists( $web, $topic ) ) {
# spent 74.2ms making 2 calls to Foswiki::Contrib::MailerContrib::WebNotify::_load, avg 37.1ms/call # spent 234µs making 2 calls to Foswiki::Func::topicExists, avg 117µs/call
57 $this->_load();
58 }
59
6028µs return $this;
61}
62
63=begin TML
64
65---++ ObjectMethod writeWebNotify()
66Write the object to the %NOTIFYTOPIC% topic it was read from.
67If there is a problem writing the topic (e.g. it is locked), or the
68current user is not authorised to write it, then the method will
69throw an exception.
70
71=cut
72
73sub writeWebNotify {
74 my $this = shift;
75
76 # First remove overlaps
77 $this->_optimise();
78
79 # Then chuck it out
80 Foswiki::Func::saveTopic( $this->{web}, $this->{topic}, undef,
81 $this->stringify(), { minor => 1 } );
82}
83
84=begin TML
85
86---++ ObjectMethod getSubscriber($name, $noAdd)
87 * =$name= - Name of subscriber (wikiname with no web or email address)
88 * =$noAdd= - If false or undef, a new subscriber will be created for this name
89Get a subscriber from the list of subscribers, and return a reference
90to the Subscriber object. If $noAdd is true, and the subscriber is not
91found, undef will be returned. Otherwise a new Subscriber object will
92be added if necessary.
93
94=cut
95
96
# spent 763µs (550+212) within Foswiki::Contrib::MailerContrib::WebNotify::getSubscriber which was called 64 times, avg 12µs/call: # 62 times (534µs+205µs) by Foswiki::Contrib::MailerContrib::WebNotify::subscribe at line 157, avg 12µs/call # 2 times (16µs+7µs) by Foswiki::Contrib::MailerContrib::_isSubscribedToTopic at line 164 of /var/www/foswikidev/core/lib/Foswiki/Contrib/MailerContrib.pm, avg 12µs/call
sub getSubscriber {
976436µs my ( $this, $name, $noAdd ) = @_;
98
996444µs my $subscriber = $this->{subscribers}{$name};
1006422µs unless ( $noAdd || defined($subscriber) ) {
10156187µs56212µs $subscriber = new Foswiki::Contrib::MailerContrib::Subscriber($name);
# spent 212µs making 56 calls to Foswiki::Contrib::MailerContrib::Subscriber::new, avg 4µs/call
10256110µs $this->{subscribers}{$name} = $subscriber;
103 }
10464133µs return $subscriber;
105}
106
107# Optimise the webnotify to remove overlaps in subscription lists
108sub _optimise {
109 my $this = shift;
110 foreach my $subscriber ( values %{ $this->{subscribers} } ) {
111 $subscriber->optimise();
112 }
113}
114
115=begin TML
116
117---++ ObjectMethod getSubscribers()
118Get a list of all subscriber names (unsorted)
119
120=cut
121
122sub getSubscribers {
123 my ($this) = @_;
124
125 return keys %{ $this->{subscribers} };
126}
127
128=begin TML
129
130---++ ObjectMethod subscribe($name, $topics, $depth, $options)
131 * =$name= - Name of subscriber (wikiname with no web or email address)
132 * =$topics= - wildcard expression giving topics to subscribe to
133 * =$depth= - Child depth to scan (default 0)
134 * =$options= - Bitmap of Mailer::Const options
135Add a subscription, adding the subscriber if necessary.
136
137=cut
138
139
# spent 4.82ms (990µs+3.83) within Foswiki::Contrib::MailerContrib::WebNotify::subscribe which was called 62 times, avg 78µs/call: # 62 times (990µs+3.83ms) by Foswiki::Contrib::MailerContrib::WebNotify::parsePageSubscriptions at line 486, avg 78µs/call
sub subscribe {
1406238µs my ( $this, $name, $topics, $depth, $opts ) = @_;
141
1426212µs $opts ||= 0;
143
1446241µs my @names = ($name);
1456227µs unless ( $this->{noexpandgroups} ) {
1466270µs621.35ms my $it = Foswiki::Func::eachGroupMember($name);
# spent 1.35ms making 62 calls to Foswiki::Func::eachGroupMember, avg 22µs/call
1476220µs if ($it) {
148 @names = ();
149 while ( $it->hasNext() ) {
150 my $member = $it->next();
151 push( @names, $member );
152 }
153 }
154 }
155
15662162µs foreach my $n (@names) {
1576288µs62739µs my $subscriber = $this->getSubscriber($n);
# spent 739µs making 62 calls to Foswiki::Contrib::MailerContrib::WebNotify::getSubscriber, avg 12µs/call
15862174µs621.58ms my $sub =
# spent 1.58ms making 62 calls to Foswiki::Contrib::MailerContrib::Subscription::new, avg 26µs/call
159 new Foswiki::Contrib::MailerContrib::Subscription( $topics, $depth,
160 $opts );
16162147µs62157µs $subscriber->subscribe($sub);
# spent 157µs making 62 calls to Foswiki::Contrib::MailerContrib::Subscriber::subscribe, avg 3µs/call
162 }
163}
164
165=begin TML
166
167---++ ObjectMethod unsubscribe($name, $topics, $depth)
168 * =$name= - Name of subscriber (wikiname with no web or email address)
169 * =$topics= - wildcard expression giving topics to subscribe to
170 * =$depth= - Child depth to scan (default 0)
171Add an unsubscription, adding the subscriber if necessary. An unsubscription
172is a specific request to ignore notifications for a topic for this
173particular subscriber.
174
175=cut
176
177sub unsubscribe {
178 my ( $this, $name, $topics, $depth ) = @_;
179
180 my @names = ($name);
181 unless ( $this->{noexpandgroups} ) {
182 my $it = Foswiki::Func::eachGroupMember($name);
183 if ($it) {
184 @names = ();
185 while ( $it->hasNext() ) {
186 my $member = $it->next();
187 push( @names, $member );
188 }
189 }
190 }
191
192 foreach my $n (@names) {
193 my $subscriber = $this->getSubscriber($n);
194 my $sub =
195 new Foswiki::Contrib::MailerContrib::Subscription( $topics, $depth,
196 0 );
197 $subscriber->unsubscribe($sub);
198 }
199}
200
201=begin TML
202
203---++ ObjectMethod stringify([$subscribersOnly]) -> string
204Return a string representation of this object, in %NOTIFYTOPIC% format.
205
206Optional =$subscribersOnly= parameter to only print the parsed subscription list.
207Used when running a mailnotify, where printing out the entire WebNotify topic is confusing,
208as it's different from the actual topic contents, but doesn't inform the user why.
209
210=cut
211
212sub stringify {
213 my ( $this, $subscribersOnly ) = @_;
214
215 my $page = '';
216
217 $page .= $this->{pretext} if ( !$subscribersOnly );
218 $page .= "---\n" if TRACE && $page !~ /---\n*$/;
219 foreach my $name ( sort keys %{ $this->{subscribers} } ) {
220 my $subscriber = $this->{subscribers}{$name};
221 $page .= $subscriber->stringify() . "\n";
222 }
223 $page .= "---\n" if TRACE && $this->{posttext} !~ /^\n*---/;
224 $page .= $this->{posttext} if ( !$subscribersOnly );
225
226 return $page;
227}
228
229=begin TML
230
231---++ ObjectMethod processChange($change, $db, $changeSet, $seenSet, $allSet)
232 * =$change= - ref of a Foswiki::Contrib::Mailer::Change
233 * =$db= - Foswiki::Contrib::MailerContrib::UpData database of parent references
234 * =$changeSet= - ref of a hash mapping name&emails to sets of changes
235 * =$seenSet= - ref of a hash recording indices of topics already seen for
236 each name&email addressee
237 * =$allSet= - ref of a hash that maps topics to name&email ids for news subscriptions
238Find all subscribers that are interested in the given change. Only the most
239recent change to each topic listed in the .changes file is retained. This
240method does _not_ change this object.
241
242=cut
243
244sub processChange {
245 my ( $this, $change, $db, $changeSet, $seenSet, $allSet ) = @_;
246
247 my $topic = $change->{TOPIC};
248 my $web = $change->{WEB};
249 my %authors = map { $_ => 1 } @{
250 Foswiki::Contrib::MailerContrib::Subscriber::getEmailAddressesForUser(
251 $change->{author}
252 )
253 };
254 print STDERR "Process change to $web.$topic\n" if TRACE;
255
256 foreach my $name ( keys %{ $this->{subscribers} } ) {
257 my $subscriber = $this->{subscribers}{$name};
258 my $subs = $subscriber->isSubscribedTo( $topic, $db );
259 if ( $subs && !$subscriber->isUnsubscribedFrom( $topic, $db ) ) {
260
261 # Check access to the old rev
262 my $cuid = Foswiki::Func::getCanonicalUserID($name);
263
264 # Check access is allowed to the most recent revision
265 my $to =
266 Foswiki::Meta->load( $Foswiki::Plugins::SESSION, $web, $topic,
267 $change->{CURR_REV} );
268 unless ( $to->haveAccess( 'VIEW', $cuid ) ) {
269 print STDERR
270"$name has no permission to view r$change->{CURR_REV} of $web.$topic\n"
271 if TRACE;
272 next;
273 }
274
275 $to =
276 Foswiki::Meta->load( $Foswiki::Plugins::SESSION, $web, $topic,
277 $change->{BASE_REV} );
278 unless ( $to->haveAccess( 'VIEW', $cuid ) ) {
279 print STDERR
280"$name has no permission to view r$change->{BASE_REV} of $web.$topic\n"
281 if TRACE;
282 next;
283 }
284
285 print "$name will be notified of changes to $topic\n" if TRACE;
286 my $emails = $subscriber->getEmailAddresses();
287 if ( $emails && scalar(@$emails) ) {
288 foreach my $email (@$emails) {
289 my $id = "$name&$email";
290
291 # Skip this change if the subscriber is the author
292 # of the change, and we are not always sending
293 next
294 if (
295 !(
296 $subs->{options} &
297 Foswiki::Contrib::MailerContrib::Subscription::ALWAYS
298 )
299 && $authors{$email}
300 );
301 print STDERR "\tusing email $email for $name\n" if TRACE;
302 if ( $subs->{options} &
303 Foswiki::Contrib::MailerContrib::Subscription::FULL_TOPIC
304 )
305 {
306
307 #print "Add $id to allSet for $topic\n";
308 push( @{ $allSet->{$topic} }, $id );
309 }
310 else {
311 my $at = $seenSet->{$id}{$topic};
312 if ($at) {
313
314 #print "Merge $id to changeset for $topic\n";
315 $changeSet->{$id}[ $at - 1 ]->merge($change);
316 }
317 else {
318
319 #print "Add $id to changeset for $topic\n";
320 $seenSet->{$id}{$topic} =
321 push( @{ $changeSet->{$id} }, $change );
322 }
323 }
324 }
325 }
326 else {
327 $this->_emailWarn( $subscriber, $name, $web );
328 }
329 }
330 }
331}
332
333=begin TML
334
335---++ ObjectMethod processCompulsory($topic, $db, \%allSet)
336 * =$topic= - topic name
337 * =$db= - Foswiki::Contrib::MailerContrib::UpData database
338 of parent references
339 * =\%allSet= - ref of a hash that maps topics to name&email addresses
340 for news subscriptions
341
342=cut
343
344sub processCompulsory {
345 my ( $this, $topic, $db, $allSet ) = @_;
346
347 foreach my $name ( keys %{ $this->{subscribers} } ) {
348 my $subscriber = $this->{subscribers}{$name};
349 my $subs = $subscriber->isSubscribedTo( $topic, $db );
350 next unless $subs;
351 next
352 unless ( $subs->{options} &
353 Foswiki::Contrib::MailerContrib::Subscription::ALWAYS );
354 unless ( $subscriber->isUnsubscribedFrom( $topic, $db ) ) {
355 my $emails = $subscriber->getEmailAddresses();
356 if ($emails) {
357 foreach my $address (@$emails) {
358 push( @{ $allSet->{$topic} }, "$name&$address" );
359 }
360 }
361 }
362 }
363}
364
365=begin TML
366
367---++ ObjectMethod isEmpty() -> boolean
368Return true if there are no subscribers
369
370=cut
371
372sub isEmpty {
373 my $this = shift;
374 return ( scalar( keys %{ $this->{subscribers} } ) == 0 );
375}
376
377# PRIVATE parse a webnotify topic extracting formatted lines
378
# spent 74.2ms (2.71+71.5) within Foswiki::Contrib::MailerContrib::WebNotify::_load which was called 2 times, avg 37.1ms/call: # 2 times (2.71ms+71.5ms) by Foswiki::Contrib::MailerContrib::WebNotify::new at line 56, avg 37.1ms/call
sub _load {
37921µs my $this = shift;
380
381210µs21.22ms my ( $meta, $text ) =
# spent 1.22ms making 2 calls to Foswiki::Func::readTopic, avg 610µs/call
382 Foswiki::Func::readTopic( $this->{web}, $this->{topic} );
3832500ns my $in_pre = 1;
38421µs $this->{pretext} = '';
3852800ns $this->{posttext} = '';
38621µs $this->{meta} = $meta;
387
388 # join \ terminated lines
389218µs $text =~ s/\\\r?\n//gs;
390216µs my $webRE = qr/(?:$Foswiki::cfg{UsersWebName}\.)?/;
391276µs my $legacyRE = qr{
392 ^\s+\*\s$webRE
393 ($Foswiki::regex{wikiWordRegex})
394 \s+-\s+
395 ($Foswiki::cfg{MailerContrib}{EmailFilterIn}+)
396 \s*$
397 }x;
398269µs my $stdRE = qr{^\s+\*\s$webRE
399 (
400 $Foswiki::regex{wikiWordRegex}
401 | '.*?'
402 | ".*?"
403 | $Foswiki::cfg{MailerContrib}{EmailFilterIn}
404 )
405 \s*(:.*)?$
406 }x;
407272µs foreach my $baseline ( split( /\r?\n/, $text ) ) {
40888169µs8860.3ms my $line =
# spent 60.3ms making 88 calls to Foswiki::Func::expandCommonVariables, avg 685µs/call
409 Foswiki::Func::expandCommonVariables( $baseline, $this->{topic},
410 $this->{web}, $meta );
411881.53ms8541µs if ( $line =~ /$legacyRE/
# spent 541µs making 8 calls to utf8::SWASHNEW, avg 68µs/call
412 && $1 ne $Foswiki::cfg{DefaultUserWikiName} )
413 {
414
415 # Main.WikiName - email@domain (legacy format)
416 $this->subscribe( $2, '*', 0, 0 );
417 $in_pre = 0;
418 }
419 elsif ($line =~ /$stdRE/
420 && $1 ne $Foswiki::cfg{DefaultUserWikiName} )
421 {
4226232µs my $subscriber = $1;
423
424 # Get the topic list from the last bracket matched. Have to do it
425 # this awkward way because the email filter may contain braces
4266230µs my $topics = $+;
427
428 # email addresses can't start with :
42962106µs $topics = undef unless ( $topics =~ s/^:// );
4306271µs $subscriber =~ s/^(['"])(.*)\1$/$2/; # remove quotes
431
432 # CDot: I don't understand how this can ever be tainted, but the
433 # unit tests fail without this untaint. The subscriber is
434 # validated, and should be untainted, by the conditional regex.
4356297µs62200µs $subscriber = Foswiki::Sandbox::untaintUnchecked($subscriber);
# spent 200µs making 62 calls to Foswiki::Sandbox::untaintUnchecked, avg 3µs/call
436
4376291µs629.27ms if ( defined $topics ) {
# spent 9.27ms making 62 calls to Foswiki::Contrib::MailerContrib::WebNotify::parsePageSubscriptions, avg 150µs/call
438 $this->parsePageSubscriptions( $subscriber, $topics );
439 }
440 else {
441 $this->subscribe( $subscriber, '*', 0, 0 );
442 }
4436236µs $in_pre = 0;
444 }
445 else {
4462618µs if ($in_pre) {
447 $this->{pretext} .= "$baseline\n";
448 }
449 else {
4502237µs $this->{posttext} .= "$baseline\n";
451 }
452 }
453 }
454210µs print STDERR "LOADED " . $this->stringify() if TRACE;
455}
456
457=begin TML
458
459---++ ObjectMethod parsePageSubscriptions($who, $spec, $unsubscribe)
460
461Parse a pages list for a single user (corresponding to one line in
462WebNotify), adding subscriptions for user $who as appropriate
463If $unsubscribe is set to '-' by SubscribePlugin to force a '-' operation
464
465=cut
466
467# If we see a simple topic specification with no unusual options, and
468# at childDepth 0, we can collect it into a group subscription for
469# efficiency.
4701300nsour @simple_subscriptions;
471
472
# spent 9.27ms (574µs+8.70) within Foswiki::Contrib::MailerContrib::WebNotify::parsePageSubscriptions which was called 62 times, avg 150µs/call: # 62 times (574µs+8.70ms) by Foswiki::Contrib::MailerContrib::WebNotify::_load at line 437, avg 150µs/call
sub parsePageSubscriptions {
4736236µs my ( $this, $who, $spec, $unsubscribe ) = @_;
474
4756251µs $this->{topicSub} = \&_subscribeTopic;
476
4776238µs local @simple_subscriptions = ();
4786277µs620s my $ret =
# spent 3.88ms making 62 calls to Foswiki::Contrib::MailerContrib::parsePageList, avg 63µs/call, recursion: max depth 1, sum of overlapping time 3.88ms
479 Foswiki::Contrib::MailerContrib::parsePageList( $this, $who, $spec,
480 $unsubscribe );
4816214µs if ( $ret =~ m/\S/ ) {
482 Foswiki::Func::writeWarning("Badly formatted page list at $who: $spec");
483 return -1;
484 }
485
48662149µs624.82ms if ( scalar(@simple_subscriptions) ) {
# spent 4.82ms making 62 calls to Foswiki::Contrib::MailerContrib::WebNotify::subscribe, avg 78µs/call
487
488 $this->subscribe( $who, join( ' ', @simple_subscriptions ), 0, 0 );
489 }
49062142µs return;
491}
492
493# helper for parsePageSubscriptions
494
# spent 2.15ms (958µs+1.19) within Foswiki::Contrib::MailerContrib::WebNotify::_subscribeTopic which was called 180 times, avg 12µs/call: # 180 times (958µs+1.19ms) by Foswiki::Contrib::MailerContrib::parsePageList at line 212 of /var/www/foswikidev/core/lib/Foswiki/Contrib/MailerContrib.pm, avg 12µs/call
sub _subscribeTopic {
495180113µs my ( $this, $who, $unsubscribe, $webTopic, $options, $childDepth ) = @_;
496
497180239µs1801.19ms my ( $web, $topic ) =
# spent 1.19ms making 180 calls to Foswiki::Func::normalizeWebTopicName, avg 7µs/call
498 Foswiki::Func::normalizeWebTopicName( $this->{web}, $webTopic );
499
50018031µs my $opts = 0;
50118029µs my $kids = $childDepth || 0;
50218023µs if ($options) {
503 $opts |= Foswiki::Contrib::MailerContrib::Subscription::FULL_TOPIC;
504 if ( $options =~ /!/ ) {
505 $opts |= Foswiki::Contrib::MailerContrib::Subscription::ALWAYS;
506 }
507 }
508180159µs if ( $unsubscribe && $unsubscribe eq '-' ) {
509 $this->unsubscribe( $who, $topic, $kids );
510 }
511 elsif ( !$opts && !$childDepth ) {
512
513 push( @simple_subscriptions, $topic );
514 }
515 else {
516
517 # Otherwise we have to add a separate subscription record
518 $this->subscribe( $who, $topic, $kids, $opts );
519 }
520
521 #TODO: howto find & report errors?
522180351µs return '';
523}
524
525# PRIVATE emailWarn to warn when an email address cannot be found
526# for a subscriber.
527sub _emailWarn {
528 my ( $this, $subscriber, $name, $web ) = @_;
529
530 # Make sure we only warn once. Don't want to see this for every
531 # Topic we are notifying on.
532 unless ( defined $this->{nomail}{$name} ) {
533 $this->{nomail}{$name} = 1;
534 Foswiki::Func::writeWarning( "Failed to find permitted email for '"
535 . $subscriber->stringify()
536 . "' when processing web '$web'" );
537 }
538}
539
54012µs1;
541__END__