line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package XML::Atom::App; |
2
|
|
|
|
|
|
|
|
3
|
7
|
|
|
7
|
|
201193
|
use warnings; |
|
7
|
|
|
|
|
18
|
|
|
7
|
|
|
|
|
260
|
|
4
|
7
|
|
|
7
|
|
40
|
use strict; |
|
7
|
|
|
|
|
14
|
|
|
7
|
|
|
|
|
230
|
|
5
|
7
|
|
|
7
|
|
37
|
use Carp (); |
|
7
|
|
|
|
|
17
|
|
|
7
|
|
|
|
|
110
|
|
6
|
7
|
|
|
7
|
|
8565
|
use Time::HiRes; |
|
7
|
|
|
|
|
27134
|
|
|
7
|
|
|
|
|
125
|
|
7
|
|
|
|
|
|
|
|
8
|
7
|
|
|
7
|
|
8199
|
use version; our $VERSION = qv('0.0.5'); |
|
7
|
|
|
|
|
18520
|
|
|
7
|
|
|
|
|
45
|
|
9
|
|
|
|
|
|
|
|
10
|
7
|
|
|
7
|
|
4090
|
use XML::Atom; |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
use XML::Atom::Entry; |
12
|
|
|
|
|
|
|
use XML::Atom::Feed; |
13
|
|
|
|
|
|
|
|
14
|
|
|
|
|
|
|
use base qw(XML::Atom::Feed); |
15
|
|
|
|
|
|
|
$XML::Atom::DefaultVersion = '1.0'; # $feed->version() |
16
|
|
|
|
|
|
|
|
17
|
|
|
|
|
|
|
# not currently in use but if ever needed the logic is in place... |
18
|
|
|
|
|
|
|
my %new_map; |
19
|
|
|
|
|
|
|
my %key_map; |
20
|
|
|
|
|
|
|
my %link_key_map; |
21
|
|
|
|
|
|
|
my %author_key_map; |
22
|
|
|
|
|
|
|
|
23
|
|
|
|
|
|
|
sub new { |
24
|
|
|
|
|
|
|
my ($self, $args_hr, $opt_hr) = @_; |
25
|
|
|
|
|
|
|
local $XML::Atom::DefaultVersion = '1.0'; |
26
|
|
|
|
|
|
|
$args_hr = {} if !defined $args_hr || ref $args_hr ne 'HASH'; |
27
|
|
|
|
|
|
|
$opt_hr = {} if !defined $opt_hr || ref $opt_hr ne 'HASH'; |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
my $feed = $self->SUPER::new( 'Version' => delete($args_hr->{'Version'}) || $XML::Atom::DefaultVersion ); |
30
|
|
|
|
|
|
|
|
31
|
|
|
|
|
|
|
my $particles = delete $args_hr->{'particles'} || ''; |
32
|
|
|
|
|
|
|
my $link = exists $args_hr->{'link'} ? delete $args_hr->{'link'} : undef; |
33
|
|
|
|
|
|
|
$link ||= $opt_hr->{no_self_link} ? undef : [{ 'rel' => 'self' }]; |
34
|
|
|
|
|
|
|
my $contrib = exists $args_hr->{'contributor'} ? delete $args_hr->{'contributor'} : undef; |
35
|
|
|
|
|
|
|
|
36
|
|
|
|
|
|
|
$feed->{'alert_cant'} = delete $args_hr->{'alert_cant'} || ''; |
37
|
|
|
|
|
|
|
$feed->{'alert_cant'} = '' if ref $feed->{'alert_cant'} ne 'CODE'; |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
for my $item ( sort keys %{ $args_hr } ) { |
40
|
|
|
|
|
|
|
$item = $new_map{$item} if exists $new_map{$item}; |
41
|
|
|
|
|
|
|
if ( $feed->can($item) ) { |
42
|
|
|
|
|
|
|
$feed->$item( ref $args_hr->{$item} eq 'ARRAY' ? @{$args_hr->{$item}} : ($args_hr->{$item}) ); |
43
|
|
|
|
|
|
|
} |
44
|
|
|
|
|
|
|
else { |
45
|
|
|
|
|
|
|
$feed->alert_cant( $item ); |
46
|
|
|
|
|
|
|
} |
47
|
|
|
|
|
|
|
} |
48
|
|
|
|
|
|
|
|
49
|
|
|
|
|
|
|
$feed->_do_app_author( $feed, delete $args_hr->{'author'} ); |
50
|
|
|
|
|
|
|
$feed->_do_app_link( $feed, $link ); |
51
|
|
|
|
|
|
|
$feed->_do_app_contributor( $feed, $contrib ) if defined $contrib; |
52
|
|
|
|
|
|
|
|
53
|
|
|
|
|
|
|
$feed->{'time_of_last_create_from_atomic_structure'} = 0; |
54
|
|
|
|
|
|
|
$feed->create_from_atomic_structure( $particles ) if ref $particles eq 'ARRAY'; |
55
|
|
|
|
|
|
|
return $feed; |
56
|
|
|
|
|
|
|
} |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
sub clear_particles { |
59
|
|
|
|
|
|
|
my ($feed, $dx) = @_; |
60
|
|
|
|
|
|
|
$feed->{'time_of_last_create_from_atomic_structure'} = 0; |
61
|
|
|
|
|
|
|
|
62
|
|
|
|
|
|
|
# would love to know of a better way to remove $feed->entries, anyone ? |
63
|
|
|
|
|
|
|
my $author = $feed->author(); |
64
|
|
|
|
|
|
|
my @links = $feed->link(); |
65
|
|
|
|
|
|
|
my @contribs = $feed->contributors(); |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
use XML::Simple (); |
68
|
|
|
|
|
|
|
my $xml_struct = XML::Simple::XMLin( $feed->as_xml ); |
69
|
|
|
|
|
|
|
for my $key (qw(xmlns entry link author contributor)) { |
70
|
|
|
|
|
|
|
delete $xml_struct->{$key}; |
71
|
|
|
|
|
|
|
} |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
$feed->init; # resets 'elem' key to new empty object, wipes out everything not just entries.. |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
for my $item ( sort keys %{ $xml_struct } ) { |
76
|
|
|
|
|
|
|
$item = $new_map{$item} if exists $new_map{$item}; |
77
|
|
|
|
|
|
|
if ( $feed->can($item) ) { |
78
|
|
|
|
|
|
|
$xml_struct->{$item} = $xml_struct->{$item}{'content'} if ref $xml_struct->{$item} eq 'HASH'; |
79
|
|
|
|
|
|
|
$feed->$item( ref $xml_struct->{$item} eq 'ARRAY' ? @{$xml_struct->{$item}} : ($xml_struct->{$item}) ); |
80
|
|
|
|
|
|
|
} |
81
|
|
|
|
|
|
|
else { |
82
|
|
|
|
|
|
|
$feed->alert_cant( $item ); |
83
|
|
|
|
|
|
|
} |
84
|
|
|
|
|
|
|
} |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
$feed->author( $author ) if $author; |
87
|
|
|
|
|
|
|
$feed->add_link($_) for @links; |
88
|
|
|
|
|
|
|
$feed->add_contributor($_) for @contribs; |
89
|
|
|
|
|
|
|
|
90
|
|
|
|
|
|
|
return $feed; |
91
|
|
|
|
|
|
|
} |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
sub alert_cant { |
94
|
|
|
|
|
|
|
my ($feed, $cant, $obj) = @_; |
95
|
|
|
|
|
|
|
$obj = $feed if !defined $obj || !$obj; |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
if ( ref $feed->{'alert_cant'} eq 'CODE' ) { |
98
|
|
|
|
|
|
|
return $feed->{'alert_cant'}->( $feed, $cant, $obj ); |
99
|
|
|
|
|
|
|
} |
100
|
|
|
|
|
|
|
else { |
101
|
|
|
|
|
|
|
my $msg = sprintf q{Can't locate object method "%s" via package "%s"}, $cant, ref($obj); |
102
|
|
|
|
|
|
|
if ( exists $INC{'CGI/Carp.pm'} ) { |
103
|
|
|
|
|
|
|
return CGI::Carp::carp( $msg ); |
104
|
|
|
|
|
|
|
} |
105
|
|
|
|
|
|
|
else { |
106
|
|
|
|
|
|
|
return Carp::carp( $msg ); |
107
|
|
|
|
|
|
|
} |
108
|
|
|
|
|
|
|
} |
109
|
|
|
|
|
|
|
} |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
sub atom_date_string { |
112
|
|
|
|
|
|
|
goto &datetime_as_rfc3339; |
113
|
|
|
|
|
|
|
} |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
sub datetime_as_rfc3339 { |
116
|
|
|
|
|
|
|
my ($feed, $dt) = @_; |
117
|
|
|
|
|
|
|
|
118
|
|
|
|
|
|
|
if (ref $dt eq 'ARRAY') { |
119
|
|
|
|
|
|
|
require DateTime if !exists $INC{'DateTime.pm'}; |
120
|
|
|
|
|
|
|
$dt = DateTime->new(@{ $dt }); |
121
|
|
|
|
|
|
|
} |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
my $offset = $dt->offset != 0 ? '%z' : 'Z'; |
124
|
|
|
|
|
|
|
return $dt->strftime('%FT%T' . $offset); |
125
|
|
|
|
|
|
|
} |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
sub create_entry_from_atomic_structure { |
128
|
|
|
|
|
|
|
my ( $feed, $entry_hr ) = @_; |
129
|
|
|
|
|
|
|
local $XML::Atom::DefaultVersion = $feed->version(); |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
my $entry = XML::Atom::Entry->new; |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
for my $item (keys %{ $entry_hr } ) { |
134
|
|
|
|
|
|
|
next if $item eq 'author' || $item eq 'link' || $item eq 'contributor' || $item eq 'source'; |
135
|
|
|
|
|
|
|
$item = $key_map{$item} if exists $key_map{$item}; |
136
|
|
|
|
|
|
|
if ( $entry->can($item) ) { |
137
|
|
|
|
|
|
|
$entry->$item( ref $entry_hr->{$item} eq 'ARRAY' ? @{$entry_hr->{$item}} : $entry_hr->{$item} ); |
138
|
|
|
|
|
|
|
} |
139
|
|
|
|
|
|
|
else { |
140
|
|
|
|
|
|
|
$feed->alert_cant( $item, $entry ); |
141
|
|
|
|
|
|
|
} |
142
|
|
|
|
|
|
|
} |
143
|
|
|
|
|
|
|
|
144
|
|
|
|
|
|
|
$feed->_do_app_author( $entry, $entry_hr->{'author'} ); |
145
|
|
|
|
|
|
|
$feed->_do_app_contributor( $entry, $entry_hr->{'contributor'} ); |
146
|
|
|
|
|
|
|
$feed->_do_app_link( $entry, $entry_hr->{'link'} ); |
147
|
|
|
|
|
|
|
$feed->_do_app_source( $entry, $entry_hr->{'source'} ) if defined $entry_hr->{'source'}; |
148
|
|
|
|
|
|
|
|
149
|
|
|
|
|
|
|
return $entry; |
150
|
|
|
|
|
|
|
} |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
sub create_from_atomic_structure { |
153
|
|
|
|
|
|
|
my ( $feed, $particles, $opts_hr ) = @_; |
154
|
|
|
|
|
|
|
$opts_hr = {} if !defined $opts_hr || ref $opts_hr ne 'HASH'; |
155
|
|
|
|
|
|
|
local $XML::Atom::DefaultVersion = $feed->version(); |
156
|
|
|
|
|
|
|
|
157
|
|
|
|
|
|
|
$feed->clear_particles() if !$opts_hr->{'do_not_clear_particles'}; |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
for my $entry_hr ( @{ $particles } ) { |
160
|
|
|
|
|
|
|
my $entry = $feed->create_entry_from_atomic_structure( $entry_hr ); |
161
|
|
|
|
|
|
|
$feed->add_entry($entry); |
162
|
|
|
|
|
|
|
} |
163
|
|
|
|
|
|
|
|
164
|
|
|
|
|
|
|
$feed->{'time_of_last_create_from_atomic_structure'} = Time::HiRes::time(); |
165
|
|
|
|
|
|
|
return $feed; |
166
|
|
|
|
|
|
|
} |
167
|
|
|
|
|
|
|
|
168
|
|
|
|
|
|
|
sub _do_app_contributor { |
169
|
|
|
|
|
|
|
my ($feed, $thing, $aref) = @_; |
170
|
|
|
|
|
|
|
return unless defined $aref; |
171
|
|
|
|
|
|
|
$aref = [ $aref ] unless ref $aref eq 'ARRAY'; |
172
|
|
|
|
|
|
|
|
173
|
|
|
|
|
|
|
foreach my $contrib_ds ( @{$aref} ) { |
174
|
|
|
|
|
|
|
if ( ref $contrib_ds eq 'HASH' ) { |
175
|
|
|
|
|
|
|
my $contrib = XML::Atom::App::Contributor->new; |
176
|
|
|
|
|
|
|
for my $item ( keys %{ $contrib_ds } ) { |
177
|
|
|
|
|
|
|
$item = $author_key_map{$item} if exists $author_key_map{$item}; |
178
|
|
|
|
|
|
|
if ( $contrib->can( $item ) ) { |
179
|
|
|
|
|
|
|
$contrib->$item( ref $contrib_ds->{$item} eq 'ARRAY' ? @{$contrib_ds->{$item}} : $contrib_ds->{$item} ); |
180
|
|
|
|
|
|
|
} |
181
|
|
|
|
|
|
|
else { |
182
|
|
|
|
|
|
|
$feed->alert_cant( $item, $contrib ); |
183
|
|
|
|
|
|
|
} |
184
|
|
|
|
|
|
|
} |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
$thing->add_contributor($contrib); |
187
|
|
|
|
|
|
|
} |
188
|
|
|
|
|
|
|
} |
189
|
|
|
|
|
|
|
} |
190
|
|
|
|
|
|
|
|
191
|
|
|
|
|
|
|
sub _do_app_author { |
192
|
|
|
|
|
|
|
my ($feed, $thing, $author_ds) = @_; |
193
|
|
|
|
|
|
|
if ( ref $author_ds eq 'HASH' ) { |
194
|
|
|
|
|
|
|
my $author = XML::Atom::Person->new; |
195
|
|
|
|
|
|
|
for my $item ( keys %{ $author_ds } ) { |
196
|
|
|
|
|
|
|
$item = $author_key_map{$item} if exists $author_key_map{$item}; |
197
|
|
|
|
|
|
|
if ( $author->can( $item ) ) { |
198
|
|
|
|
|
|
|
$author->$item( ref $author_ds->{$item} eq 'ARRAY' ? @{$author_ds->{$item}} : $author_ds->{$item} ); |
199
|
|
|
|
|
|
|
} |
200
|
|
|
|
|
|
|
else { |
201
|
|
|
|
|
|
|
$feed->alert_cant( $item, $author ); |
202
|
|
|
|
|
|
|
} |
203
|
|
|
|
|
|
|
} |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
$thing->author($author); |
206
|
|
|
|
|
|
|
} |
207
|
|
|
|
|
|
|
} |
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
sub _do_app_link { |
210
|
|
|
|
|
|
|
my ($feed, $thing, $link_ds) = @_; |
211
|
|
|
|
|
|
|
|
212
|
|
|
|
|
|
|
if ( ref $link_ds eq 'ARRAY' ) { |
213
|
|
|
|
|
|
|
for my $link_hr ( @{ $link_ds } ) { |
214
|
|
|
|
|
|
|
next if ref $link_hr ne 'HASH'; |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
my $link = XML::Atom::Link->new; |
217
|
|
|
|
|
|
|
for my $item ( keys %{ $link_hr } ) { |
218
|
|
|
|
|
|
|
$item = $link_key_map{$item} if exists $link_key_map{$item}; |
219
|
|
|
|
|
|
|
if ( $link->can( $item ) ) { |
220
|
|
|
|
|
|
|
$link->$item( ref $link_hr->{$item} eq 'ARRAY' ? @{$link_hr->{$item}} : $link_hr->{$item} ); |
221
|
|
|
|
|
|
|
} |
222
|
|
|
|
|
|
|
else { |
223
|
|
|
|
|
|
|
$feed->alert_cant( $item, $link); |
224
|
|
|
|
|
|
|
} |
225
|
|
|
|
|
|
|
} |
226
|
|
|
|
|
|
|
$thing->add_link($link); |
227
|
|
|
|
|
|
|
} |
228
|
|
|
|
|
|
|
} |
229
|
|
|
|
|
|
|
} |
230
|
|
|
|
|
|
|
|
231
|
|
|
|
|
|
|
|
232
|
|
|
|
|
|
|
sub _do_app_source { |
233
|
|
|
|
|
|
|
my ($feed, $entry, $source_ds) = @_; |
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
if ( ref $source_ds ne 'HASH' ) { |
236
|
|
|
|
|
|
|
$entry->source( $source_ds ); |
237
|
|
|
|
|
|
|
return; |
238
|
|
|
|
|
|
|
} |
239
|
|
|
|
|
|
|
delete $source_ds->{particles}; |
240
|
|
|
|
|
|
|
my $src = __PACKAGE__-> new( $source_ds, {no_self_link=>1} ); |
241
|
|
|
|
|
|
|
$entry->source( $src ); |
242
|
|
|
|
|
|
|
} |
243
|
|
|
|
|
|
|
|
244
|
|
|
|
|
|
|
sub output_with_headers { |
245
|
|
|
|
|
|
|
my ($feed, $xml) = @_; |
246
|
|
|
|
|
|
|
# local $XML::Atom::DefaultVersion = $feed->version(); |
247
|
|
|
|
|
|
|
|
248
|
|
|
|
|
|
|
$xml = $feed->as_xml() if !defined $xml || !$xml; # get $xml if non provided |
249
|
|
|
|
|
|
|
{ |
250
|
|
|
|
|
|
|
use bytes; |
251
|
|
|
|
|
|
|
my $len = length($xml); |
252
|
|
|
|
|
|
|
if (defined wantarray) { |
253
|
|
|
|
|
|
|
return "Content-length: $len\nContent-type: application/atom+xml\n\n$xml"; |
254
|
|
|
|
|
|
|
} |
255
|
|
|
|
|
|
|
else { |
256
|
|
|
|
|
|
|
# print in void context |
257
|
|
|
|
|
|
|
print "Content-length: $len\nContent-type: application/atom+xml\n\n$xml"; |
258
|
|
|
|
|
|
|
} |
259
|
|
|
|
|
|
|
} |
260
|
|
|
|
|
|
|
} |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
sub orange_atom_icon_32_32_base64 { |
263
|
|
|
|
|
|
|
# my ($feed) = @_; |
264
|
|
|
|
|
|
|
return q{data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYAAABzenr0AAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAUzSURBVHjavFdbbFRVFF3nPjoz7dTWTittaW0jUDRAUqaNojyqREnEQKgfUj9MqqAmhqRt/OCD4CuY+Kckoh+aiGKC+gMJbdHoRysJ8dkhhmJLNdDKtJU+6GMK87j3Hs85d2Z6HzNtMYWb3Dn3NWftvfba+5xNYDl+e6Fkj6yqb/oDRbWq14vlPBLRKCITkxf0ROLt+hNjp1PPSRK4kA3vF1dXNRcWlyA2OQU9eos9opAkAiKxD+XkKO6t15aRWO7J/MgmAZU8MEgexgZHMX518Dh72sYMmVKShnxWuWHdHtxKIDIYTgMuDzgfmSOIQkYMpdUF8OY92Hytt4/jvkg47czzU16iQovM3QFwmNck+Yyduu7D6NA0Z6JR4THntFs9V4tWQg6Ui3s6MwKDncsFTnXKLJhDSeUK3AgPtyhccDzmVs999buRt/1Vm4i0od+hX7+MRG87jPGB/w1u8FPj9xEw7McVrnYuOCvtpjTth3J/nTg99c8LRhKhr6D3dTB5R24bXFwbMXBsyZzeoXaycEpJ95TB09AGX/NpqLVNtw8urnVzLvHjFNxiFqRy2OOHuqUVnue+ACkoWzo4O6lGzTmuHq6nPvY2m9rVqjrIK2rMEKxqyG5NPAKt+wjo0LklgfNxJkZMA3KJvqRUk3z5UFY3QH14P0h+WUY79HPvgv7VuSg4ZRGY1YgZgqXmORccF17sy2ehnf9AeO085K2HQFbtXBScj0LcpgF2cN+WV+DZ/LJQu6gD4R7oV7pBJwbSgtMvfiPoVp56DySwxm7EtkMs1WdAB7qzggsDJKQYsHucSkOudrkiCPWR/fA2nYCn8SNIK4NptSMyAu3sAdDRkIsJdfth0LzSrODUoPNZ4KI9SxJI5UHk7D4GdQfz2us31c7CoHMjRkKuDPHseCMrONVhNcDJwMJpKFVvg9L4OaTiNWm1x789KCqkrXhVBiEz0WYCT2nAzQAD1/vaETv1GrRfP4Vx5cfMNcDPwvP0h0DhanPym7OIf/+O67vcJ1/PCJ4KgdzaUP6Wz+dU+5yIL6fV+PsHGAOdwlPpvvUOyeeAVGyCdqkDNB6DPjsBSrnndfOGevOh3RhGItxvA+fX1CtbGFhgYUFkFMZPR6F1HnClHq8HyubWtJexX06CRmdt33hrd7nA7SFY4qoGpnYuOKcRykPPgDCBcsHx9Iv+fNL2PueBehCWUfYQIIMGLOCcOmXDXsh1+yCt35tUPfvzGFuSvzvoinXOxqa02qOhM6733nVP2MAdaej2XN11DPKjLZCD+yBvahGCo7JfTKAN9UD7s8Oe9zUNIhz8fWI8DG2k38WCFdxugANcXrvTVd1IEbuv3Jour7Hzn7jLMBNfKs7R3i67gRVrbeCOEDhinmWhAatsqdquM2XzHZINhK2cqTjHr/XZdVJUbgN3MWAVXKbSyg9jesRW2xP9di+lwrL5ojM3m2H/kG9hwcIA37c71W6wJdW2J2S5nrjYbq/t1AHAhJsKQeyfPvf6IMJgghPJhFZ4x0KlfLFvt22du45Au/A1SOlGc0P672XXwhLtOcM0kTTEMMd0qkVmMNXxMd/tsedUjInr4SQDgOfeXMSiN0FCL5WHah4L1qqYXPJOJlttd+a5M+YpcG5poLYKQ5f+6JJ4r8bbJYP47hq4r7QAs9PjYNhHJd4o8l5taiwuOpa7AS4XKqI/5NjJbTnaWK92nLdLuhQAJayRNMiygXPBeQN+Qbvu0zDc3y+aUzhbkGR73sI7ljvUnndx2q3t+X8CDAD66FtrIL864AAAAABJRU5ErkJggg%3D%3D}; |
265
|
|
|
|
|
|
|
} |
266
|
|
|
|
|
|
|
|
267
|
|
|
|
|
|
|
sub orange_atom_icon_32_32_body_with_headers { |
268
|
|
|
|
|
|
|
# my ($feed) = @_; |
269
|
|
|
|
|
|
|
my $base64 = orange_atom_icon_32_32_base64(); |
270
|
|
|
|
|
|
|
my ($ctype) = $base64 =~ m{data:([^/]+[/][^;]+);base64,}; |
271
|
|
|
|
|
|
|
$ctype = 'image/png' if !$ctype; |
272
|
|
|
|
|
|
|
$base64 =~ s{^data:image/png;base64,}{}; |
273
|
|
|
|
|
|
|
|
274
|
|
|
|
|
|
|
require MIME::Base64; |
275
|
|
|
|
|
|
|
my $binary = MIME::Base64::decode_base64( $base64 ); |
276
|
|
|
|
|
|
|
|
277
|
|
|
|
|
|
|
{ |
278
|
|
|
|
|
|
|
use bytes; |
279
|
|
|
|
|
|
|
my $len = length $binary; |
280
|
|
|
|
|
|
|
return "Content-length: $len\nContent-type: image/png\n\n$binary"; |
281
|
|
|
|
|
|
|
} |
282
|
|
|
|
|
|
|
} |
283
|
|
|
|
|
|
|
|
284
|
|
|
|
|
|
|
sub orange_atom_icon_32_32_img_tag { |
285
|
|
|
|
|
|
|
my ($feed, $attr) = @_; # !! make sure your $attr are XSS safe !! |
286
|
|
|
|
|
|
|
$attr = $attr ? " $attr" : ''; |
287
|
|
|
|
|
|
|
return q{}; |
288
|
|
|
|
|
|
|
} |
289
|
|
|
|
|
|
|
|
290
|
|
|
|
|
|
|
sub orange_atom_icon_16_16_base64 { |
291
|
|
|
|
|
|
|
# my ($feed) = @_; |
292
|
|
|
|
|
|
|
return q{data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAAK/INwWK6QAAABl0RVh0U29mdHdhcmUAQWRvYmUgSW1hZ2VSZWFkeXHJZTwAAAKOSURBVHjadJNNSFRRGIbfc+6dO6OOOplDykSZaRCtnKRc+ANRUBFEm0gicxG0bGoVhERRYIvIjRAtW+UmW5QQQS6qRWQSWJRaUcjkT0LiVWfm/pzTd869M5LShe+eufC973m+n2Fj55KJymTt9ZgVy3AGMHoxvvEs/qZgDL4AlhbsAfv34g1TiRPxRMZbWwU3GQzO9clNhGcYBpkY4UlGiWRd5scnMvx5tUWano9IMoXy1pOUBPgz4xC/xv8r1hSexNKiB1Nhq6RIbQoVhy6i+MiCDffDEPyJITBvZZPYLwiQFFzVZ0Q45Moc8q8fwP34FGJ5FixaCevgBZT1DMNs7Nok9iikL8GyfWkZ3VgvhbljP6yOy2BbmzWR/+o2vM/PSmLfkchTaAIlsHa1ourSS5Sfvg8r3Q38mYb7+DzE9Ig2MDquAan2kth3AgKu0JSBapLCNranEWnPIHp2GDzZDEE3+1OBiXW4D4LHtViZCB/rBHJuHPmHp+CO3oK0Zyk7DvP4IGR1EwrPb673JX0mELslgvVRYW0O8usIvCe9AboyOdIPn1Ug9+Kupihr69ZiZSJFsYRwztbRO4icGARv6IT3ZkCTsKp68J2dyE2MQuZtsFgllbZHTyMsAVqsaldCVt8CtvsYPHsZzvtH+tZIc5e+sfBtLOhFYytRFAlYuGGED2clGNn8lO62m53U37y6XmM7M8E3onEIIpCSLp/vPyC31Bp6SUSsjmIbnO9jpVEZqbROzn15F5RDZs5CFs58FmaNBTZ5Ze+9hn11Genl/1mS0qjChumaCVvo2iViNXHkuD1g9Daxt7lVEQPMNpcSdah1pQb5kqho4yVXQc2iacHiMMpNFPia/jv/FWAAUTVTOunExzkAAAAASUVORK5CYII%3D}; |
293
|
|
|
|
|
|
|
} |
294
|
|
|
|
|
|
|
|
295
|
|
|
|
|
|
|
sub orange_atom_icon_16_16_body_with_headers { |
296
|
|
|
|
|
|
|
# my ($feed) = @_; |
297
|
|
|
|
|
|
|
my $base64 = orange_atom_icon_16_16_base64(); |
298
|
|
|
|
|
|
|
my ($ctype) = $base64 =~ m{data:([^/]+[/][^;]+);base64,}; |
299
|
|
|
|
|
|
|
$ctype = 'image/png' if !$ctype; |
300
|
|
|
|
|
|
|
$base64 =~ s{^data:image/png;base64,}{}; |
301
|
|
|
|
|
|
|
|
302
|
|
|
|
|
|
|
require MIME::Base64; |
303
|
|
|
|
|
|
|
my $binary = MIME::Base64::decode_base64( $base64 ); |
304
|
|
|
|
|
|
|
|
305
|
|
|
|
|
|
|
{ |
306
|
|
|
|
|
|
|
use bytes; |
307
|
|
|
|
|
|
|
my $len = length $binary; |
308
|
|
|
|
|
|
|
return "Content-length: $len\nContent-type: image/png\n\n$binary"; |
309
|
|
|
|
|
|
|
} |
310
|
|
|
|
|
|
|
} |
311
|
|
|
|
|
|
|
|
312
|
|
|
|
|
|
|
sub orange_atom_icon_16_16_img_tag { |
313
|
|
|
|
|
|
|
my ($feed, $attr) = @_; # !! make sure your $attr are XSS safe !! |
314
|
|
|
|
|
|
|
$attr = $attr ? " $attr" : ''; |
315
|
|
|
|
|
|
|
return q{}; |
316
|
|
|
|
|
|
|
} |
317
|
|
|
|
|
|
|
|
318
|
|
|
|
|
|
|
# |
319
|
|
|
|
|
|
|
# This is a workaround for the fact that XML::Atom::Person always pretends |
320
|
|
|
|
|
|
|
# to by an author. This minimal change allows a contributor. |
321
|
|
|
|
|
|
|
{ |
322
|
|
|
|
|
|
|
package XML::Atom::App::Contributor; |
323
|
|
|
|
|
|
|
use base 'XML::Atom::Person'; |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
sub element_name { 'contributor' } |
326
|
|
|
|
|
|
|
} |
327
|
|
|
|
|
|
|
|
328
|
|
|
|
|
|
|
|
329
|
|
|
|
|
|
|
1; |
330
|
|
|
|
|
|
|
|
331
|
|
|
|
|
|
|
__END__ |