💾 Archived View for thrig.me › blog › 2024 › 05 › 19 › gem2atom.pl captured on 2024-08-18 at 20:52:32.

View Raw

More Information

⬅️ Previous capture (2024-05-26)

-=-=-=-=-=-=-

#!/usr/bin/perl
# gem2atom.pl - convert gemfeed to Atom
use 5.36.0;
use DateTime::Format::Strptime;
use Getopt::Long;
use Net::Gemini;
use XML::Atom;
use XML::Atom::Entry;
use XML::Atom::Feed;

my $max_posts = ~0;
GetOptions( 'b=s' => \my $base_url, 'M=i' => \$max_posts )
  or exit 1;
die "Usage: $0 -b base_url [gemfeed-file|-]\n"
  unless defined $base_url;
my ( $feed, $feed_title, $header );

$XML::Atom::DefaultVersion = "1.0";

my $entry_count = 1;
while ( my $line = readline ) {
    unless ( defined $feed_title ) {
        if ( $line =~ m/^#\s*(.+)/ ) {
            $feed_title = $1;
        } else {
            next;
        }
    }
    if ( $line =~ m/^=>\s*(\S+)\s*([0-9-]{10})\s*(.+)/ ) {
        my ( $entry_path, $entry_date, $entry_title ) = ( $1, $2, $3 );
        eval {
            my $dt = DateTime::Format::Strptime->new(
                pattern   => '%Y-%m-%d',
                time_zone => 'UTC',
                on_error  => 'croak',
            );
            $dt->parse_datetime($entry_date);
            1;
        } or die "invalid date '$entry_date' at $ARGV:$.\n";
        unless ( defined $feed ) {
            $feed = XML::Atom::Feed->new;
            $feed->title($feed_title);
            my $link = XML::Atom::Link->new;
            $link->rel('alternate');
            $link->href($base_url);
            $feed->add_link($link);
            $feed->updated( DateTime->now->strftime('%Y-%m-%dT%H:%M:%SZ') );
        }
        my $entry = XML::Atom::Entry->new;
        $entry->title($entry_title);
        my $link = XML::Atom::Link->new;
        $link->rel('alternate');
        $link->href( URI->new_abs( $entry_path, $base_url )->canonical );
        $entry->add_link($link);
        $entry->updated( $entry_date . 'T12:00:00Z' );
        $feed->add_entry($entry);
        last if ++$entry_count > $max_posts;
    }
} continue {
    last if eof;    # only the first file given in ARGV
}

print $feed->as_xml if defined $feed;