diff options
Diffstat (limited to 'gen.pl')
-rwxr-xr-x | gen.pl | 62 |
1 files changed, 62 insertions, 0 deletions
@@ -0,0 +1,62 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +my @feeds = ( + [ 'Security.nl', 'https://www.security.nl/rss/headlines.xml' ], + [ 'r/netsec', 'https://www.reddit.com/r/netsec/.rss' ], + [ 'Threatpost', 'https://threatpost.com/feed' ], + [ 'BleepingComputer', 'https://www.bleepingcomputer.com/feed/' ], + #[ 'AusCERT', 'https://www.auscert.org.au/rss.html' ], + [ 'Naked Security', 'https://nakedsecurity.sophos.com/feed/' ], + [ 'NCSC', 'https://www.ncsc.nl/rss/beveiligingsadviezen' ], +); + +my $fn = '/var/www/www/intel/feeds.json'; + + +use POSIX 'strftime'; +use LWP::UserAgent; +use XML::FeedPP; +use JSON::XS; + +sub unescape { local $_ = shift; s/&(amp|quot|#(\d+));/$2 ? chr $2 : +{qw{amp & quot "}}->{$1}/eg; $_ } + + +my @items; + +for my $feed (@feeds) { + #print "Fetching $feed->[0]\n"; + my $ua = LWP::UserAgent->new; + $ua->agent("Yorhel's RSS reader"); + $ua->timeout(30); + my $res = $ua->get($feed->[1]); + #print "got\n"; + + if($res->is_success) { + my $X = eval { XML::FeedPP->new(scalar $res->decoded_content()); }; + if(!$X) { + warn "Parsing $feed->[0]: $@\n"; + next; + } + for my $i ($X->get_item()) { + warn "No date/time in feed '$feed->[0]'\n" if !$i->pubDate(); + push @items, { + feed => $feed->[0], + title => scalar unescape($i->title()), + url => scalar $i->link(), + ts => scalar XML::FeedPP::Util::get_epoch($i->pubDate()), # XXX: Use of internal function + }; + } + } else { + warn "Unable to fetch '$feed->[1]': ".$res->status_line()."\n"; + } +} + +@items = sort { $b->{ts} <=> $a->{ts} } @items; + +open my $F, '>', "$fn~" or die $!; +print $F encode_json \@items; +close $F; +rename "$fn~", $fn or die $!; |