| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
package Data::Microformat::hCard; |
|
2
|
13
|
|
|
13
|
|
5826
|
use base qw(Data::Microformat); |
|
|
13
|
|
|
|
|
23
|
|
|
|
13
|
|
|
|
|
5354
|
|
|
3
|
|
|
|
|
|
|
|
|
4
|
13
|
|
|
13
|
|
141
|
use strict; |
|
|
13
|
|
|
|
|
24
|
|
|
|
13
|
|
|
|
|
440
|
|
|
5
|
13
|
|
|
13
|
|
66
|
use warnings; |
|
|
13
|
|
|
|
|
29
|
|
|
|
13
|
|
|
|
|
616
|
|
|
6
|
|
|
|
|
|
|
|
|
7
|
|
|
|
|
|
|
our $VERSION = "0.04"; |
|
8
|
|
|
|
|
|
|
|
|
9
|
13
|
|
|
13
|
|
7742
|
use Data::Microformat::adr; |
|
|
13
|
|
|
|
|
29
|
|
|
|
13
|
|
|
|
|
344
|
|
|
10
|
13
|
|
|
13
|
|
6297
|
use Data::Microformat::geo; |
|
|
13
|
|
|
|
|
27
|
|
|
|
13
|
|
|
|
|
283
|
|
|
11
|
13
|
|
|
13
|
|
6672
|
use Data::Microformat::hCard::type; |
|
|
13
|
|
|
|
|
27
|
|
|
|
13
|
|
|
|
|
333
|
|
|
12
|
13
|
|
|
13
|
|
6837
|
use Data::Microformat::hCard::name; |
|
|
13
|
|
|
|
|
39
|
|
|
|
13
|
|
|
|
|
279
|
|
|
13
|
13
|
|
|
13
|
|
6943
|
use Data::Microformat::hCard::organization; |
|
|
13
|
|
|
|
|
28
|
|
|
|
13
|
|
|
|
|
30700
|
|
|
14
|
|
|
|
|
|
|
|
|
15
|
40
|
|
|
40
|
1
|
110
|
sub class_name { "vcard" } |
|
16
|
44
|
|
|
44
|
1
|
272
|
sub singular_fields { qw(fn n bday tz geo sort_string uid class) } |
|
17
|
44
|
|
|
44
|
1
|
272
|
sub plural_fields { qw(adr agent category email key label logo mailer nickname note org photo rev role sound tel title url) } |
|
18
|
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
sub is_representative |
|
20
|
|
|
|
|
|
|
{ |
|
21
|
7
|
|
|
7
|
1
|
12
|
my $self = shift; |
|
22
|
7
|
100
|
|
|
|
15
|
if ($self->{_representative}) |
|
23
|
|
|
|
|
|
|
{ |
|
24
|
3
|
|
|
|
|
11
|
return 1; |
|
25
|
|
|
|
|
|
|
} |
|
26
|
|
|
|
|
|
|
else |
|
27
|
|
|
|
|
|
|
{ |
|
28
|
4
|
|
|
|
|
15
|
return 0; |
|
29
|
|
|
|
|
|
|
} |
|
30
|
|
|
|
|
|
|
} |
|
31
|
|
|
|
|
|
|
|
|
32
|
|
|
|
|
|
|
sub from_tree |
|
33
|
|
|
|
|
|
|
{ |
|
34
|
17
|
|
|
17
|
1
|
39
|
my $class = shift; |
|
35
|
17
|
|
|
|
|
34
|
my $tree = shift; |
|
36
|
|
|
|
|
|
|
|
|
37
|
17
|
|
|
|
|
31
|
my $representative_url = shift; |
|
38
|
17
|
100
|
|
|
|
68
|
if ($representative_url) |
|
39
|
|
|
|
|
|
|
{ |
|
40
|
4
|
|
|
|
|
11
|
$representative_url = _normalize_url($representative_url); |
|
41
|
|
|
|
|
|
|
} |
|
42
|
|
|
|
|
|
|
|
|
43
|
|
|
|
|
|
|
|
|
44
|
17
|
|
|
|
|
41
|
my $rel_me = ""; |
|
45
|
|
|
|
|
|
|
|
|
46
|
17
|
|
|
|
|
26
|
my @all_cards; |
|
47
|
17
|
|
|
|
|
171
|
my @cards = $tree->look_down("class", qr/vcard/); |
|
48
|
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
#First: build the list of things we recognize; |
|
50
|
17
|
|
|
|
|
3151
|
my $recognized_regex = "("; |
|
51
|
17
|
|
|
|
|
152
|
foreach my $field ( ( Data::Microformat::adr->singular_fields, |
|
52
|
|
|
|
|
|
|
Data::Microformat::adr->plural_fields, |
|
53
|
|
|
|
|
|
|
Data::Microformat::adr->class_name, |
|
54
|
|
|
|
|
|
|
Data::Microformat::geo->singular_fields, |
|
55
|
|
|
|
|
|
|
Data::Microformat::geo->plural_fields, |
|
56
|
|
|
|
|
|
|
Data::Microformat::geo->class_name, |
|
57
|
|
|
|
|
|
|
Data::Microformat::hCard::name->singular_fields, |
|
58
|
|
|
|
|
|
|
Data::Microformat::hCard::name->plural_fields, |
|
59
|
|
|
|
|
|
|
Data::Microformat::hCard::name->class_name, |
|
60
|
|
|
|
|
|
|
Data::Microformat::hCard::organization->singular_fields, |
|
61
|
|
|
|
|
|
|
Data::Microformat::hCard::organization->plural_fields, |
|
62
|
|
|
|
|
|
|
Data::Microformat::hCard::organization->class_name, |
|
63
|
|
|
|
|
|
|
Data::Microformat::hCard::type->singular_fields, |
|
64
|
|
|
|
|
|
|
Data::Microformat::hCard::type->plural_fields, |
|
65
|
|
|
|
|
|
|
Data::Microformat::hCard::type->class_name, |
|
66
|
|
|
|
|
|
|
Data::Microformat::hCard->singular_fields, |
|
67
|
|
|
|
|
|
|
Data::Microformat::hCard->plural_fields, |
|
68
|
|
|
|
|
|
|
Data::Microformat::hCard->class_name, )) |
|
69
|
|
|
|
|
|
|
{ |
|
70
|
884
|
|
|
|
|
1023
|
$field =~ s/\_/\-/; |
|
71
|
884
|
|
|
|
|
1200
|
$recognized_regex .= '(^|\s)'.$field.'($|\s)|'; |
|
72
|
|
|
|
|
|
|
} |
|
73
|
17
|
|
|
|
|
96
|
chop($recognized_regex); |
|
74
|
17
|
|
|
|
|
29
|
$recognized_regex .= ")"; |
|
75
|
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
|
|
77
|
17
|
|
|
|
|
39
|
foreach my $card_tree (@cards) |
|
78
|
|
|
|
|
|
|
{ |
|
79
|
|
|
|
|
|
|
# Walk the tree looking for useless bits |
|
80
|
|
|
|
|
|
|
# Where class is undefined |
|
81
|
23
|
|
|
|
|
84
|
my @useless = $card_tree->look_down("class", undef); |
|
82
|
23
|
|
|
|
|
1986
|
foreach my $element (@useless) |
|
83
|
|
|
|
|
|
|
{ |
|
84
|
7
|
|
|
|
|
58
|
my @kids = $element->detach_content; |
|
85
|
7
|
|
|
|
|
85
|
my $parent = $element->detach; |
|
86
|
7
|
100
|
|
|
|
112
|
if (@kids) |
|
87
|
|
|
|
|
|
|
{ |
|
88
|
5
|
|
|
|
|
16
|
$parent->push_content(@kids); |
|
89
|
|
|
|
|
|
|
} |
|
90
|
7
|
|
|
|
|
139
|
$element->delete; |
|
91
|
|
|
|
|
|
|
} |
|
92
|
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
@useless = $card_tree->look_down(sub{ |
|
94
|
230
|
100
|
|
230
|
|
11232
|
if ($_[0]->attr('class')) |
|
95
|
|
|
|
|
|
|
{ |
|
96
|
229
|
|
|
|
|
2126
|
return $_[0]->attr('class') !~ m/$recognized_regex/; |
|
97
|
|
|
|
|
|
|
} |
|
98
|
|
|
|
|
|
|
else |
|
99
|
|
|
|
|
|
|
{ |
|
100
|
1
|
|
|
|
|
11
|
return 1; |
|
101
|
23
|
|
|
|
|
183
|
}}); |
|
102
|
|
|
|
|
|
|
|
|
103
|
23
|
|
|
|
|
676
|
foreach my $element (@useless) |
|
104
|
|
|
|
|
|
|
{ |
|
105
|
1
|
|
|
|
|
4
|
my @kids = $element->detach_content; |
|
106
|
1
|
|
|
|
|
7
|
my $parent = $element->detach; |
|
107
|
1
|
50
|
|
|
|
7
|
if (@kids) |
|
108
|
|
|
|
|
|
|
{ |
|
109
|
0
|
|
|
|
|
0
|
$parent->push_content(@kids); |
|
110
|
|
|
|
|
|
|
} |
|
111
|
1
|
|
|
|
|
3
|
$element->delete; |
|
112
|
|
|
|
|
|
|
} |
|
113
|
|
|
|
|
|
|
|
|
114
|
23
|
|
|
|
|
202
|
my $card = Data::Microformat::hCard->new; |
|
115
|
23
|
|
|
|
|
116
|
$card->{_no_dupe_keys} = 1; |
|
116
|
|
|
|
|
|
|
|
|
117
|
23
|
|
|
|
|
92
|
my @bits = $card_tree->content_list; |
|
118
|
|
|
|
|
|
|
|
|
119
|
23
|
|
|
|
|
191
|
foreach my $bit (@bits) |
|
120
|
|
|
|
|
|
|
{ |
|
121
|
155
|
100
|
|
|
|
367
|
if (ref($bit) eq "HTML::Element") |
|
122
|
|
|
|
|
|
|
{ |
|
123
|
130
|
|
|
|
|
127
|
my $nested_goes_here; |
|
124
|
130
|
|
|
|
|
323
|
my $hcard_class = $bit->attr('class'); |
|
125
|
130
|
50
|
|
|
|
1182
|
next unless $hcard_class; |
|
126
|
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
#Check for nested vcard. |
|
128
|
130
|
100
|
|
|
|
292
|
if ($hcard_class =~ m/vcard/) |
|
129
|
|
|
|
|
|
|
{ |
|
130
|
|
|
|
|
|
|
#We have a nested class in here. Mark where it needs to go. |
|
131
|
1
|
|
|
|
|
1
|
my $temp_hcard_class = $hcard_class; |
|
132
|
1
|
|
|
|
|
4
|
$temp_hcard_class =~ s/vcard//; |
|
133
|
1
|
|
|
|
|
5
|
$temp_hcard_class = $class->_trim($temp_hcard_class); |
|
134
|
1
|
|
|
|
|
4
|
my @types = split(" ", $temp_hcard_class); |
|
135
|
1
|
50
|
|
|
|
5
|
if (scalar @types > 0) |
|
136
|
|
|
|
|
|
|
{ |
|
137
|
1
|
|
|
|
|
2
|
$nested_goes_here = $types[0]; |
|
138
|
1
|
|
|
|
|
12
|
$hcard_class =~ s/$nested_goes_here//; |
|
139
|
1
|
|
|
|
|
4
|
$hcard_class = $class->_trim($hcard_class); |
|
140
|
|
|
|
|
|
|
#We do this so that if the type is, for instance, |
|
141
|
|
|
|
|
|
|
# "agent vcard," that we just put the vcard in |
|
142
|
|
|
|
|
|
|
# agent, and not anywhere else. |
|
143
|
|
|
|
|
|
|
# vcard *MUST* have another class, otherwise we''ll |
|
144
|
|
|
|
|
|
|
# discard it. |
|
145
|
|
|
|
|
|
|
} |
|
146
|
|
|
|
|
|
|
} |
|
147
|
130
|
|
|
|
|
298
|
my @types = split(" ", $hcard_class); |
|
148
|
130
|
|
|
|
|
195
|
foreach my $type (@types) |
|
149
|
|
|
|
|
|
|
{ |
|
150
|
143
|
|
|
|
|
201
|
$type =~ s/\-/\_/; |
|
151
|
143
|
|
|
|
|
496
|
$type = $class->_trim($type); |
|
152
|
|
|
|
|
|
|
|
|
153
|
143
|
|
|
|
|
149
|
my $data; |
|
154
|
143
|
|
|
|
|
436
|
my @cons = $bit->content_list; |
|
155
|
|
|
|
|
|
|
|
|
156
|
143
|
100
|
|
|
|
1127
|
unless (scalar @cons > 1) |
|
157
|
|
|
|
|
|
|
{ |
|
158
|
114
|
|
|
|
|
327
|
$data = $class->_trim($cons[0]); |
|
159
|
114
|
100
|
66
|
|
|
336
|
if ($bit->tag eq "abbr" && $bit->attr('title')) |
|
|
|
100
|
66
|
|
|
|
|
|
|
|
100
|
66
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
{ |
|
161
|
9
|
|
|
|
|
209
|
$data = $class->_trim($bit->attr('title')); |
|
162
|
|
|
|
|
|
|
} |
|
163
|
|
|
|
|
|
|
elsif ($bit->tag eq "a" && $bit->attr('href')) |
|
164
|
|
|
|
|
|
|
{ |
|
165
|
38
|
100
|
|
|
|
940
|
if ($type =~ m/(photo|logo|agent|sound|url)/) |
|
166
|
|
|
|
|
|
|
{ |
|
167
|
28
|
|
|
|
|
74
|
$data = $class->_trim($class->_url_decode($bit->attr('href'))); |
|
168
|
28
|
100
|
66
|
|
|
77
|
if ($bit->attr('rel') && $bit->attr('rel') eq "me") |
|
169
|
|
|
|
|
|
|
{ |
|
170
|
1
|
|
|
|
|
23
|
$rel_me = $data; |
|
171
|
|
|
|
|
|
|
} |
|
172
|
|
|
|
|
|
|
} |
|
173
|
|
|
|
|
|
|
} |
|
174
|
|
|
|
|
|
|
elsif ($bit->tag eq "object" && $bit->attr('data')) |
|
175
|
|
|
|
|
|
|
{ |
|
176
|
2
|
100
|
|
|
|
57
|
if ($type =~ m/(photo|logo|agent|sound|url)/) |
|
177
|
|
|
|
|
|
|
{ |
|
178
|
1
|
|
|
|
|
3
|
$data = $class->_trim($bit->attr('data')); |
|
179
|
|
|
|
|
|
|
} |
|
180
|
|
|
|
|
|
|
} |
|
181
|
|
|
|
|
|
|
elsif ($bit->tag eq "img") |
|
182
|
|
|
|
|
|
|
{ |
|
183
|
2
|
100
|
66
|
|
|
52
|
if ($type =~ m/(photo|logo|agent|sound|url)/ && $bit->attr('src')) |
|
|
|
50
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
{ |
|
185
|
1
|
|
|
|
|
13
|
$data = $class->_trim($bit->attr('src')); |
|
186
|
|
|
|
|
|
|
} |
|
187
|
|
|
|
|
|
|
elsif ($bit->attr('alt')) |
|
188
|
|
|
|
|
|
|
{ |
|
189
|
1
|
|
|
|
|
9
|
$data = $class->_trim($bit->attr('alt')); |
|
190
|
|
|
|
|
|
|
} |
|
191
|
|
|
|
|
|
|
} |
|
192
|
|
|
|
|
|
|
} |
|
193
|
|
|
|
|
|
|
|
|
194
|
143
|
100
|
|
|
|
2452
|
if ($type eq "vcard") |
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
{ |
|
196
|
1
|
|
|
|
|
27
|
my $nestedcard = $class->from_tree($bit); |
|
197
|
1
|
50
|
|
|
|
3
|
if ($nested_goes_here) |
|
198
|
|
|
|
|
|
|
{ |
|
199
|
1
|
|
|
|
|
9
|
$card->$nested_goes_here($nestedcard); |
|
200
|
|
|
|
|
|
|
} |
|
201
|
|
|
|
|
|
|
} |
|
202
|
|
|
|
|
|
|
elsif ($type eq "tel") |
|
203
|
|
|
|
|
|
|
{ |
|
204
|
10
|
|
|
|
|
61
|
my $tel = Data::Microformat::hCard::type->from_tree($bit); |
|
205
|
10
|
|
|
|
|
66
|
$card->tel($tel); |
|
206
|
|
|
|
|
|
|
} |
|
207
|
|
|
|
|
|
|
elsif ($type eq "email") |
|
208
|
|
|
|
|
|
|
{ |
|
209
|
7
|
|
|
|
|
34
|
my $email = Data::Microformat::hCard::type->from_tree($bit); |
|
210
|
7
|
|
|
|
|
50
|
$card->email($email); |
|
211
|
|
|
|
|
|
|
} |
|
212
|
|
|
|
|
|
|
elsif ($type eq "n") |
|
213
|
|
|
|
|
|
|
{ |
|
214
|
2
|
|
|
|
|
12
|
my $name = Data::Microformat::hCard::name->from_tree($bit); |
|
215
|
2
|
|
|
|
|
13
|
$card->n($name); |
|
216
|
|
|
|
|
|
|
} |
|
217
|
|
|
|
|
|
|
elsif ($type eq "adr") |
|
218
|
|
|
|
|
|
|
{ |
|
219
|
7
|
|
|
|
|
61
|
my $adr = Data::Microformat::adr->from_tree($bit); |
|
220
|
7
|
|
|
|
|
47
|
$card->adr($adr); |
|
221
|
|
|
|
|
|
|
} |
|
222
|
|
|
|
|
|
|
elsif ($type eq "geo") |
|
223
|
|
|
|
|
|
|
{ |
|
224
|
4
|
|
|
|
|
28
|
my $geo = Data::Microformat::geo->from_tree($bit); |
|
225
|
4
|
|
|
|
|
29
|
$card->geo($geo); |
|
226
|
|
|
|
|
|
|
} |
|
227
|
|
|
|
|
|
|
elsif ($type eq "org") |
|
228
|
|
|
|
|
|
|
{ |
|
229
|
6
|
|
|
|
|
29
|
my $org = Data::Microformat::hCard::organization->from_tree($bit); |
|
230
|
6
|
|
|
|
|
40
|
$card->org($org); |
|
231
|
|
|
|
|
|
|
} |
|
232
|
|
|
|
|
|
|
else |
|
233
|
|
|
|
|
|
|
{ |
|
234
|
106
|
|
|
|
|
311
|
eval { $card->$type($data); }; |
|
|
106
|
|
|
|
|
741
|
|
|
235
|
106
|
50
|
|
|
|
478
|
if ($@) |
|
236
|
|
|
|
|
|
|
{ |
|
237
|
0
|
|
|
|
|
0
|
print STDERR "Didn't recognize type $type.\n"; |
|
238
|
|
|
|
|
|
|
} |
|
239
|
|
|
|
|
|
|
} |
|
240
|
|
|
|
|
|
|
} |
|
241
|
|
|
|
|
|
|
} |
|
242
|
|
|
|
|
|
|
} |
|
243
|
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
|
|
245
|
|
|
|
|
|
|
|
|
246
|
|
|
|
|
|
|
# Check: Implied N Optimization? |
|
247
|
23
|
100
|
100
|
|
|
146
|
if (!$card->n && $card->fn && (!$card->org || (!$card->fn eq $card->org))) |
|
|
|
|
66
|
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
248
|
|
|
|
|
|
|
{ |
|
249
|
7
|
|
|
|
|
50
|
my $n = Data::Microformat::hCard::name->new; |
|
250
|
7
|
|
|
|
|
36
|
my @arr = split(" ", $card->fn); |
|
251
|
7
|
50
|
|
|
|
30
|
if ($arr[1]) |
|
252
|
|
|
|
|
|
|
{ |
|
253
|
7
|
|
|
|
|
17
|
$arr[1] =~ s/\.//; |
|
254
|
|
|
|
|
|
|
} |
|
255
|
7
|
50
|
33
|
|
|
42
|
if ($arr[0] =~ m/\,/ && length $arr[1] == 1) |
|
256
|
|
|
|
|
|
|
{ |
|
257
|
0
|
|
|
|
|
0
|
$arr[0] =~ s/\,//; |
|
258
|
0
|
|
|
|
|
0
|
$n->family_name($class->_trim($arr[0])); |
|
259
|
0
|
|
|
|
|
0
|
$n->given_name($class->_trim($arr[1])); |
|
260
|
|
|
|
|
|
|
} |
|
261
|
|
|
|
|
|
|
else |
|
262
|
|
|
|
|
|
|
{ |
|
263
|
7
|
|
|
|
|
30
|
$n->family_name($class->_trim($arr[1])); |
|
264
|
7
|
|
|
|
|
35
|
$n->given_name($class->_trim($arr[0])); |
|
265
|
|
|
|
|
|
|
} |
|
266
|
7
|
|
|
|
|
41
|
$card->n($n); |
|
267
|
|
|
|
|
|
|
} |
|
268
|
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
# Check: Org? |
|
270
|
23
|
100
|
100
|
|
|
125
|
if (($card->org) && (($card->fn || "") eq $card->org->organization_name)) |
|
|
|
|
100
|
|
|
|
|
|
271
|
|
|
|
|
|
|
{ |
|
272
|
2
|
|
|
|
|
18
|
my $name = Data::Microformat::hCard::name->new; |
|
273
|
2
|
|
|
|
|
25
|
$name->family_name(" "); |
|
274
|
2
|
|
|
|
|
15
|
$name->given_name(" "); |
|
275
|
2
|
|
|
|
|
15
|
$name->additional_name(" "); |
|
276
|
2
|
|
|
|
|
14
|
$name->honorific_prefix(" "); |
|
277
|
2
|
|
|
|
|
24
|
$name->honorific_suffix(" "); |
|
278
|
2
|
|
|
|
|
15
|
$card->n($name); |
|
279
|
|
|
|
|
|
|
} |
|
280
|
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
# Check: Nickname Optimization? |
|
282
|
23
|
100
|
|
|
|
122
|
if ($card->fn) |
|
283
|
|
|
|
|
|
|
{ |
|
284
|
10
|
|
|
|
|
52
|
my @words = split(" ", $card->fn); |
|
285
|
10
|
0
|
66
|
|
|
73
|
if (($card->org && (!$card->org->organization_name eq $card->fn)) && (!$card->n) && (scalar @words == 1)) |
|
|
|
|
33
|
|
|
|
|
|
|
|
|
33
|
|
|
|
|
|
286
|
|
|
|
|
|
|
{ |
|
287
|
0
|
|
|
|
|
0
|
$card->nickname($card->fn); |
|
288
|
0
|
|
|
|
|
0
|
my $name = Data::Microformat::hCard::name->new; |
|
289
|
0
|
|
|
|
|
0
|
$name->family_name(""); |
|
290
|
0
|
|
|
|
|
0
|
$name->given_name(""); |
|
291
|
0
|
|
|
|
|
0
|
$name->additional_name(""); |
|
292
|
0
|
|
|
|
|
0
|
$name->honorific_prefix(""); |
|
293
|
0
|
|
|
|
|
0
|
$name->honorific_suffix(""); |
|
294
|
0
|
|
|
|
|
0
|
$card->n($name); |
|
295
|
|
|
|
|
|
|
} |
|
296
|
|
|
|
|
|
|
} |
|
297
|
23
|
|
|
|
|
56
|
$card->{_no_dupe_keys} = 0; |
|
298
|
23
|
|
|
|
|
101
|
push (@all_cards, $card); |
|
299
|
|
|
|
|
|
|
} |
|
300
|
|
|
|
|
|
|
|
|
301
|
17
|
|
|
|
|
95
|
$tree->delete; |
|
302
|
|
|
|
|
|
|
|
|
303
|
|
|
|
|
|
|
# Check: Representative hCard? |
|
304
|
17
|
100
|
|
|
|
3874
|
if ($representative_url) |
|
305
|
|
|
|
|
|
|
{ |
|
306
|
4
|
100
|
|
|
|
7
|
if (scalar @all_cards == 1) |
|
307
|
|
|
|
|
|
|
{ |
|
308
|
1
|
|
|
|
|
3
|
$all_cards[0]->{_representative} = 1; |
|
309
|
|
|
|
|
|
|
} |
|
310
|
|
|
|
|
|
|
else |
|
311
|
|
|
|
|
|
|
{ |
|
312
|
3
|
|
|
|
|
4
|
my $found_one = 0; |
|
313
|
3
|
|
|
|
|
5
|
foreach my $card (@all_cards) |
|
314
|
|
|
|
|
|
|
{ |
|
315
|
5
|
100
|
66
|
|
|
19
|
if ($card->url && $card->uid && $card->url eq $card->uid && _normalize_url($card->url) eq _normalize_url($representative_url)) |
|
|
|
|
100
|
|
|
|
|
|
|
|
|
66
|
|
|
|
|
|
316
|
|
|
|
|
|
|
{ |
|
317
|
1
|
|
|
|
|
2
|
$card->{_representative} = 1; |
|
318
|
1
|
|
|
|
|
2
|
$found_one = 1; |
|
319
|
1
|
|
|
|
|
1
|
last; |
|
320
|
|
|
|
|
|
|
} |
|
321
|
|
|
|
|
|
|
} |
|
322
|
3
|
100
|
|
|
|
8
|
if (!$found_one) |
|
323
|
|
|
|
|
|
|
{ |
|
324
|
2
|
|
|
|
|
5
|
foreach my $card (@all_cards) |
|
325
|
|
|
|
|
|
|
{ |
|
326
|
4
|
100
|
66
|
|
|
14
|
if ($card->url && $card->url eq $rel_me) |
|
327
|
|
|
|
|
|
|
{ |
|
328
|
1
|
|
|
|
|
2
|
$card->{_representative} = 1; |
|
329
|
1
|
|
|
|
|
2
|
last; |
|
330
|
|
|
|
|
|
|
} |
|
331
|
|
|
|
|
|
|
} |
|
332
|
|
|
|
|
|
|
} |
|
333
|
|
|
|
|
|
|
} |
|
334
|
|
|
|
|
|
|
} |
|
335
|
|
|
|
|
|
|
|
|
336
|
17
|
100
|
|
|
|
63
|
if (wantarray) |
|
337
|
|
|
|
|
|
|
{ |
|
338
|
4
|
|
|
|
|
21
|
return @all_cards; |
|
339
|
|
|
|
|
|
|
} |
|
340
|
|
|
|
|
|
|
else |
|
341
|
|
|
|
|
|
|
{ |
|
342
|
13
|
|
|
|
|
88
|
return $all_cards[0]; |
|
343
|
|
|
|
|
|
|
} |
|
344
|
|
|
|
|
|
|
} |
|
345
|
|
|
|
|
|
|
|
|
346
|
|
|
|
|
|
|
sub _normalize_url |
|
347
|
|
|
|
|
|
|
{ |
|
348
|
6
|
|
|
6
|
|
8
|
my $url = shift; |
|
349
|
6
|
|
|
|
|
13
|
$url =~ s/[A-Z]/[a-z]/; |
|
350
|
6
|
|
|
|
|
9
|
$url =~ s/\/$//; |
|
351
|
6
|
|
|
|
|
15
|
return $url; |
|
352
|
|
|
|
|
|
|
} |
|
353
|
|
|
|
|
|
|
|
|
354
|
|
|
|
|
|
|
1; |
|
355
|
|
|
|
|
|
|
|
|
356
|
|
|
|
|
|
|
__END__ |