💾 Archived View for gmn.clttr.info › sources › orrg.git › tree › orrg.pl.txt captured on 2024-08-25 at 00:37:59.
⬅️ Previous capture (2023-01-29)
-=-=-=-=-=-=-
#!/usr/bin/perl # Copyright René Wagner 2020 # licenced under BSD 3-Clause licence # https://src.clttr.info/rwa/orrg use strict; use URI::Escape; use XML::FeedPP; use HTML::Strip; use DateTime; use DateTime::Format::ISO8601; use POSIX qw(strftime); use lib 'lib/'; use orrg; # enable UTF-8 mode for everything use utf8; binmode STDOUT, ':utf8'; binmode STDERR, ':utf8'; if (!defined($ENV{'SERVER_PROTOCOL'}) || $ENV{'SERVER_PROTOCOL'} ne 'GEMINI') { write_response('CGI_ERROR', '', undef); } my $query = lc(uri_unescape($ENV{'QUERY_STRING'})); if ($query eq '' || $query !~ /^(https|gemini)\:\/\//) { write_response('INPUT', 'Paste the URI of the rss feed you want to read', undef); } write_response('SUCCESS', 'text/gemini', create_response($query)); exit; sub create_response { my ( $qs ) = @_; my @body = (); my $content = feed_get($qs); if ( !defined($content) || $content eq '' ) { push @body, ('# orrg error', '', 'The requested feed could not be loaded. :(', '', '=> '. $qs .' open feed in browser'); } else { my $feed = feed_parse($content); if (defined($feed)) { recent_add($qs, trim_ws($feed->title)); popular_add($qs, trim_ws($feed->title)); push @body, '# '. trim_ws($feed->title); push @body, 'fetched '. strftime('%Y-%m-%dT%H:%M:%SZ', gmtime()); push @body, ''; $feed->description eq '' or push @body, trim_ws($feed->description); $feed->image eq '' or push @body, '=> '. $feed->image .' feed image'; $feed->link eq '' or push @body, ('=> '.$feed->link.' open website', ''); foreach my $it ($feed->get_item()) { push @body, @{item($it)}; } } else { push @body, ('# orrg error', '', 'The requested feed could be loaded but not parsed. :(', '', '=> '. $qs .' open feed in native client'); } } push @body, ('', '', '=> ./index.pl [home]'); return @body; } sub item { my ($it) = @_; my $hs = HTML::Strip->new(emit_spaces => 0, auto_reset => 1); my @item = (); my $title = trim_ws($it->title); my $link = trim_ws($it->link); my $desc = $it->description; if ($desc ne '') { $desc =~ s/\<li\>/* /igm; $desc =~ s/\<h[1-2][^\>]+\>/### /igm; $desc =~ s/\<br \/\>/\r\n/igm; $desc =~ s/\<pre.*\>/\r\n```\r\n/igm; $desc =~ s/\<\/pre\>/\r\n```\r\n/igm; $desc = $hs->parse($desc); } push @item, (($desc ne '' && $desc ne $title) || $it->pubDate ne '')? '## '. $title : $title; if ($it->pubDate ne '') { my $dt = DateTime::Format::ISO8601->parse_datetime($it->pubDate); push @item, 'published '. strftime('%Y-%m-%dT%H:%M:%SZ', gmtime($dt->epoch)); push @item, ''; } if ($desc ne '' && $desc ne $title) { push @item, $desc; } $link eq '' or push @item, ('=> '.$link.' open entry in browser', ''); return \@item; } sub trim_ws { my ( $string ) = @_; $string =~ s/^\s+\*/*/igm; $string =~ s/\s+$//igm; $string =~ s/^\s+//igm; $string =~ s/^\r\n$//igm; return $string; } sub feed_get { my ( $query ) = @_; my $content; if ( $query =~ /^https\:\/\// ) { $content = `wget -qO - $query`; } if ( $query =~ /^gemini\:\/\// ) { $content = `gmni -L -j once -i -N $query`; $content =~ /20\W/ or return undef; $content =~ s/^[0-9]{0,2}\W.+\r\n//; } return $content; } sub feed_parse { my ($content) = @_; my $feed = XML::FeedPP->new($content, -type => 'string', utf8_flag => 1); if (defined($feed)) { $feed->sort_item(); } return $feed; }