Script to allow patrons to download the due dates for the books in ICalendar format
[koha.git] / opac / opac-rss.pl
1 #!/usr/bin/perl
2
3 use strict;    # always use
4
5 use XML::RSS;
6 use Digest::MD5 qw(md5_base64);
7 use POSIX qw(ceil floor);
8 use Date::Calc qw(Today_and_Now Delta_YMDHMS);
9 use C4::Context;
10 use C4::Search;
11 use C4::Koha;
12 use C4::Biblio;
13
14 # Copyright 2007 Paul POULAIN
15 #
16 # This file is part of Koha
17 #
18 # Koha is free software; you can redistribute it and/or modify it under the
19 # terms of the GNU General Public License as published by the Free Software
20 # Foundation; either version 2 of the License, or (at your option) any later
21 # version.
22 #
23 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
24 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
25 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
26 #
27 # You should have received a copy of the GNU General Public License along with
28 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
29 # Suite 330, Boston, MA  02111-1307 USA
30
31 =head1 NAME
32
33 opac-search.pl : script to have RSS feeds automatically on each OPAC search
34
35 =head1 SYNOPSIS
36
37 on each query (on OPAC), a link to this script is automatically added. The user can save it's queries as RSS feeds.
38 This script :
39
40 =over 4
41
42   - build the RDF file from the query
43   - save the RDF file in a opac/rss directory for caching : the RDF is calculated only once every 30mn, and the cache file name is calculated by a md5_base64 of the query (each user registering the same query will use the same cache : speed improvement)
44   - let the user specify it's query (q parameter : opac-rss.pl?q=ti:hugo)
45   - let the user specify the number of results returned (by default 20, but there are no limits : opac-rss.pl?q=ti:hugo&size=9999)
46
47 This script auto calculates the website URL
48
49 the RDF contains : 
50
51 =over 4
52
53   - Koha: $query as RSS title
54   - Koha as subject
55   - LibraryName systempreference as RDF description and creator
56   - copyright currentyear
57   - biblio title as RSS "title" and biblio author as RSS description
58
59 =cut
60
61 # create a new CGI object
62 # not sure undef_params option is working, need to test
63 use CGI qw('-no_undef_params');
64 my $cgi = new CGI;
65
66 # the query to use
67 my $query = $cgi->param('q');
68 $query =~ s/:/=/g;
69
70 # the number of lines to retrieve
71 my $size = $cgi->param('size') || 50;
72
73 # the filename of the cached rdf file.
74 my $filename = md5_base64($query);
75 my $rss = new XML::RSS( version => '1.0' );
76
77 # the site URL
78 my $url = $cgi->url();
79 $url =~ s/opac-rss\.pl.*//;
80 $url =~ /(http:\/\/.*?)\//;
81 my $short_url = $1;
82
83 my $RDF_update_needed = 1;
84 my ( $year, $month, $day, $hour, $min, $sec ) = Today_and_Now();
85
86 if ( -e "rss/$filename" ) {
87     $rss->parsefile("rss/$filename");
88
89 # check if we have to rebuild the RSS feed (once every 30mn), or just return the actual rdf
90     my $rdf_stamp = $rss->{'channel'}->{'dc'}->{'date'};
91     $rdf_stamp =~ /(.*)-(.*)-(.*):(.*):(.*):(.*)/;
92     my (
93         $stamp_year, $stamp_month, $stamp_day,
94         $stamp_hour, $stamp_min,   $stamp_sec
95     ) = ( $1, $2, $3, $4, $5, $6 );
96
97 # if more than 30 mn since the last RDF update, rebuild the RDF. Otherwise, just return it
98     unless ( ( $year - $stamp_year > 0 )
99         or ( $month - $stamp_month > 0 )
100         or ( $day - $stamp_day > 0 )
101         or ( $hour - $stamp_hour > 0 )
102         or ( $min - $stamp_min > 30 ) )
103     {
104         $RDF_update_needed = 0;
105     }
106 }
107
108 if ($RDF_update_needed) {
109
110     #     warn "RDF update in progress";
111     $rss->channel(
112         title       => "Koha : $query",
113         description => C4::Context->preference("LibraryName"),
114         link        => $short_url,
115         dc          => {
116             date     => "$year-$month-$day:$hour:$min:$sec",
117             subject  => "Koha",
118             creator  => C4::Context->preference("LibraryName"),
119             rights   => "Copyright $year",
120             language => C4::Context->preference("opaclanguages"),
121         },
122     );
123
124     my $total;    # the total results for the whole set
125     my ( $error, $marcresults ) = SimpleSearch($query);
126
127     my $hits = scalar @$marcresults;
128     $hits = $size if $hits > $size;
129     my @results;
130     for ( my $i = 0 ; $i < $hits ; $i++ ) {
131         my %resultsloop;
132         my $marcrecord = MARC::File::USMARC::decode( $marcresults->[$i] );
133         my $biblio = TransformMarcToKoha( C4::Context->dbh, $marcrecord, '' );
134
135 # check if the entry is already in the feed. Otherwise, pop the $line th line and add this new one.
136         my $already_in_feed = 0;
137         foreach ( @{ $rss->{'items'} } ) {
138             if ( $_->{'link'} =~ /biblionumber=$biblio->{'biblionumber'}/ ) {
139                 $already_in_feed = 1;
140             }
141         }
142         unless ($already_in_feed) {
143             pop( @{ $rss->{'items'} } ) if ( @{ $rss->{'items'} } >= $size );
144             $rss->add_item(
145                 title       => $biblio->{'title'},
146                 description => $biblio->{'author'},
147                 link        => "$url/opac-detail.pl?biblionumber="
148                   . $biblio->{'biblionumber'},
149                 mode => 'insert',
150             );
151         }
152     }
153
154     # save the rss feed.
155     $rss->save("rss/$filename");
156 }
157 else {
158
159     #     warn "RDF CACHE used"
160 }
161 print $cgi->header( -type => "application/rss+xml" );
162 print $rss->as_string;