@@ -13,6 +13,10 @@ use Path::Tiny ();
13
13
use Date::Format ();
14
14
use Scalar::Util ();
15
15
use Text::MicroTemplate;
16
+ use XML::Atom::Feed;
17
+ use XML::Atom::Entry;
18
+ use XML::Atom::Person;
19
+ use XML::Atom::Link;
16
20
17
21
use Text::Xatena;
18
22
use Text::Xatena::Inline;
@@ -78,7 +82,7 @@ sub build_entries {
78
82
$self -> build_categories($src_list );
79
83
$self -> build_tags($src_list );
80
84
# $self->build_sitemap(\@entries);
81
- # $self->build_atom(\@entries );
85
+ $self -> build_atom_feed( $src_list );
82
86
}
83
87
84
88
@@ -129,6 +133,22 @@ sub build_entry {
129
133
$self -> diag(" Created entry $dest \n " );
130
134
}
131
135
136
+ # content/foo/bar.txt => /foo/bar
137
+ sub entry_url_path {
138
+ my ($self , $src ) = @_ ;
139
+
140
+ my $content_dir = $self -> content_dir;
141
+ my $path = " $src " ;
142
+ $path =~ s ! $content_dir!! ;
143
+ $path =~ s !\. ([^.]+)$!! ;
144
+ return $path ;
145
+ }
146
+
147
+ sub entry_url {
148
+ my ($self , $src ) = @_ ;
149
+ return " https://perl-users.jp" . $self -> entry_url_path($src );
150
+ }
151
+
132
152
sub entry_text {
133
153
my ($self , $src ) = @_ ;
134
154
my $matter = $self -> front_matter($src );
@@ -281,14 +301,8 @@ sub build_tag {
281
301
my $file = Path::Tiny::path($_ );
282
302
my $matter = $self -> front_matter($file );
283
303
my $title = $matter -> title;
304
+ my $href = $self -> entry_url_path($file );
284
305
285
- # content/foo/bar.txt => /foo/bar
286
- my $href = do {
287
- my $content_dir = $self -> content_dir;
288
- my $path = $file =~ s ! $content_dir!! r ;
289
- my $href = $path =~ s !\. ([^.]+)$!! r ;
290
- $href ;
291
- };
292
306
{
293
307
file => $file ,
294
308
matter => $matter ,
@@ -316,9 +330,71 @@ sub build_sitemap {
316
330
... # TODO
317
331
}
318
332
319
- sub build_atom {
320
- my ($self , $entries ) = @_ ;
321
- ... # TODO
333
+ my $ATOM_FEED_COUNT = 10;
334
+ my $ATOM_DATE_FORMAT = ' %Y-%m-%dT%H:%M:%S%z' ;
335
+
336
+ sub build_atom_feed {
337
+ my ($self , $src_list ) = @_ ;
338
+
339
+ my $feed = XML::Atom::Feed-> new;
340
+ $feed -> title(' 新着記事 - Perl Users JP' );
341
+ $feed -> id(' tag:perl-users.jp,2020:/feed' );
342
+ $feed -> lang(' ja-JP' );
343
+
344
+ { # link alternate
345
+ my $link = XML::Atom::Link-> new;
346
+ $link -> type(' text/html' );
347
+ $link -> rel(' alternate' );
348
+ $link -> href(' https://perl-users.jp' );
349
+ $feed -> add_link($link );
350
+ }
351
+
352
+ { # link self
353
+ my $link = XML::Atom::Link-> new;
354
+ $link -> type(' application/atom+xml' );
355
+ $link -> rel(' self' );
356
+ $link -> href(' https://perl-users.jp/feed.atom' );
357
+ $feed -> add_link($link );
358
+ }
359
+
360
+ my @sorted = sort { $b -> stat -> mtime <=> $a -> stat -> mtime } $src_list -> @*;
361
+ my @new_src_list = splice @sorted , 0, $ATOM_FEED_COUNT ;
362
+ for my $src (@new_src_list ) {
363
+ my $entry = XML::Atom::Entry-> new;
364
+
365
+ my $matter = $self -> front_matter($src );
366
+ my $path = $self -> entry_url_path($src );
367
+
368
+ $entry -> title($matter -> title);
369
+ $entry -> id(" tag:perl-users.jp,2020:$path " );
370
+ $entry -> updated(Date::Format::time2str($ATOM_DATE_FORMAT , $src -> stat -> mtime));
371
+ # $entry->published(Date::Format::time2str($ATOM_DATE_FORMAT, $src->stat->mtime)); # FIXME mtime
372
+ $entry -> content(
373
+ $self -> entry_text($src )
374
+ );
375
+
376
+ my $author = XML::Atom::Person-> new;
377
+ $author -> name($matter -> author);
378
+ $entry -> author($author );
379
+
380
+ my $link = XML::Atom::Link-> new;
381
+ $link -> type(' text/html' );
382
+ $link -> rel(' alternate' );
383
+ $link -> href($self -> entry_url($src ));
384
+
385
+ $feed -> add_entry($entry );
386
+ }
387
+
388
+ my $first_src = $new_src_list [0];
389
+ $feed -> updated(Date::Format::time2str($ATOM_DATE_FORMAT , $first_src -> stat -> mtime));
390
+
391
+ my $xml = $feed -> as_xml;
392
+
393
+ my $atom_dir = $self -> public_dir-> child();
394
+ my $dest = $atom_dir -> child(' feed.atom' );
395
+ $atom_dir -> mkpath unless $atom_dir -> is_dir;
396
+ $dest -> spew($xml );
397
+ $self -> diag(" Created atom $dest \n " );
322
398
}
323
399
324
400
sub diag {
@@ -382,6 +458,9 @@ sub format_text {
382
458
$parser -> html_footer(' ' );
383
459
$parser -> parse_string_document(" =pod\n\n $text " );
384
460
}
461
+ elsif ($format eq ' html' ) {
462
+ return $text ;
463
+ }
385
464
else {
386
465
die " unsupported format: $format " ;
387
466
}
0 commit comments