Filename | /usr/local/libexec/sympa/Sympa/Robot.pm |
Statements | Executed 214766 statements in 555ms |
Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
---|---|---|---|---|---|
2070 | 2 | 1 | 240ms | 377ms | _load_topics_get_title | Sympa::Robot::
1507 | 1 | 1 | 227ms | 2.30s | load_topics | Sympa::Robot::
1507 | 1 | 1 | 47.7ms | 2.35s | topic_keys | Sympa::Robot::
130065 | 2 | 1 | 42.2ms | 42.2ms | CORE:match (opcode) | Sympa::Robot::
1507 | 2 | 1 | 26.6ms | 24.9s | list_params | Sympa::Robot::
7535 | 2 | 1 | 3.58ms | 3.58ms | CORE:sort (opcode) | Sympa::Robot::
345 | 1 | 1 | 3.04ms | 3.04ms | CORE:fteread (opcode) | Sympa::Robot::
690 | 1 | 1 | 2.68ms | 2.68ms | _add_topic | Sympa::Robot::
0 | 0 | 0 | 0s | 0s | BEGIN@30 | Sympa::Robot::
0 | 0 | 0 | 0s | 0s | BEGIN@31 | Sympa::Robot::
0 | 0 | 0 | 0s | 0s | BEGIN@32 | Sympa::Robot::
0 | 0 | 0 | 0s | 0s | BEGIN@34 | Sympa::Robot::
0 | 0 | 0 | 0s | 0s | BEGIN@35 | Sympa::Robot::
0 | 0 | 0 | 0s | 0s | BEGIN@36 | Sympa::Robot::
0 | 0 | 0 | 0s | 0s | BEGIN@37 | Sympa::Robot::
0 | 0 | 0 | 0s | 0s | BEGIN@38 | Sympa::Robot::
0 | 0 | 0 | 0s | 0s | BEGIN@39 | Sympa::Robot::
0 | 0 | 0 | 0s | 0s | BEGIN@40 | Sympa::Robot::
0 | 0 | 0 | 0s | 0s | BEGIN@41 | Sympa::Robot::
0 | 0 | 0 | 0s | 0s | __ANON__ (xsub) | Sympa::Robot::
0 | 0 | 0 | 0s | 0s | _topic_get_title | Sympa::Robot::
0 | 0 | 0 | 0s | 0s | get_netidtoemail_db | Sympa::Robot::
0 | 0 | 0 | 0s | 0s | set_netidtoemail_db | Sympa::Robot::
0 | 0 | 0 | 0s | 0s | topic_get_title | Sympa::Robot::
0 | 0 | 0 | 0s | 0s | update_email_netidmap_db | Sympa::Robot::
Line | State ments |
Time on line |
Calls | Time in subs |
Code |
---|---|---|---|---|---|
1 | # -*- indent-tabs-mode: nil; -*- | ||||
2 | # vim:ft=perl:et:sw=4 | ||||
3 | # $Id$ | ||||
4 | |||||
5 | # Sympa - SYsteme de Multi-Postage Automatique | ||||
6 | # | ||||
7 | # Copyright (c) 1997, 1998, 1999 Institut Pasteur & Christophe Wolfhugel | ||||
8 | # Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, | ||||
9 | # 2006, 2007, 2008, 2009, 2010, 2011 Comite Reseau des Universites | ||||
10 | # Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016, 2017 GIP RENATER | ||||
11 | # Copyright 2017, 2020 The Sympa Community. See the AUTHORS.md | ||||
12 | # file at the top-level directory of this distribution and at | ||||
13 | # <https://github.com/sympa-community/sympa.git>. | ||||
14 | # | ||||
15 | # This program is free software; you can redistribute it and/or modify | ||||
16 | # it under the terms of the GNU General Public License as published by | ||||
17 | # the Free Software Foundation; either version 2 of the License, or | ||||
18 | # (at your option) any later version. | ||||
19 | # | ||||
20 | # This program is distributed in the hope that it will be useful, | ||||
21 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
22 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
23 | # GNU General Public License for more details. | ||||
24 | # | ||||
25 | # You should have received a copy of the GNU General Public License | ||||
26 | # along with this program. If not, see <http://www.gnu.org/licenses/>. | ||||
27 | |||||
28 | package Sympa::Robot; | ||||
29 | |||||
30 | use strict; | ||||
31 | use warnings; | ||||
32 | use Encode qw(); | ||||
33 | |||||
34 | use Sympa; | ||||
35 | use Conf; | ||||
36 | use Sympa::DatabaseManager; | ||||
37 | use Sympa::Language; | ||||
38 | use Sympa::ListDef; | ||||
39 | use Sympa::Log; | ||||
40 | use Sympa::Tools::Data; | ||||
41 | use Sympa::Tools::File; | ||||
42 | |||||
43 | my $language = Sympa::Language->instance; | ||||
44 | my $log = Sympa::Log->instance; | ||||
45 | |||||
46 | ## Database and SQL statement handlers | ||||
47 | my ($sth, @sth_stack); | ||||
48 | |||||
49 | our %list_of_topics = (); | ||||
50 | ## Last modification times | ||||
51 | our %mtime; | ||||
52 | |||||
53 | our %listmaster_messages_stack; | ||||
54 | |||||
55 | # MOVED: Use Sympa::send_file(), or Sympa::Message::Template::new() with | ||||
56 | # Sympa::Mailer::send_message(). | ||||
57 | # sub send_global_file($tpl, $who, $robot, $context, $options); | ||||
58 | |||||
59 | # MOVED: Use Sympa::send_notify_to_listmaster() or | ||||
60 | # Sympa::Spool::Listmaster::flush(). | ||||
61 | # sub send_notify_to_listmaster($operation, $robot, $data, $checkstack, $purge); | ||||
62 | |||||
63 | ## Is the user listmaster | ||||
64 | # MOVED: Use Sympa::is_listmaster(). | ||||
65 | #sub is_listmaster; | ||||
66 | |||||
67 | ## get idp xref to locally validated email address | ||||
68 | sub get_netidtoemail_db { | ||||
69 | my $robot = shift; | ||||
70 | my $netid = shift; | ||||
71 | my $idpname = shift; | ||||
72 | $log->syslog('debug', '(%s, %s)', $netid, $idpname); | ||||
73 | |||||
74 | my ($l, %which, $email); | ||||
75 | |||||
76 | push @sth_stack, $sth; | ||||
77 | |||||
78 | my $sdm = Sympa::DatabaseManager->instance; | ||||
79 | unless ( | ||||
80 | $sdm | ||||
81 | and $sth = $sdm->do_prepared_query( | ||||
82 | q{SELECT email_netidmap | ||||
83 | FROM netidmap_table | ||||
84 | WHERE netid_netidmap = ? and serviceid_netidmap = ? and | ||||
85 | robot_netidmap = ?}, | ||||
86 | $netid, $idpname, | ||||
87 | $robot | ||||
88 | ) | ||||
89 | ) { | ||||
90 | $log->syslog( | ||||
91 | 'err', | ||||
92 | 'Unable to get email address from netidmap_table for id %s, service %s, robot %s', | ||||
93 | $netid, | ||||
94 | $idpname, | ||||
95 | $robot | ||||
96 | ); | ||||
97 | return undef; | ||||
98 | } | ||||
99 | |||||
100 | $email = $sth->fetchrow; | ||||
101 | |||||
102 | $sth->finish(); | ||||
103 | |||||
104 | $sth = pop @sth_stack; | ||||
105 | |||||
106 | return $email; | ||||
107 | } | ||||
108 | |||||
109 | ## set idp xref to locally validated email address | ||||
110 | sub set_netidtoemail_db { | ||||
111 | my $robot = shift; | ||||
112 | my $netid = shift; | ||||
113 | my $idpname = shift; | ||||
114 | my $email = shift; | ||||
115 | $log->syslog('debug', '(%s, %s, %s)', $netid, $idpname, $email); | ||||
116 | |||||
117 | my ($l, %which); | ||||
118 | |||||
119 | my $sdm = Sympa::DatabaseManager->instance; | ||||
120 | unless ( | ||||
121 | $sdm | ||||
122 | and $sdm->do_prepared_query( | ||||
123 | q{INSERT INTO netidmap_table | ||||
124 | (netid_netidmap, serviceid_netidmap, email_netidmap, | ||||
125 | robot_netidmap) | ||||
126 | VALUES (?, ?, ?, ?)}, | ||||
127 | $netid, $idpname, $email, $robot | ||||
128 | ) | ||||
129 | ) { | ||||
130 | $log->syslog( | ||||
131 | 'err', | ||||
132 | 'Unable to set email address %s in netidmap_table for id %s, service %s, robot %s', | ||||
133 | $email, | ||||
134 | $netid, | ||||
135 | $idpname, | ||||
136 | $robot | ||||
137 | ); | ||||
138 | return undef; | ||||
139 | } | ||||
140 | |||||
141 | return 1; | ||||
142 | } | ||||
143 | |||||
144 | ## Update netidmap table when user email address changes | ||||
145 | sub update_email_netidmap_db { | ||||
146 | my ($robot, $old_email, $new_email) = @_; | ||||
147 | |||||
148 | unless (defined $robot | ||||
149 | && defined $old_email | ||||
150 | && defined $new_email) { | ||||
151 | $log->syslog('err', 'Missing parameter'); | ||||
152 | return undef; | ||||
153 | } | ||||
154 | |||||
155 | my $sdm = Sympa::DatabaseManager->instance; | ||||
156 | unless ( | ||||
157 | $sdm | ||||
158 | and $sdm->do_prepared_query( | ||||
159 | q{UPDATE netidmap_table | ||||
160 | SET email_netidmap = ? | ||||
161 | WHERE email_netidmap = ? AND robot_netidmap = ?}, | ||||
162 | $new_email, | ||||
163 | $old_email, $robot | ||||
164 | ) | ||||
165 | ) { | ||||
166 | $log->syslog( | ||||
167 | 'err', | ||||
168 | 'Unable to set new email address %s in netidmap_table to replace old address %s for robot %s', | ||||
169 | $new_email, | ||||
170 | $old_email, | ||||
171 | $robot | ||||
172 | ); | ||||
173 | return undef; | ||||
174 | } | ||||
175 | |||||
176 | return 1; | ||||
177 | } | ||||
178 | |||||
179 | my $default_topics_visibility = 'noconceal'; | ||||
180 | |||||
181 | # Loads the list of topics if updated. | ||||
182 | # The topic names "others" and "topicsless" are reserved words therefore | ||||
183 | # ignored. Note: "other" is not reserved and may be used. | ||||
184 | # spent 2.30s (227ms+2.07) within Sympa::Robot::load_topics which was called 1507 times, avg 1.52ms/call:
# 1507 times (227ms+2.07s) by Sympa::Robot::topic_keys at line 365, avg 1.52ms/call | ||||
185 | 1507 | 300µs | my $robot = shift; | ||
186 | 1507 | 2.57ms | 1507 | 356ms | $log->syslog('debug2', '(%s)', $robot); # spent 356ms making 1507 calls to Sympa::Log::syslog, avg 236µs/call |
187 | |||||
188 | 1507 | 2.42ms | 1507 | 964ms | my $conf_file = Sympa::search_fullpath($robot, 'topics.conf'); # spent 964ms making 1507 calls to Sympa::search_fullpath, avg 640µs/call |
189 | |||||
190 | 1507 | 349µs | unless ($conf_file) { | ||
191 | $log->syslog('err', 'No topics.conf defined'); | ||||
192 | return; | ||||
193 | } | ||||
194 | |||||
195 | 1507 | 941µs | my $topics = {}; | ||
196 | |||||
197 | ## Load if not loaded or changed on disk | ||||
198 | 1507 | 3.80ms | 1162 | 37.8ms | if (!$list_of_topics{$robot} # spent 37.8ms making 1162 calls to Sympa::Tools::File::get_mtime, avg 33µs/call |
199 | or Sympa::Tools::File::get_mtime($conf_file) > | ||||
200 | $mtime{'topics'}{$robot}) { | ||||
201 | |||||
202 | ## delete previous list of topics | ||||
203 | 345 | 4.31ms | %list_of_topics = (); | ||
204 | |||||
205 | 345 | 3.69ms | 345 | 3.04ms | unless (-r $conf_file) { # spent 3.04ms making 345 calls to Sympa::Robot::CORE:fteread, avg 9µs/call |
206 | $log->syslog('err', 'Unable to read %s', $conf_file); | ||||
207 | return; | ||||
208 | } | ||||
209 | |||||
210 | 345 | 849µs | 345 | 53.4ms | my $config_content = Sympa::Tools::Text::slurp($conf_file); # spent 53.4ms making 345 calls to Sympa::Tools::Text::slurp, avg 155µs/call |
211 | 345 | 130µs | unless (defined $config_content) { | ||
212 | $log->syslog('err', 'Unable to open config file %s', $conf_file); | ||||
213 | return; | ||||
214 | } | ||||
215 | |||||
216 | ## Rough parsing | ||||
217 | 345 | 139µs | my $index = 0; | ||
218 | 345 | 110µs | my (@rough_data, $topic); | ||
219 | 345 | 26.3ms | foreach my $line (split /(?<=\n)(?=\n|.)/, $config_content) { | ||
220 | 15180 | 113ms | 45195 | 25.2ms | if ($line =~ /\A(others|topicsless)\s*\z/i) { # spent 25.2ms making 45195 calls to Sympa::Robot::CORE:match, avg 557ns/call |
221 | # "others" and "topicsless" are reserved words. Ignore. | ||||
222 | next; | ||||
223 | } elsif ($line =~ /^([\-\w\/]+)\s*$/) { | ||||
224 | 2070 | 246µs | $index++; | ||
225 | 2070 | 2.30ms | $topic = { | ||
226 | 'name' => lc($1), | ||||
227 | 'order' => $index | ||||
228 | }; | ||||
229 | } elsif ($line =~ /^([\w\.]+)\s+(.+\S)\s*$/) { | ||||
230 | 11385 | 2.07ms | next unless defined $topic->{'name'}; | ||
231 | |||||
232 | 11385 | 6.75ms | $topic->{$1} = $2; | ||
233 | } elsif ($line =~ /^\s*$/) { | ||||
234 | 1725 | 379µs | next unless defined $topic->{'name'}; | ||
235 | |||||
236 | 1725 | 380µs | push @rough_data, $topic; | ||
237 | 1725 | 405µs | $topic = {}; | ||
238 | } | ||||
239 | } | ||||
240 | |||||
241 | ## Last topic | ||||
242 | 345 | 284µs | if (defined $topic->{'name'}) { | ||
243 | 345 | 78µs | push @rough_data, $topic; | ||
244 | 345 | 80µs | $topic = {}; | ||
245 | } | ||||
246 | |||||
247 | 345 | 873µs | 345 | 9.83ms | $mtime{'topics'}{$robot} = Sympa::Tools::File::get_mtime($conf_file); # spent 9.83ms making 345 calls to Sympa::Tools::File::get_mtime, avg 28µs/call |
248 | |||||
249 | 345 | 272µs | unless ($#rough_data > -1) { | ||
250 | $log->syslog('notice', 'No topic defined in %s', $conf_file); | ||||
251 | return; | ||||
252 | } | ||||
253 | |||||
254 | ## Analysis | ||||
255 | 345 | 251µs | foreach my $topic (@rough_data) { | ||
256 | 2070 | 1.39ms | my @tree = split '/', $topic->{'name'}; | ||
257 | |||||
258 | 2070 | 1.47ms | if ($#tree == 0) { | ||
259 | 1380 | 1.39ms | 1380 | 260ms | my $title = _load_topics_get_title($topic); # spent 260ms making 1380 calls to Sympa::Robot::_load_topics_get_title, avg 189µs/call |
260 | 1380 | 1.26ms | $list_of_topics{$robot}{$tree[0]}{'title'} = $title; | ||
261 | $list_of_topics{$robot}{$tree[0]}{'visibility'} = | ||||
262 | 1380 | 1.02ms | $topic->{'visibility'} || $default_topics_visibility; | ||
263 | $list_of_topics{$robot}{$tree[0]}{'order'} = | ||||
264 | 1380 | 1.02ms | $topic->{'order'}; | ||
265 | } else { | ||||
266 | 690 | 842µs | my $subtopic = join('/', @tree[1 .. $#tree]); | ||
267 | 690 | 572µs | 690 | 116ms | my $title = _load_topics_get_title($topic); # spent 116ms making 690 calls to Sympa::Robot::_load_topics_get_title, avg 168µs/call |
268 | my $visibility = | ||||
269 | 690 | 292µs | $topic->{'visibility'} || $default_topics_visibility; | ||
270 | 690 | 1.52ms | 690 | 2.68ms | $list_of_topics{$robot}{$tree[0]}{'sub'}{$subtopic} = # spent 2.68ms making 690 calls to Sympa::Robot::_add_topic, avg 4µs/call |
271 | _add_topic($subtopic, $title, $visibility); | ||||
272 | } | ||||
273 | } | ||||
274 | |||||
275 | ## Set undefined Topic (defined via subtopic) | ||||
276 | 345 | 2.01ms | foreach my $t (keys %{$list_of_topics{$robot}}) { | ||
277 | 1380 | 621µs | unless (defined $list_of_topics{$robot}{$t}{'title'}) { | ||
278 | $list_of_topics{$robot}{$t}{'title'} = {'default' => $t}; | ||||
279 | } | ||||
280 | } | ||||
281 | } | ||||
282 | |||||
283 | ## Set the title in the current language | ||||
284 | 1507 | 2.29ms | 1507 | 2.15ms | my $lang = $language->get_lang; # spent 2.15ms making 1507 calls to Sympa::Language::get_lang, avg 1µs/call |
285 | 1507 | 2.82ms | foreach my $top (keys %{$list_of_topics{$robot}}) { | ||
286 | 6028 | 2.18ms | my $topic = $list_of_topics{$robot}{$top}; | ||
287 | 6028 | 6.05ms | 6028 | 169ms | foreach my $l (Sympa::Language::implicated_langs($lang)) { # spent 169ms making 6028 calls to Sympa::Language::implicated_langs, avg 28µs/call |
288 | 6028 | 3.22ms | if (exists $topic->{'title'}{$l}) { | ||
289 | $topic->{'current_title'} = $topic->{'title'}{$l}; | ||||
290 | } | ||||
291 | } | ||||
292 | 6028 | 1.70ms | unless (exists $topic->{'current_title'}) { | ||
293 | if (exists $topic->{'title'}{'gettext'}) { | ||||
294 | $topic->{'current_title'} = | ||||
295 | $language->gettext($topic->{'title'}{'gettext'}); | ||||
296 | } else { | ||||
297 | 1380 | 663µs | $topic->{'current_title'} = $topic->{'title'}{'default'} | ||
298 | || $top; | ||||
299 | } | ||||
300 | } | ||||
301 | |||||
302 | 6028 | 6.39ms | foreach my $subtop (keys %{$topic->{'sub'}}) { | ||
303 | 3014 | 2.77ms | 3014 | 71.2ms | foreach my $l (Sympa::Language::implicated_langs($lang)) { # spent 71.2ms making 3014 calls to Sympa::Language::implicated_langs, avg 24µs/call |
304 | 3014 | 2.04ms | if (exists $topic->{'sub'}{$subtop}{'title'}{$l}) { | ||
305 | $topic->{'sub'}{$subtop}{'current_title'} = | ||||
306 | $topic->{'sub'}{$subtop}{'title'}{$l}; | ||||
307 | } | ||||
308 | } | ||||
309 | 3014 | 1.73ms | unless (exists $topic->{'sub'}{$subtop}{'current_title'}) { | ||
310 | if (exists $topic->{'sub'}{$subtop}{'title'}{'gettext'}) { | ||||
311 | $topic->{'sub'}{$subtop}{'current_title'} = | ||||
312 | $language->gettext( | ||||
313 | $topic->{'sub'}{$subtop}{'title'}{'gettext'}); | ||||
314 | } else { | ||||
315 | $topic->{'sub'}{$subtop}{'current_title'} = | ||||
316 | 690 | 476µs | $topic->{'sub'}{$subtop}{'title'}{'default'} | ||
317 | || $subtop; | ||||
318 | } | ||||
319 | } | ||||
320 | } | ||||
321 | } | ||||
322 | |||||
323 | 1507 | 4.36ms | return %{$list_of_topics{$robot}}; | ||
324 | } | ||||
325 | |||||
326 | # Old name: _get_topic_titles(). | ||||
327 | sub _load_topics_get_title { | ||||
328 | 2070 | 345µs | my $topic = shift; | ||
329 | |||||
330 | 2070 | 265µs | my $title; | ||
331 | 2070 | 2.93ms | foreach my $key (%{$topic}) { | ||
332 | 31050 | 230ms | 84870 | 17.0ms | if ($key =~ /^title\.gettext$/i) { # spent 17.0ms making 84870 calls to Sympa::Robot::CORE:match, avg 201ns/call |
333 | $title->{'gettext'} = $topic->{$key}; | ||||
334 | } elsif ($key =~ /^title\.(\S+)$/i) { | ||||
335 | 8280 | 2.27ms | my $lang = $1; | ||
336 | # canonicalize lang if possible. | ||||
337 | 8280 | 5.91ms | 8280 | 120ms | $lang = Sympa::Language::canonic_lang($lang) || $lang; # spent 120ms making 8280 calls to Sympa::Language::canonic_lang, avg 14µs/call |
338 | 8280 | 4.15ms | $title->{$lang} = $topic->{$key}; | ||
339 | } elsif ($key =~ /^title$/i) { | ||||
340 | $title->{'default'} = $topic->{$key}; | ||||
341 | } | ||||
342 | } | ||||
343 | |||||
344 | 2070 | 2.50ms | return $title; | ||
345 | } | ||||
346 | |||||
347 | ## Inner sub used by load_topics() | ||||
348 | # spent 2.68ms within Sympa::Robot::_add_topic which was called 690 times, avg 4µs/call:
# 690 times (2.68ms+0s) by Sympa::Robot::load_topics at line 270, avg 4µs/call | ||||
349 | 690 | 381µs | my ($name, $title, $visibility) = @_; | ||
350 | 690 | 262µs | my $topic = {}; | ||
351 | |||||
352 | 690 | 419µs | my @tree = split '/', $name; | ||
353 | 690 | 1.83ms | if ($#tree == 0) { | ||
354 | return {'title' => $title, 'visibility' => $visibility}; | ||||
355 | } else { | ||||
356 | $topic->{'sub'}{$name} = | ||||
357 | _add_topic(join('/', @tree[1 .. $#tree]), $title, $visibility); | ||||
358 | return $topic; | ||||
359 | } | ||||
360 | } | ||||
361 | |||||
362 | # spent 2.35s (47.7ms+2.30) within Sympa::Robot::topic_keys which was called 1507 times, avg 1.56ms/call:
# 1507 times (47.7ms+2.30s) by Sympa::Robot::list_params at line 446, avg 1.56ms/call | ||||
363 | 1507 | 490µs | my $robot_id = shift; | ||
364 | |||||
365 | 1507 | 3.49ms | 1507 | 2.30s | my %topics = Sympa::Robot::load_topics($robot_id); # spent 2.30s making 1507 calls to Sympa::Robot::load_topics, avg 1.52ms/call |
366 | return map { | ||||
367 | 7535 | 16.6ms | 1507 | 2.56ms | my $topic = $_; # spent 2.56ms making 1507 calls to Sympa::Robot::CORE:sort, avg 2µs/call |
368 | 6028 | 30.3ms | 6028 | 1.02ms | if ($topics{$topic}->{sub}) { # spent 1.02ms making 6028 calls to Sympa::Robot::CORE:sort, avg 170ns/call |
369 | ( $topic, | ||||
370 | map { $topic . '/' . $_ } sort keys %{$topics{$topic}->{sub}} | ||||
371 | ); | ||||
372 | } else { | ||||
373 | ($topic); | ||||
374 | } | ||||
375 | } sort keys %topics; | ||||
376 | } | ||||
377 | |||||
378 | sub topic_get_title { | ||||
379 | my $robot_id = shift; | ||||
380 | my $topic = shift; | ||||
381 | |||||
382 | my $tinfo = {Sympa::Robot::load_topics($robot_id)}; | ||||
383 | return unless %$tinfo; | ||||
384 | |||||
385 | my @ttitles; | ||||
386 | my @tpaths = split '/', $topic; | ||||
387 | |||||
388 | while (1) { | ||||
389 | my $t = shift @tpaths; | ||||
390 | unless (exists $tinfo->{$t}) { | ||||
391 | @ttitles = (); | ||||
392 | last; | ||||
393 | } elsif (not @tpaths) { | ||||
394 | push @ttitles, (_topic_get_title($tinfo->{$t}) || $t); | ||||
395 | last; | ||||
396 | } elsif (not $tinfo->{$t}->{sub}) { | ||||
397 | @ttitles = (); | ||||
398 | last; | ||||
399 | } else { | ||||
400 | push @ttitles, (_topic_get_title($tinfo->{$t}) || $t); | ||||
401 | $tinfo = $tinfo->{$t}->{sub}; | ||||
402 | } | ||||
403 | } | ||||
404 | |||||
405 | return @ttitles if wantarray; | ||||
406 | return join ' / ', @ttitles; | ||||
407 | } | ||||
408 | |||||
409 | sub _topic_get_title { | ||||
410 | my $titem = shift; | ||||
411 | |||||
412 | return undef unless $titem and exists $titem->{title}; | ||||
413 | |||||
414 | foreach my $lang (Sympa::Language::implicated_langs($language->get_lang)) | ||||
415 | { | ||||
416 | return $titem->{title}->{$lang} | ||||
417 | if $titem->{title}->{$lang}; | ||||
418 | } | ||||
419 | if ($titem->{title}->{gettext}) { | ||||
420 | return $language->gettext($titem->{title}->{gettext}); | ||||
421 | } elsif ($titem->{title}->{default}) { | ||||
422 | return $titem->{title}->{default}; | ||||
423 | } else { | ||||
424 | return undef; | ||||
425 | } | ||||
426 | } | ||||
427 | |||||
428 | =over 4 | ||||
429 | |||||
430 | =item list_params | ||||
431 | |||||
432 | I<Getter>. | ||||
433 | Returns hashref to list parameter information. | ||||
434 | |||||
435 | =back | ||||
436 | |||||
437 | =cut | ||||
438 | |||||
439 | # Old name: tools::get_list_params(). | ||||
440 | # spent 24.9s (26.6ms+24.9) within Sympa::Robot::list_params which was called 1507 times, avg 16.6ms/call:
# 1494 times (26.3ms+24.5s) by Sympa::List::_load_edit_list_conf at line 6158 of /usr/local/libexec/sympa/Sympa/List.pm, avg 16.4ms/call
# 13 times (255µs+407ms) by Sympa::List::_load_list_config_file at line 4987 of /usr/local/libexec/sympa/Sympa/List.pm, avg 31.3ms/call | ||||
441 | 1507 | 389µs | my $robot_id = shift; | ||
442 | |||||
443 | 1507 | 3.53ms | 1507 | 6.44s | my $pinfo = Sympa::Tools::Data::clone_var(\%Sympa::ListDef::pinfo); # spent 6.44s making 1507 calls to Sympa::Tools::Data::clone_var, avg 4.28ms/call |
444 | 1507 | 9.46ms | 1507 | 16.1s | $pinfo->{lang}{format} = [Sympa::get_supported_languages($robot_id)]; # spent 16.1s making 1507 calls to Sympa::get_supported_languages, avg 10.7ms/call |
445 | |||||
446 | 1507 | 2.78ms | 1507 | 2.35s | my @topics = Sympa::Robot::topic_keys($robot_id); # spent 2.35s making 1507 calls to Sympa::Robot::topic_keys, avg 1.56ms/call |
447 | 1507 | 2.50ms | $pinfo->{topics}{format} = [@topics]; | ||
448 | # Compat. | ||||
449 | 1507 | 2.83ms | $pinfo->{topics}{file_format} = sprintf '(%s)(,(%s))*', | ||
450 | join('|', @topics), | ||||
451 | join('|', @topics); | ||||
452 | |||||
453 | 1507 | 8.09ms | return $pinfo; | ||
454 | } | ||||
455 | |||||
456 | 1; | ||||
# spent 3.04ms within Sympa::Robot::CORE:fteread which was called 345 times, avg 9µs/call:
# 345 times (3.04ms+0s) by Sympa::Robot::load_topics at line 205, avg 9µs/call | |||||
sub Sympa::Robot::CORE:match; # opcode | |||||
sub Sympa::Robot::CORE:sort; # opcode |