Filename | /usr/local/src/github.com/foswiki/core/lib/Foswiki/Contrib/MailerContrib/Subscriber.pm |
Statements | Executed 5891403 statements in 25.4s |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
12180 | 1 | 1 | 28.7s | 163s | _addAndOptimise | Foswiki::Contrib::MailerContrib::Subscriber::
12180 | 1 | 1 | 220ms | 163s | subscribe | Foswiki::Contrib::MailerContrib::Subscriber::
12180 | 1 | 1 | 204ms | 204ms | _subtract | Foswiki::Contrib::MailerContrib::Subscriber::
1066 | 1 | 1 | 11.4ms | 11.4ms | new | Foswiki::Contrib::MailerContrib::Subscriber::
2 | 1 | 1 | 5.53ms | 21.5ms | isSubscribedTo | Foswiki::Contrib::MailerContrib::Subscriber::
1 | 1 | 1 | 32µs | 40µs | BEGIN@17 | Foswiki::Contrib::MailerContrib::Subscriber::
1 | 1 | 1 | 17µs | 40µs | BEGIN@18 | Foswiki::Contrib::MailerContrib::Subscriber::
1 | 1 | 1 | 16µs | 55µs | BEGIN@19 | Foswiki::Contrib::MailerContrib::Subscriber::
1 | 1 | 1 | 9µs | 9µs | BEGIN@22 | Foswiki::Contrib::MailerContrib::Subscriber::
1 | 1 | 1 | 9µs | 9µs | BEGIN@23 | Foswiki::Contrib::MailerContrib::Subscriber::
1 | 1 | 1 | 9µs | 9µs | BEGIN@21 | Foswiki::Contrib::MailerContrib::Subscriber::
0 | 0 | 0 | 0s | 0s | getEmailAddresses | Foswiki::Contrib::MailerContrib::Subscriber::
0 | 0 | 0 | 0s | 0s | getEmailAddressesForUser | Foswiki::Contrib::MailerContrib::Subscriber::
0 | 0 | 0 | 0s | 0s | isUnsubscribedFrom | Foswiki::Contrib::MailerContrib::Subscriber::
0 | 0 | 0 | 0s | 0s | stringify | Foswiki::Contrib::MailerContrib::Subscriber::
0 | 0 | 0 | 0s | 0s | unsubscribe | Foswiki::Contrib::MailerContrib::Subscriber::
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 | ||||
6 | Object that represents a subscriber to notification. A subscriber is | ||||
7 | a name (which may be a wikiName or an email address) and a list of | ||||
8 | subscriptions which describe the topis subscribed to, and | ||||
9 | unsubscriptions representing topics they are specifically not | ||||
10 | interested in. The subscriber | ||||
11 | name may also be a group, so it may expand to many email addresses. | ||||
12 | |||||
13 | =cut | ||||
14 | |||||
15 | package Foswiki::Contrib::MailerContrib::Subscriber; | ||||
16 | |||||
17 | 2 | 47µs | 2 | 47µs | # spent 40µs (32+7) within Foswiki::Contrib::MailerContrib::Subscriber::BEGIN@17 which was called:
# once (32µs+7µs) by Foswiki::Contrib::MailerContrib::WebNotify::BEGIN@23 at line 17 # spent 40µs making 1 call to Foswiki::Contrib::MailerContrib::Subscriber::BEGIN@17
# spent 7µs making 1 call to strict::import |
18 | 2 | 45µs | 2 | 62µs | # spent 40µs (17+22) within Foswiki::Contrib::MailerContrib::Subscriber::BEGIN@18 which was called:
# once (17µs+22µs) by Foswiki::Contrib::MailerContrib::WebNotify::BEGIN@23 at line 18 # spent 40µs making 1 call to Foswiki::Contrib::MailerContrib::Subscriber::BEGIN@18
# spent 22µs making 1 call to warnings::import |
19 | 2 | 48µs | 2 | 93µs | # spent 55µs (16+38) within Foswiki::Contrib::MailerContrib::Subscriber::BEGIN@19 which was called:
# once (16µs+38µs) by Foswiki::Contrib::MailerContrib::WebNotify::BEGIN@23 at line 19 # spent 55µs making 1 call to Foswiki::Contrib::MailerContrib::Subscriber::BEGIN@19
# spent 38µs making 1 call to Assert::import |
20 | |||||
21 | 2 | 39µs | 1 | 9µs | # spent 9µs within Foswiki::Contrib::MailerContrib::Subscriber::BEGIN@21 which was called:
# once (9µs+0s) by Foswiki::Contrib::MailerContrib::WebNotify::BEGIN@23 at line 21 # spent 9µs making 1 call to Foswiki::Contrib::MailerContrib::Subscriber::BEGIN@21 |
22 | 2 | 38µs | 1 | 9µs | # spent 9µs within Foswiki::Contrib::MailerContrib::Subscriber::BEGIN@22 which was called:
# once (9µs+0s) by Foswiki::Contrib::MailerContrib::WebNotify::BEGIN@23 at line 22 # spent 9µs making 1 call to Foswiki::Contrib::MailerContrib::Subscriber::BEGIN@22 |
23 | 2 | 1.51ms | 1 | 9µs | # spent 9µs within Foswiki::Contrib::MailerContrib::Subscriber::BEGIN@23 which was called:
# once (9µs+0s) by Foswiki::Contrib::MailerContrib::WebNotify::BEGIN@23 at line 23 # spent 9µs making 1 call to Foswiki::Contrib::MailerContrib::Subscriber::BEGIN@23 |
24 | |||||
25 | =begin TML | ||||
26 | |||||
27 | ---++ new($name) | ||||
28 | * =$name= - Wikiname, with no web, or email address, of user targeted for notification | ||||
29 | Create a new user. | ||||
30 | |||||
31 | =cut | ||||
32 | |||||
33 | # spent 11.4ms within Foswiki::Contrib::MailerContrib::Subscriber::new which was called 1066 times, avg 11µs/call:
# 1066 times (11.4ms+0s) by Foswiki::Contrib::MailerContrib::WebNotify::getSubscriber at line 94 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Contrib/MailerContrib/WebNotify.pm, avg 11µs/call | ||||
34 | 3198 | 13.9ms | my ( $class, $name ) = @_; | ||
35 | my $this = bless( { name => $name }, $class ); | ||||
36 | |||||
37 | return $this; | ||||
38 | } | ||||
39 | |||||
40 | =begin TML | ||||
41 | |||||
42 | ---++ getEmailAddresses() -> \@list | ||||
43 | Get a list of email addresses for the user(s) represented by this | ||||
44 | subscription | ||||
45 | |||||
46 | =cut | ||||
47 | |||||
48 | sub getEmailAddresses { | ||||
49 | my $this = shift; | ||||
50 | |||||
51 | unless ( defined( $this->{emails} ) ) { | ||||
52 | $this->{emails} = getEmailAddressesForUser( $this->{name} ); | ||||
53 | } | ||||
54 | return $this->{emails}; | ||||
55 | } | ||||
56 | |||||
57 | =begin TML | ||||
58 | |||||
59 | ---++ STATIC getEmailAddressesForUser() -> \@list | ||||
60 | Get a list of email addresses for the user(s) represented by this | ||||
61 | subscription. Static method provided for use by other modules. | ||||
62 | |||||
63 | =cut | ||||
64 | |||||
65 | sub getEmailAddressesForUser { | ||||
66 | my $name = shift; | ||||
67 | my $emails = []; | ||||
68 | |||||
69 | return $emails unless $name; | ||||
70 | |||||
71 | if ( $name =~ /^$Foswiki::cfg{MailerContrib}{EmailFilterIn}$/ ) { | ||||
72 | push( @{$emails}, $name ); | ||||
73 | } | ||||
74 | else { | ||||
75 | my $users = $Foswiki::Plugins::SESSION->{users}; | ||||
76 | if ( $users->can('findUserByWikiName') ) { | ||||
77 | |||||
78 | # User is represented by a wikiname. Map to a canonical | ||||
79 | # userid. | ||||
80 | my $list = $users->findUserByWikiName($name); | ||||
81 | foreach my $user (@$list) { | ||||
82 | |||||
83 | # Automatically expands groups | ||||
84 | push( @{$emails}, $users->getEmails($user) ); | ||||
85 | } | ||||
86 | } | ||||
87 | else { | ||||
88 | |||||
89 | # Old code; use the user object | ||||
90 | my $user = $users->findUser( $name, undef, 1 ); | ||||
91 | if ($user) { | ||||
92 | push( @{$emails}, $user->emails() ); | ||||
93 | } | ||||
94 | else { | ||||
95 | $user = $users->findUser( $name, $name, 1 ); | ||||
96 | if ($user) { | ||||
97 | push( @{$emails}, $user->emails() ); | ||||
98 | } | ||||
99 | else { | ||||
100 | |||||
101 | # unknown - can't find an email | ||||
102 | $emails = []; | ||||
103 | } | ||||
104 | } | ||||
105 | } | ||||
106 | } | ||||
107 | return $emails; | ||||
108 | } | ||||
109 | |||||
110 | # Add a subscription to an internal list, optimising the list so that | ||||
111 | # the fewest subscriptions are kept that are needed to cover all | ||||
112 | # topics. | ||||
113 | # spent 163s (28.7+134) within Foswiki::Contrib::MailerContrib::Subscriber::_addAndOptimise which was called 12180 times, avg 13.4ms/call:
# 12180 times (28.7s+134s) by Foswiki::Contrib::MailerContrib::Subscriber::subscribe at line 165, avg 13.4ms/call | ||||
114 | 73076 | 249ms | my ( $this, $set, $new ) = @_; | ||
115 | |||||
116 | # Don't add already covered duplicates | ||||
117 | my $i = 0; | ||||
118 | my @remove; | ||||
119 | 12180 | 25.0ms | foreach my $known ( @{ $this->{$set} } ) { | ||
120 | 5680412 | 24.7s | 1893472 | 67.5s | return if $known->covers($new); # spent 67.5s making 1893472 calls to Foswiki::Contrib::MailerContrib::Subscription::covers, avg 36µs/call |
121 | 1893470 | 66.8s | if ( $new->covers($known) ) { # spent 66.8s making 1893470 calls to Foswiki::Contrib::MailerContrib::Subscription::covers, avg 35µs/call | ||
122 | |||||
123 | # remove anything covered by the new subscription | ||||
124 | unshift( @remove, $i ); | ||||
125 | } | ||||
126 | $i++; | ||||
127 | } | ||||
128 | foreach $i (@remove) { | ||||
129 | splice( @{ $this->{$set} }, $i, 1 ); | ||||
130 | } | ||||
131 | 12178 | 25.8ms | push( @{ $this->{$set} }, $new ); | ||
132 | } | ||||
133 | |||||
134 | # Subtract a subscription from an internal list. Do the best job | ||||
135 | # you can in the face of wildcards. | ||||
136 | # spent 204ms within Foswiki::Contrib::MailerContrib::Subscriber::_subtract which was called 12180 times, avg 17µs/call:
# 12180 times (204ms+0s) by Foswiki::Contrib::MailerContrib::Subscriber::subscribe at line 166, avg 17µs/call | ||||
137 | 60900 | 196ms | my ( $this, $set, $new ) = @_; | ||
138 | |||||
139 | my $i = 0; | ||||
140 | my @remove; | ||||
141 | 12180 | 22.9ms | foreach my $known ( @{ $this->{$set} } ) { | ||
142 | if ( $new->covers($known) ) { | ||||
143 | |||||
144 | # remove anything covered by the new subscription | ||||
145 | unshift( @remove, $i ); | ||||
146 | } | ||||
147 | $i++; | ||||
148 | } | ||||
149 | foreach $i (@remove) { | ||||
150 | splice( @{ $this->{$set} }, $i, 1 ); | ||||
151 | } | ||||
152 | } | ||||
153 | |||||
154 | =begin TML | ||||
155 | |||||
156 | ---++ subscribe($subs) | ||||
157 | * =$subs= - Subscription object | ||||
158 | Add a new subscription to this subscriber object. | ||||
159 | |||||
160 | =cut | ||||
161 | |||||
162 | # spent 163s (220ms+163) within Foswiki::Contrib::MailerContrib::Subscriber::subscribe which was called 12180 times, avg 13.4ms/call:
# 12180 times (220ms+163s) by Foswiki::Contrib::MailerContrib::WebNotify::subscribe at line 146 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Contrib/MailerContrib/WebNotify.pm, avg 13.4ms/call | ||||
163 | 36540 | 188ms | my ( $this, $subs ) = @_; | ||
164 | |||||
165 | 12180 | 163s | $this->_addAndOptimise( 'subscriptions', $subs ); # spent 163s making 12180 calls to Foswiki::Contrib::MailerContrib::Subscriber::_addAndOptimise, avg 13.4ms/call | ||
166 | 12180 | 204ms | $this->_subtract( 'unsubscriptions', $subs ); # spent 204ms making 12180 calls to Foswiki::Contrib::MailerContrib::Subscriber::_subtract, avg 17µs/call | ||
167 | } | ||||
168 | |||||
169 | =begin TML | ||||
170 | |||||
171 | ---++ unsubscribe($subs) | ||||
172 | * =$subs= - Subscription object | ||||
173 | Add a new unsubscription to this subscriber object. | ||||
174 | The unsubscription will always be added, even if there is | ||||
175 | a wildcard overlap with an existing subscription or unsubscription. | ||||
176 | |||||
177 | An unsubscription is a statement of the subscribers desire _not_ | ||||
178 | to be notified of changes to this topic. | ||||
179 | |||||
180 | =cut | ||||
181 | |||||
182 | sub unsubscribe { | ||||
183 | my ( $this, $subs ) = @_; | ||||
184 | |||||
185 | $this->_addAndOptimise( 'unsubscriptions', $subs ); | ||||
186 | if ( $subs->matches('*') ) { | ||||
187 | |||||
188 | # -* makes no sense and causes evaluation problems. | ||||
189 | $this->_subtract( 'unsubscriptions', $subs ); | ||||
190 | } | ||||
191 | $this->_subtract( 'subscriptions', $subs ); | ||||
192 | |||||
193 | #TODO: should look at removing redundant exclusions ie a - SubScribe (2) when there is no positive subscription | ||||
194 | |||||
195 | #if there are no subscriptions, there is no point luging around the unsubs | ||||
196 | if ( scalar( @{ $this->{'subscriptions'} } ) == 0 ) { | ||||
197 | undef @{ $this->{'unsubscriptions'} }; | ||||
198 | } | ||||
199 | } | ||||
200 | |||||
201 | =begin TML | ||||
202 | |||||
203 | ---++ isSubscribedTo($topic, $db) -> $subscription | ||||
204 | * =$topic= - Topic object we are checking | ||||
205 | * =$db= - Foswiki::Contrib::MailerContrib::UpData database of parents | ||||
206 | Check if we have a subscription to the given topic. Return the subscription | ||||
207 | that matches if we do, undef otherwise. | ||||
208 | |||||
209 | =cut | ||||
210 | |||||
211 | # spent 21.5ms (5.53+16.0) within Foswiki::Contrib::MailerContrib::Subscriber::isSubscribedTo which was called 2 times, avg 10.8ms/call:
# 2 times (5.53ms+16.0ms) by Foswiki::Contrib::MailerContrib::_isSubscribedToTopic at line 168 of /usr/local/src/github.com/foswiki/core/lib/Foswiki/Contrib/MailerContrib.pm, avg 10.8ms/call | ||||
212 | 6 | 38µs | my ( $this, $topic, $db ) = @_; | ||
213 | |||||
214 | 2 | 4µs | foreach my $subscription ( @{ $this->{subscriptions} } ) { | ||
215 | 718 | 4.56ms | 718 | 16.0ms | if ( $subscription->matches( $topic, $db ) ) { # spent 16.0ms making 718 calls to Foswiki::Contrib::MailerContrib::Subscription::matches, avg 22µs/call |
216 | return $subscription; | ||||
217 | } | ||||
218 | } | ||||
219 | |||||
220 | return; | ||||
221 | } | ||||
222 | |||||
223 | =begin TML | ||||
224 | |||||
225 | ---++ isUnsubscribedFrom($topic) -> $subscription | ||||
226 | * =$topic= - Topic object we are checking | ||||
227 | * =$db= - Foswiki::Contrib::MailerContrib::UpData database of parents | ||||
228 | Check if we have an unsubscription from the given topic. Return the subscription that matches if we do, undef otherwise. | ||||
229 | |||||
230 | =cut | ||||
231 | |||||
232 | sub isUnsubscribedFrom { | ||||
233 | my ( $this, $topic, $db ) = @_; | ||||
234 | |||||
235 | foreach my $subscription ( @{ $this->{unsubscriptions} } ) { | ||||
236 | if ( $subscription->matches( $topic, $db ) ) { | ||||
237 | return $subscription; | ||||
238 | } | ||||
239 | } | ||||
240 | |||||
241 | return; | ||||
242 | } | ||||
243 | |||||
244 | =begin TML | ||||
245 | |||||
246 | ---++ stringify() -> string | ||||
247 | Return a string representation of this object, in Web<nop>Notify format. | ||||
248 | |||||
249 | =cut | ||||
250 | |||||
251 | sub stringify { | ||||
252 | my $this = shift; | ||||
253 | my $subs = | ||||
254 | join( ' ', map { $_->stringify(); } @{ $this->{subscriptions} } ); | ||||
255 | my $unsubs = | ||||
256 | join( " - ", map { $_->stringify(); } @{ $this->{unsubscriptions} } ); | ||||
257 | $unsubs = " - $unsubs" if $unsubs; | ||||
258 | |||||
259 | my $name = $this->{name}; | ||||
260 | if ( $name =~ /^$Foswiki::regex{wikiWordRegex}$/ ) { | ||||
261 | $name = '%USERSWEB%.' . $name; | ||||
262 | } | ||||
263 | elsif ( $name !~ /^$Foswiki::cfg{MailerContrib}{EmailFilterIn}$/ ) { | ||||
264 | $name = $name =~ /'/ ? '"' . $name . '"' : "'$name'"; | ||||
265 | } | ||||
266 | return " * " . $name . ": " . $subs . $unsubs; | ||||
267 | } | ||||
268 | |||||
269 | 1 | 4µs | 1; | ||
270 | __END__ |