]> git.donarmstrong.com Git - infobot.git/blob - src/Modules/RSSFeeds.pl
2697faf056de58753edb251f383df5a2604d7b0e
[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, ":utf8" );
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,  ":utf8" );
42         binmode( OUT, ":utf8" );
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("rssFeed: User $::who tried to flush the cache, but isn't +o!");
128                         return;
129                 }
130                 unlink $cacheFile if ( -e $cacheFile );
131                 &::status("rssFeed: Flushing cache.");
132                 &::performStrictReply("$::who: Flushed RSS Feed cache.");
133                 return;
134         }
135
136         if ( $command =~ /^update$/i ) {
137                 if ( not &::IsFlag("o") ) {
138                         &::status("rssFeed: User $::who tried to manually update feeds, but isn't +o!");
139                         return;
140                 }
141                 &::status("rssFeed: Manual update of feeds requested by $::who.");
142         }
143
144         foreach my $chan ( keys %::channels ) {
145                 my $rssFeedUrl = &::getChanConf( 'rssFeedUrl', $chan );
146                 my @urls = split / /, $rssFeedUrl;
147
148                 # Store by url then chan to allow for same url's in multiple channels
149                 foreach (@urls) { $feeds{$chan}{$_} = 1 }
150         }
151
152         foreach my $chans ( keys %feeds ) {
153                 foreach ( keys %{ $feeds{$chans} } ) {
154                         my $result = &getFeed( $cacheFile, $chans, $_ );
155                         &::status($result) if $result;
156                 }
157         }
158         return;
159 }
160
161 1;
162 # vim: ts=2 sw=2