#!/usr/bin/perl # Copyright (C) 2007 王亮 # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public Licence as published by # the Free Software Foundation; either version 2, or (at your option) # any later version. # This program is distributed in the hope that it will be useful, but # WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public Licence for more details. use strict; use warnings; use XML::OPML; use XML::Feed; use Encode; use YAML::Syck; use File::HomeDir; use File::Spec::Functions; use Getopt::Long; my $overwrite_old_subscriptions; my $result = GetOptions ( "scratch" => \$overwrite_old_subscriptions, ); die "Usage: perl cache.pl [--scratch]\n" unless $result; my $cache_dir = catdir(File::HomeDir->my_home, ".feedman"); unless (-e $cache_dir and -d _) { mkdir $cache_dir, 0700 or can_not_open_file_or_create_dir('create', $cache_dir, $!); } my $cachefile = catfile($cache_dir, "feed.yaml"); my %subscription; if (!$overwrite_old_subscriptions and -e $cachefile and -f _) { local $YAML::Syck::ImplicitUnicode = 1; my $cache = LoadFile($cachefile); %subscription = %$cache; } for my $opml_file (@ARGV) { my $opml = XML::OPML->new; $opml->parse($opml_file); print $opml->head->{title}, "\n"; for my $outline (@{$opml->outline}) { if (exists $outline->{opmlvalue} and $outline->{opmlvalue} eq 'embed') { for my $key (keys %$outline) { if (ref $outline->{$key} eq "HASH") { my $embedded_outline = $outline->{$key}; $embedded_outline->{xmlUrl} =~ s!^feed://!http://!; if (exists $embedded_outline->{htmlUrl} and $embedded_outline->{htmlUrl} ne "") { my $htmlUrl = lc $embedded_outline->{htmlUrl}; unless (exists $subscription{$htmlUrl} and exists $subscription{$htmlUrl}->{feeds}) { my @feeds = XML::Feed->find_feeds($embedded_outline->{htmlUrl}); $_ =~ s!^feed://!http://! for @feeds; @feeds = grep { $_ !~ m/\Q$embedded_outline->{xmlUrl}\E/i } @feeds; $embedded_outline->{feeds} = \@feeds; $subscription{$htmlUrl} = $embedded_outline; print " ", encode_utf8($embedded_outline->{title}) , "\n"; } } else { warn "htmlUrl not found. $embedded_outline->{title} skipped.\n"; } } } } elsif (exists $outline->{htmlUrl} and $outline->{htmlUrl} ne "") { $outline->{xmlUrl} =~ s!^feed://!http://!; my $htmlUrl = lc $outline->{htmlUrl}; unless (exists $subscription{$htmlUrl} and exists $subscription{$htmlUrl}->{feeds}) { my @feeds = XML::Feed->find_feeds($outline->{htmlUrl}); $_ =~ s!^feed://!http://! for @feeds; @feeds = grep { $_ !~ m/\Q$outline->{xmlUrl}\E/i } @feeds; $outline->{feeds} = \@feeds; $subscription{$htmlUrl} = $outline; print " ", encode_utf8($outline->{title}), "\n"; } } else { warn "htmlUrl not found. $outline->{title} skipped.\n"; } } } DumpFile($cachefile, \%subscription); sub can_not_open_file_or_create_dir { my ($operation, $name, $message) = @_; "can not $operation $name: $message\n"; }