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