← 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/Subscriber.pm
StatementsExecuted 311 statements in 1.50ms
Subroutines
Calls P F Exclusive
Time
Inclusive
Time
Subroutine
5611212µs212µsFoswiki::Contrib::MailerContrib::Subscriber::::newFoswiki::Contrib::MailerContrib::Subscriber::new
6211157µs157µsFoswiki::Contrib::MailerContrib::Subscriber::::subscribeFoswiki::Contrib::MailerContrib::Subscriber::subscribe
11116µs28µsFoswiki::Contrib::MailerContrib::Subscriber::::BEGIN@17Foswiki::Contrib::MailerContrib::Subscriber::BEGIN@17
11112µs16µsFoswiki::Contrib::MailerContrib::Subscriber::::BEGIN@18Foswiki::Contrib::MailerContrib::Subscriber::BEGIN@18
21110µs10µsFoswiki::Contrib::MailerContrib::Subscriber::::isSubscribedToFoswiki::Contrib::MailerContrib::Subscriber::isSubscribedTo
11110µs34µsFoswiki::Contrib::MailerContrib::Subscriber::::BEGIN@19Foswiki::Contrib::MailerContrib::Subscriber::BEGIN@19
1114µs4µsFoswiki::Contrib::MailerContrib::Subscriber::::BEGIN@21Foswiki::Contrib::MailerContrib::Subscriber::BEGIN@21
1113µs3µsFoswiki::Contrib::MailerContrib::Subscriber::::BEGIN@23Foswiki::Contrib::MailerContrib::Subscriber::BEGIN@23
1113µs3µsFoswiki::Contrib::MailerContrib::Subscriber::::BEGIN@22Foswiki::Contrib::MailerContrib::Subscriber::BEGIN@22
0000s0sFoswiki::Contrib::MailerContrib::Subscriber::::_subtractFoswiki::Contrib::MailerContrib::Subscriber::_subtract
0000s0sFoswiki::Contrib::MailerContrib::Subscriber::::getEmailAddressesFoswiki::Contrib::MailerContrib::Subscriber::getEmailAddresses
0000s0sFoswiki::Contrib::MailerContrib::Subscriber::::getEmailAddressesForUserFoswiki::Contrib::MailerContrib::Subscriber::getEmailAddressesForUser
0000s0sFoswiki::Contrib::MailerContrib::Subscriber::::isUnsubscribedFromFoswiki::Contrib::MailerContrib::Subscriber::isUnsubscribedFrom
0000s0sFoswiki::Contrib::MailerContrib::Subscriber::::optimiseFoswiki::Contrib::MailerContrib::Subscriber::optimise
0000s0sFoswiki::Contrib::MailerContrib::Subscriber::::stringifyFoswiki::Contrib::MailerContrib::Subscriber::stringify
0000s0sFoswiki::Contrib::MailerContrib::Subscriber::::unsubscribeFoswiki::Contrib::MailerContrib::Subscriber::unsubscribe
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::Subscriber
6Object that represents a subscriber to notification. A subscriber is
7a name (which may be a wikiName or an email address) and a list of
8subscriptions which describe the topis subscribed to, and
9unsubscriptions representing topics they are specifically not
10interested in. The subscriber
11name may also be a group, so it may expand to many email addresses.
12
13=cut
14
15package Foswiki::Contrib::MailerContrib::Subscriber;
16
17227µs240µs
# spent 28µs (16+12) within Foswiki::Contrib::MailerContrib::Subscriber::BEGIN@17 which was called: # once (16µs+12µs) by Foswiki::Contrib::MailerContrib::WebNotify::BEGIN@22 at line 17
use strict;
# spent 28µs making 1 call to Foswiki::Contrib::MailerContrib::Subscriber::BEGIN@17 # spent 12µs making 1 call to strict::import
18225µs220µs
# spent 16µs (12+4) within Foswiki::Contrib::MailerContrib::Subscriber::BEGIN@18 which was called: # once (12µs+4µs) by Foswiki::Contrib::MailerContrib::WebNotify::BEGIN@22 at line 18
use warnings;
# spent 16µs making 1 call to Foswiki::Contrib::MailerContrib::Subscriber::BEGIN@18 # spent 4µs making 1 call to warnings::import
19225µs259µs
# spent 34µs (10+25) within Foswiki::Contrib::MailerContrib::Subscriber::BEGIN@19 which was called: # once (10µs+25µs) by Foswiki::Contrib::MailerContrib::WebNotify::BEGIN@22 at line 19
use Assert;
# spent 34µs making 1 call to Foswiki::Contrib::MailerContrib::Subscriber::BEGIN@19 # spent 24µs making 1 call to Exporter::import
20
21219µs14µs
# spent 4µs within Foswiki::Contrib::MailerContrib::Subscriber::BEGIN@21 which was called: # once (4µs+0s) by Foswiki::Contrib::MailerContrib::WebNotify::BEGIN@22 at line 21
use Foswiki ();
22219µs13µs
# spent 3µs within Foswiki::Contrib::MailerContrib::Subscriber::BEGIN@22 which was called: # once (3µs+0s) by Foswiki::Contrib::MailerContrib::WebNotify::BEGIN@22 at line 22
use Foswiki::Plugins ();
232854µs13µs
# spent 3µs within Foswiki::Contrib::MailerContrib::Subscriber::BEGIN@23 which was called: # once (3µs+0s) by Foswiki::Contrib::MailerContrib::WebNotify::BEGIN@22 at line 23
use Foswiki::Contrib::MailerContrib::WebNotify ();
24
25=begin TML
26
27---++ ClassMethod new($name)
28 * =$name= - Wikiname, with no web, or email address, of user targeted for notification
29Create a new user.
30
31=cut
32
33
# spent 212µs within Foswiki::Contrib::MailerContrib::Subscriber::new which was called 56 times, avg 4µs/call: # 56 times (212µs+0s) by Foswiki::Contrib::MailerContrib::WebNotify::getSubscriber at line 101 of /var/www/foswikidev/core/lib/Foswiki/Contrib/MailerContrib/WebNotify.pm, avg 4µs/call
sub new {
345629µs my ( $class, $name ) = @_;
3556123µs my $this = bless(
36 {
37 name => $name,
38
39 # emails => [],
40 # subscriptions => [],
41 # unsubscriptions => [],
42 },
43 $class
44 );
4556141µs return $this;
46}
47
48=begin TML
49
50---++ ObjectMethod getEmailAddresses() -> \@list
51Get a list of email addresses for the user(s) represented by this
52subscription
53
54=cut
55
56sub getEmailAddresses {
57 my $this = shift;
58
59 unless ( defined( $this->{emails} ) ) {
60 $this->{emails} = getEmailAddressesForUser( $this->{name} );
61 }
62 return $this->{emails};
63}
64
65=begin TML
66
67---++ STATIC getEmailAddressesForUser() -> \@list
68Get a list of email addresses for the user(s) represented by this
69subscription. Static method provided for use by other modules.
70
71=cut
72
73sub getEmailAddressesForUser {
74 my $name = shift;
75 my $emails = [];
76
77 return $emails unless $name;
78
79 if ( $name =~ /^$Foswiki::cfg{MailerContrib}{EmailFilterIn}$/ ) {
80 push( @{$emails}, $name );
81 }
82 else {
83 my $users = $Foswiki::Plugins::SESSION->{users};
84 if ( $users->can('findUserByWikiName') ) {
85
86 # User is represented by a wikiname. Map to a canonical
87 # userid.
88 my $list = $users->findUserByWikiName($name);
89 foreach my $user (@$list) {
90
91 # Automatically expands groups
92 push( @{$emails}, $users->getEmails($user) );
93 }
94 }
95 else {
96
97 # Old code; use the user object
98 my $user = $users->findUser( $name, undef, 1 );
99 if ($user) {
100 push( @{$emails}, $user->emails() );
101 }
102 else {
103 $user = $users->findUser( $name, $name, 1 );
104 if ($user) {
105 push( @{$emails}, $user->emails() );
106 }
107 else {
108
109 # unknown - can't find an email
110 $emails = [];
111 }
112 }
113 }
114 }
115 return $emails;
116}
117
118=begin TML
119
120---++ ObjectMethod optimise()
121Optimise the lists of subscriptions and unsubscriptions by finding
122overlaps and eliminating them. Intended to be used before writing
123a new WebNotify.
124
125=cut
126
127# O(N^2)
128# Call before writing.
129sub optimise {
130 my $this = shift;
131
132 foreach my $set ( 'subscriptions', 'unsubscriptions' ) {
133 my @new_set = ();
134
135 NEW:
136 foreach my $new ( @{ $this->{$set} } ) {
137
138 # Don't add already covered duplicates
139 my $i = 0;
140 my @remove;
141 foreach my $known (@new_set) {
142 next NEW if $known->covers($new);
143 if ( $new->covers($known) ) {
144
145 # remove anything covered by the new subscription
146 unshift( @remove, $i );
147 }
148 $i++;
149 }
150 foreach $i (@remove) {
151 splice( @new_set, $i, 1 );
152 }
153 push( @new_set, $new );
154 }
155
156 # TODO: should look at removing redundant exclusions e.g.
157 # -SubScribe (2) when there is no positive subscription
158 # if there are no subscriptions, there is no point lugging
159 # around the unsubs
160 $this->{$set} = \@new_set;
161 }
162}
163
164# Subtract a subscription from an internal list. If the removal expression
165# removes one or more existing expressions by exact matching, then return
166# true otherwise return false. Thus:
167# * removing 'This*' from 'This* ThisThat' will remove 'This*' and
168# 'ThisThat' and return true.
169# * removing '*That' will remove 'ThisThat' and return false.
170# * removing 'T*' will remove 'This*' and 'ThisThat' and return false.
171sub _subtract {
172 my ( $this, $set, $dead ) = @_;
173
174 my $i = 0;
175 my @remove;
176 my $removed;
177
178 #print "Subtract ".$dead->stringify()." from ".$this->stringify()."\n";
179 foreach my $known ( @{ $this->{$set} } ) {
180 $removed = $known->filterExact( $dead->{topics} );
181 if ( $dead->covers($known) ) {
182
183 #print "DEAD ".$dead->stringify()." COVERS ".$known->stringify()."\n";
184 # remove anything covered by the dead subscription
185 unshift( @remove, $i );
186 }
187 $i++;
188 }
189 foreach $i (@remove) {
190 splice( @{ $this->{$set} }, $i, 1 );
191 }
192 return $removed;
193}
194
195=begin TML
196
197---++ ObjectMethod subscribe($subs)
198 * =$subs= - Subscription object
199Add a new subscription to this subscriber object. no optimisation is performed; if
200the subscription is already there, or is covered by another subscription, then it
201will still be added.
202
203=cut
204
205
# spent 157µs within Foswiki::Contrib::MailerContrib::Subscriber::subscribe which was called 62 times, avg 3µs/call: # 62 times (157µs+0s) by Foswiki::Contrib::MailerContrib::WebNotify::subscribe at line 161 of /var/www/foswikidev/core/lib/Foswiki/Contrib/MailerContrib/WebNotify.pm, avg 3µs/call
sub subscribe {
2066234µs my ( $this, $subs ) = @_;
207
20862185µs push( @{ $this->{subscriptions} }, $subs );
209
210 #$this->_subtract( 'unsubscriptions', $subs ); disabled for performance reasons
211}
212
213=begin TML
214
215---++ ObjectMethod unsubscribe($subs)
216 * =$subs= - Subscription object
217Add a new unsubscription to this subscriber object.
218The unsubscription will always be added, even if there is
219a wildcard overlap with an existing subscription or unsubscription.
220
221An unsubscription is a statement of the subscribers desire _not_
222to be notified of changes to this topic.
223
224=cut
225
226sub unsubscribe {
227 my ( $this, $subs ) = @_;
228
229 # If there was no exact match in the removal, then push a -
230 if (
231 !$this->_subtract( 'subscriptions', $subs )
232
233 # - * causes evaluation problems.
234 && !$subs->matches('*')
235 )
236 {
237 push( @{ $this->{unsubscriptions} }, $subs );
238 }
239}
240
241=begin TML
242
243---++ isSubscribedTo($topic, $db) -> $subscription
244 * =$topic= - Topic object we are checking
245 * =$db= - Foswiki::Contrib::MailerContrib::UpData database of parents
246Check if we have a subscription to the given topic. Return the subscription
247that matches if we do, undef otherwise.
248
249=cut
250
251
# spent 10µs within Foswiki::Contrib::MailerContrib::Subscriber::isSubscribedTo which was called 2 times, avg 5µs/call: # 2 times (10µs+0s) by Foswiki::Contrib::MailerContrib::_isSubscribedToTopic at line 168 of /var/www/foswikidev/core/lib/Foswiki/Contrib/MailerContrib.pm, avg 5µs/call
sub isSubscribedTo {
25223µs my ( $this, $topic, $db ) = @_;
253
25424µs foreach my $subscription ( @{ $this->{subscriptions} } ) {
255 if ( $subscription->matches( $topic, $db ) ) {
256 return $subscription;
257 }
258 }
259
26027µs return;
261}
262
263=begin TML
264
265---++ ObjectMethod isUnsubscribedFrom($topic) -> $subscription
266 * =$topic= - Topic object we are checking
267 * =$db= - Foswiki::Contrib::MailerContrib::UpData database of parents
268Check if we have an unsubscription from the given topic. Return the subscription that matches if we do, undef otherwise.
269
270=cut
271
272sub isUnsubscribedFrom {
273 my ( $this, $topic, $db ) = @_;
274
275 foreach my $subscription ( @{ $this->{unsubscriptions} } ) {
276 if ( $subscription->matches( $topic, $db ) ) {
277 return $subscription;
278 }
279 }
280
281 return;
282}
283
284=begin TML
285
286---++ ObjectMethod stringify() -> string
287Return a string representation of this object, in Web<nop>Notify format.
288
289=cut
290
291sub stringify {
292 my $this = shift;
293 my $subs =
294 join( ' ', map { $_->stringify(); } @{ $this->{subscriptions} } );
295 my $unsubs =
296 join( " - ", map { $_->stringify(); } @{ $this->{unsubscriptions} } );
297 $unsubs = " - $unsubs" if $unsubs;
298
299 my $name = $this->{name};
300 if ( $name =~ /^$Foswiki::regex{wikiWordRegex}$/ ) {
301 $name = '%USERSWEB%.' . $name;
302 }
303 elsif ( $name !~ /^$Foswiki::cfg{MailerContrib}{EmailFilterIn}$/ ) {
304 $name = $name =~ /'/ ? '"' . $name . '"' : "'$name'";
305 }
306 return " * " . $name . ": " . $subs . $unsubs;
307}
308
30912µs1;
310__END__