]> git.donarmstrong.com Git - infobot.git/blob - src/Modules/RSSFeeds.pl
join debugging
[infobot.git] / src / Modules / RSSFeeds.pl
1 #
2 #     RSSTest.pl: RSS Tractker hacked from Plug.pl/Rss.pl
3 #     Author: Dan McGrath <djmcgrath@users.sourceforge.net>
4 #  Licensing: Artistic License (as perl itself)
5 #    Version: v0.1
6 #
7
8 package RSSFeeds;
9
10 use strict;
11 use XML::Feed;
12
13 use vars qw(%channels %param $dbh $who $chan);
14
15 sub getCacheEntry {
16     my ( $file, $url ) = @_;
17     my @entries;
18
19     &::DEBUG("rssFeed: Searching cache for $url");
20
21     open CACHE, "<$file" or return;
22     binmode( CACHE, ":encoding(UTF-8)" );
23
24     while (<CACHE>) {
25         next unless /^$url:/;
26         chop;
27         s/^$url:(.*)/$1/;
28         push @entries, $_;
29     }
30     close CACHE;
31
32     return @entries;
33 }
34
35 sub saveCache {
36     my ( $file, $url, @entries ) = @_;
37
38     open IN,  "<$file"     or return;
39     open OUT, ">$file.tmp" or return;
40
41     binmode( IN,  ":encoding(UTF-8)" );
42     binmode( OUT, ":encoding(UTF-8)" );
43
44     # copy all but old ones
45     while (<IN>) {
46         next if /^$url:/;
47         print OUT $_;
48     }
49
50     # append new ones
51     foreach (@entries) {
52         print OUT "$url:$_\n";
53     }
54
55     close IN;
56     close OUT;
57
58     rename "$file.tmp", "$file";
59 }
60
61 sub createCache {
62     my $file = shift;
63
64     &::status("rssFeed: Creating cache in $file");
65
66     open CACHE, ">$file" or return;
67     close CACHE;
68 }
69
70 sub getFeed {
71     my ( $cacheFile, $chan, $rssFeedUrl ) = @_;
72
73     &::DEBUG("rssFeed: URL: $rssFeedUrl");
74
75     my $feed = XML::Feed->parse( URI->new($rssFeedUrl) )
76       or return XML::Feed->errstr;
77
78     my $curTitle = $feed->title;
79     &::DEBUG("rssFeed: TITLE: $curTitle");
80     my @curEntries;
81
82     for my $entry ( $feed->entries ) {
83         &::DEBUG( "rssFeed: ENTRY: " . $entry->title );
84         push @curEntries, $entry->title;
85     }
86
87     # Create the cache if it doesnt exist
88     &createCache($cacheFile)
89       if ( !-e $cacheFile );
90
91     my @oldEntries = &getCacheEntry( $cacheFile, $rssFeedUrl );
92     my @newEntries;
93     foreach (@curEntries) {
94         &::DEBUG("rssFeed: CACHE: $_");
95         last if ( $_ eq $oldEntries[0] );
96         push @newEntries, $_;
97     }
98
99     if ( scalar @newEntries == 0 ) {    # if there wasn't anything new
100         return "rssFeed: No new headlines for $curTitle.";
101     }
102
103     # save to hash again
104     &saveCache( $cacheFile, $rssFeedUrl, @curEntries )
105       or return "rssFeed: Could not save cache!";
106
107     my $reply = &::formListReply( 0, $curTitle, @newEntries );
108     &::msg( $chan, $reply );
109
110     #           "\002<<\002$curTitle\002>>\002 " . join( " \002::\002 ", @newEntries ) );
111
112     return;
113 }
114
115 sub RSS {
116     my ($command) = @_;
117     my $cacheFile = "$::param{tempDir}/rssFeed.cache";
118     my %feeds;
119
120     if ( not $command =~ /^(flush|update)?$/i ) {
121         &::status("rssFeed: Unknown command: $command");
122         return;
123     }
124
125     if ( $command =~ /^flush$/i ) {
126         if ( not &::IsFlag("o") ) {
127             &::status(
128                 "rssFeed: User $::who tried to flush the cache, but isn't +o!");
129             return;
130         }
131         unlink $cacheFile if ( -e $cacheFile );
132         &::status("rssFeed: Flushing cache.");
133         &::performStrictReply("$::who: Flushed RSS Feed cache.");
134         return;
135     }
136
137     if ( $command =~ /^update$/i ) {
138         if ( not &::IsFlag("o") ) {
139             &::status(
140 "rssFeed: User $::who tried to manually update feeds, but isn't +o!"
141             );
142             return;
143         }
144         &::status("rssFeed: Manual update of feeds requested by $::who.");
145     }
146
147     foreach my $chan ( keys %::channels ) {
148         my $rssFeedUrl = &::getChanConf( 'rssFeedUrl', $chan );
149         my @urls = split / /, $rssFeedUrl;
150
151         # Store by url then chan to allow for same url's in multiple channels
152         foreach (@urls) { $feeds{$chan}{$_} = 1 }
153     }
154
155     foreach my $chans ( keys %feeds ) {
156         foreach ( keys %{ $feeds{$chans} } ) {
157             my $result = &getFeed( $cacheFile, $chans, $_ );
158             &::status($result) if $result;
159         }
160     }
161     return;
162 }
163
164 1;
165
166 # vim:ts=4:sw=4:expandtab:tw=80