@@ -, +, @@ - adds social network information in search results - adds babeltheque data in opac-detail - adds social network links in opac-detail too (google+, twitter, mail and co.) --- C4/SocialData.pm | 129 +++++++++++++++++ installer/data/mysql/kohastructure.sql | 16 ++ installer/data/mysql/sysprefs.sql | 4 + installer/data/mysql/updatedatabase.pl | 26 ++++ .../admin/preferences/enhanced_content.pref | 6 + .../en/modules/admin/preferences/searching.pref | 7 + koha-tmpl/opac-tmpl/prog/en/css/opac.css | 152 +++++++++++++++++++- .../opac-tmpl/prog/en/includes/opac-bottom.inc | 4 - koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt | 59 ++++++-- .../opac-tmpl/prog/en/modules/opac-results.tt | 20 +++ koha-tmpl/opac-tmpl/prog/images/Star0.gif | Bin 0 -> 1360 bytes koha-tmpl/opac-tmpl/prog/images/Star1.gif | Bin 0 -> 1395 bytes koha-tmpl/opac-tmpl/prog/images/Star2.gif | Bin 0 -> 1410 bytes koha-tmpl/opac-tmpl/prog/images/Star3.gif | Bin 0 -> 1391 bytes koha-tmpl/opac-tmpl/prog/images/Star4.gif | Bin 0 -> 1380 bytes koha-tmpl/opac-tmpl/prog/images/Star5.gif | Bin 0 -> 1284 bytes koha-tmpl/opac-tmpl/prog/images/bonus.png | Bin 0 -> 1768 bytes .../opac-tmpl/prog/images/socnet/delicious16.gif | Bin 0 -> 89 bytes .../opac-tmpl/prog/images/socnet/facebook16.png | Bin 0 -> 727 bytes .../opac-tmpl/prog/images/socnet/linkedin16.png | Bin 0 -> 751 bytes .../opac-tmpl/prog/images/socnet/mailto16.png | Bin 0 -> 792 bytes .../opac-tmpl/prog/images/socnet/twitter16.png | Bin 0 -> 780 bytes .../cronjobs/social_data/get_report_social_data.pl | 16 ++ misc/cronjobs/social_data/update_social_data.pl | 16 ++ opac/opac-detail.pl | 7 + opac/opac-search.pl | 19 +++- 26 files changed, 463 insertions(+), 18 deletions(-) create mode 100644 C4/SocialData.pm create mode 100644 koha-tmpl/opac-tmpl/prog/images/Star0.gif create mode 100644 koha-tmpl/opac-tmpl/prog/images/Star1.gif create mode 100644 koha-tmpl/opac-tmpl/prog/images/Star2.gif create mode 100644 koha-tmpl/opac-tmpl/prog/images/Star3.gif create mode 100644 koha-tmpl/opac-tmpl/prog/images/Star4.gif create mode 100644 koha-tmpl/opac-tmpl/prog/images/Star5.gif create mode 100644 koha-tmpl/opac-tmpl/prog/images/bonus.png create mode 100644 koha-tmpl/opac-tmpl/prog/images/socnet/delicious16.gif create mode 100644 koha-tmpl/opac-tmpl/prog/images/socnet/facebook16.png create mode 100644 koha-tmpl/opac-tmpl/prog/images/socnet/linkedin16.png create mode 100644 koha-tmpl/opac-tmpl/prog/images/socnet/mailto16.png create mode 100644 koha-tmpl/opac-tmpl/prog/images/socnet/twitter16.png create mode 100644 misc/cronjobs/social_data/get_report_social_data.pl create mode 100644 misc/cronjobs/social_data/update_social_data.pl --- a/C4/SocialData.pm +++ a/C4/SocialData.pm @@ -0,0 +1,129 @@ +package C4::SocialData; + +# This file is part of Koha. +# +# Koha is free software; you can redistribute it and/or modify it under the +# terms of the GNU General Public License as published by the Free Software +# Foundation; either version 2 of the License, or (at your option) any later +# version. +# +# Koha 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 License for more details. +# +# You should have received a copy of the GNU General Public License along with +# Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place, +# Suite 330, Boston, MA 02111-1307 USA + +use Modern::Perl; +use C4::Context; +use Business::ISBN; +use C4::Koha; + +=head2 get_data + +Get social data from a biblio + +params: + $isbn = isbn of the biblio (it must be the same in your database, isbn given to babelio) + +returns: + this function returns an hashref with keys + + isbn = isbn + num_critics = number of critics + num_critics_pro = number of profesionnal critics + num_quotations = number of quotations + num_videos = number of videos + score_avg = average score + num_scores = number of score +=cut +sub get_data { + my ( $isbn ) = @_; + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare( qq{SELECT * FROM social_data WHERE isbn = ? LIMIT 1} ); + $sth->execute( $isbn ); + my $results = $sth->fetchrow_hashref; + + return $results; +} + +=head 2 + +Update Social data + +params: + $url = url containing csv file with data + +data separator : ; (semicolon) +data order : isbn ; active ; critics number , critics pro number ; quotations number ; videos number ; average score ; scores number + +=cut +sub update_data { + my ( $output_filepath ) = @_; + + my $dbh = C4::Context->dbh; + my $sth = $dbh->prepare( qq{INSERT INTO social_data ( + `isbn`, `num_critics`, `num_critics_pro`, `num_quotations`, `num_videos`, `score_avg`, `num_scores` + ) VALUES ( ?, ?, ?, ?, ?, ?, ? ) + ON DUPLICATE KEY UPDATE `num_critics`=?, `num_critics_pro`=?, `num_quotations`=?, `num_videos`=?, `score_avg`=?, `num_scores`=? + } ); + + open( FILE, $output_filepath ) or die "File $output_filepath can not be read"; + my $sep = qq{;}; + my $i = 0; + my $unknown = 0; + while ( my $line = ) { + my ( $isbn, $active, $num_critics, $num_critics_pro, $num_quotations, $num_videos, $score_avg, $num_scores ) = split $sep, $line; + next if not $active; + eval { + $sth->execute( $isbn, $num_critics, $num_critics_pro, $num_quotations, $num_videos, $score_avg, $num_scores, + $num_critics, $num_critics_pro, $num_quotations, $num_videos, $score_avg, $num_scores + ); + }; + if ( $@ ) { + warn "Can't insert $isbn ($@)"; + } else { + $i++; + } + } + say "$i data insered or updated"; +} + +=head 2 + +Get social data report + +=cut +sub get_report { + my $dbh = C4::Context->dbh; + + my $sth = $dbh->prepare( qq{ + SELECT biblionumber, isbn FROM biblioitems + } ); + $sth->execute; + my %results; + while ( my ( $biblionumber, $isbn ) = $sth->fetchrow() ) { + push @{ $results{no_isbn} }, { biblionumber => $biblionumber } and next if not $isbn; + my $original_isbn = $isbn; + $isbn =~ s/^\s*(\S*)\s*$/$1/; + $isbn = GetNormalizedISBN( $isbn, undef, undef ); + $isbn = Business::ISBN->new( $isbn ); + next if not $isbn; + eval{ + $isbn = $isbn->as_isbn13->as_string; + }; + next if $@; + $isbn =~ s/-//g; + my $social_datas = C4::SocialData::get_data( $isbn ); + if ( $social_datas ) { + push @{ $results{with} }, { biblionumber => $biblionumber, isbn => $isbn, original => $original_isbn }; + } else { + push @{ $results{without} }, { biblionumber => $biblionumber, isbn => $isbn, original => $original_isbn }; + } + } + return \%results; +} + +1; + --- a/installer/data/mysql/kohastructure.sql +++ a/installer/data/mysql/kohastructure.sql @@ -2687,6 +2687,22 @@ CREATE TABLE `bibliocoverimage` ( CONSTRAINT `bibliocoverimage_fk1` FOREIGN KEY (`biblionumber`) REFERENCES `biblio` (`biblionumber`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB DEFAULT CHARSET=utf8; +-- +-- Table structure for table `social_data` +-- + +DROP TABLE IF EXISTS `social_data`; +CREATE TABLE IF NOT EXISTS `social_data` ( + `isbn` VARCHAR(30), + `num_critics` INT, + `num_critics_pro` INT, + `num_quotations` INT, + `num_videos` INT, + `score_avg` DECIMAL(5,2), + `num_scores` INT, + PRIMARY KEY (`isbn`) +) ENGINE=InnoDB DEFAULT CHARSET=utf8; + /*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; /*!40101 SET SQL_MODE=@OLD_SQL_MODE */; /*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; --- a/installer/data/mysql/sysprefs.sql +++ a/installer/data/mysql/sysprefs.sql @@ -337,3 +337,7 @@ INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('BorrowerRenewalPeriodBase', 'now', 'Set whether the borrower renewal date should be counted from the dateexpiry or from the current date ','dateexpiry|now','Choice'); INSERT INTO `systempreferences` (variable,value,options,explanation,type) VALUES ('AllowItemsOnHoldCheckout',0,'Do not generate RESERVE_WAITING and RESERVED warning when checking out items reserved to someone else. This allows self checkouts for those items.','','YesNo'); INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('OpacExportOptions','bibtex|dc|marcxml|marc8|utf8|marcstd|mods|ris','Define export options available on OPAC detail page.','','free'); +INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('Babeltheque_url_js','','Url for Babeltheque javascript (e.g. http://www.babeltheque.com/bw_XX.js)','','Free'); +INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('Babeltheque_url_update', '', 'Url for Babeltheque update (E.G. http://www.babeltheque.com/.../file.csv.bz2)', '', 'Free'); +INSERT INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('SocialNetworks','1','Enable/Disable social networks links in opac detail pages','','YesNo'); + --- a/installer/data/mysql/updatedatabase.pl +++ a/installer/data/mysql/updatedatabase.pl @@ -4719,6 +4719,32 @@ if (C4::Context->preference("Version") < TransformToNum($DBversion)) { SetVersion ($DBversion); } +$DBversion = "3.07.00.XXX"; +if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) { + $dbh->do( qq{INSERT IGNORE INTO `systempreferences` (variable,value,explanation,options,type) VALUES('Babeltheque_url_js','','Url for Babeltheque javascript (e.g. http://www.babeltheque.com/bw_XX.js','','Free')} ); + $dbh->do( qq{CREATE TABLE IF NOT EXISTS `social_data` + ( `isbn` VARCHAR(30), + `num_critics` INT, + `num_critics_pro` INT, + `num_quotations` INT, + `num_videos` INT, + `score_avg` DECIMAL(5,2), + `num_scores` INT, + PRIMARY KEY (`isbn`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8 + } ); + $dbh->do( qq{INSERT IGNORE INTO `systempreferences` (variable,value,explanation,options,type) VALUES ('Babeltheque_url_update', '', 'Url for Babeltheque update (E.G. http://www.babeltheque.com/.../file.csv.bz2)', '', 'Free')} ); + print "Upgrade to $DBversion done (added syspref and table for babeltheque (Babeltheque_url_js, babeltheque))\n"; + SetVersion($DBversion); +} + +$DBversion = "3.07.00.XXX"; +if ( C4::Context->preference("Version") < TransformToNum($DBversion) ) { + $dbh->do( qq{INSERT IGNORE INTO `systempreferences` (variable,value,explanation,options,type) VALUES('SocialNetworks','1','Enable/Disable social networks links in opac detail','','YesNo')} ); + print "Upgrade to $DBversion done (added syspref Social_networks)\n"; + SetVersion($DBversion); +} + =head1 FUNCTIONS =head2 DropAllForeignKeys($table) --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/enhanced_content.pref +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/enhanced_content.pref @@ -103,6 +103,12 @@ Enhanced Content: yes: Do no: "Don't" - include information (such as reviews and citations) from Babelthèque in item detail pages on the OPAC. + - + - pref: Babeltheque_url_js + - Defined the url for the Babeltheque javascript file (eg. http://www.babeltheque.com/bw_XX.js) + - + - pref: Babeltheque_url_update + - Defined the url for the Babeltheque update periodically (eq. http://www.babeltheque.com/.../file.csv.bz2). Baker and Taylor: - - pref: BakerTaylorEnabled --- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/searching.pref +++ a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/searching.pref @@ -69,6 +69,13 @@ Searching: yes: Include no: "Don't include" - subdivisions for searches generated by clicking on subject tracings. + - + - pref: SocialNetworks + default: 0 + choices: + yes: Enable + no: Disable + - Enable/Disable social network links in opac detail pages Search Form: - - Show checkboxes to search by --- a/koha-tmpl/opac-tmpl/prog/en/css/opac.css +++ a/koha-tmpl/opac-tmpl/prog/en/css/opac.css @@ -2309,4 +2309,154 @@ a.localimage img { border : 1px solid #8EB3E7; margin : 0 .5em; padding : .3em; -} +} + +/* ## BABELTHEQUE ## */ +/* Uncomment if babeltheque configuration no contains these lines */ +/* +#BW_etiquettes { + clear :left; + border: 1px solid #E8E8E8; + margin-top: 10px; + width: 49%; + float: left; + visibility: hidden; + visibility: visible\9; +} +#BW_etiquettes:not(:empty) { + visibility: visible; +} + +#BW_etiquettes h2 { + clear:left; + background-color: #E8E8E8; + margin: 5px 10px; + padding: 0 5px; +} + +#BW_ulEti {max-width:100%;} + +#BW_ulEti ul { + margin:0; + padding:0 15px; + list-style-type: none; +} + +#BW_ulEti a { + text-decoration: none; +} + +#BW_ulEti a.tag_s0 {font-weight: 120;font-size:0.8em;} +#BW_ulEti a.tag_s1 {font-weight: 150;font-size:0.9em;} +#BW_ulEti a.tag_s2 {font-weight: 180;font-size:1.0em;} +#BW_ulEti a.tag_s3 {font-weight: 200;font-size:1.2em;} +#BW_ulEti a.tag_s4 {font-weight: 220;font-size:1.4em;} +#BW_ulEti a.tag_s5 {font-weight: 230;font-size:1.5em;} +#BW_ulEti a.tag_s6 {font-weight: 320;font-size:1.6em;} +#BW_ulEti a.tag_s7 {font-weight: 350;font-size:1.7em;} +#BW_ulEti a.tag_s8 {font-weight: 400;font-size:1.8em;} +#BW_ulEti { padding: 0px; line-height: 2em; text-align: center;} +#BW_ulEti a { padding: 2px; } +#BW_ulEti { margin: 0px; } + +#BW_ulEti ol { + float:left; + display: inline; + margin: 0 10px; +} + +#BW_suggestions { + border: 1px solid #E8E8E8; + margin-top: 10px; + float: right; + width: 49%; + visibility: hidden; + visibility: visible\9; +} +#BW_suggestions:not(:empty) { + visibility: visible; +} +#BW_suggestions h2 { + background-color: #E8E8E8; + margin: 5px 10px; + padding: 0 5px; +} +#BW_suggestions .BW_livres_tag_page { + padding: 0 15px; +} +#BW_suggestions .BW_livres_tag_page:before { + content : '> '; +} +#BW_droite .BW_livres_tag:before { + content : '> '; +} + +#BW_videos { + clear : both; + border: 1px solid #E8E8E8; + padding-bottom: 140px; + margin-top: 10px; + max-width: 100%; + visibility: hidden; + visibility: visible\9; +} + +#BW_videos:not(:empty) { + visibility: visible; +} + +#BW_videos h2 { + background-color: #E8E8E8; + margin: 5px 10px; + padding: 0 5px; +} +#BW_videos .BW_bloc_vid { + clear: both; + padding: 0 15px; +} +.BW_vignette_vid { + border: 1px solid #DFD9CE; + float: left; + height: 141px; + margin: 5px; + min-height: 141px; + padding: 5px; + white-space: nowrap; +} + +#BW_notes {clear :left;} +#BW_notes h2 {font-size:85%;} + +#BW_citations {} +#BW_citations h2 {font-size:85%;} + +#BW_critiques {} +#BW_critiques h2 {font-size:85%;} + +#BW_critiques_pro {} +#BW_critiques_pro h2 {font-size:85%;} + +#BW_citations,#BW_critiques,#BW_critiques_pro { + background: -moz-linear-gradient(center top , #3399FF, #3333FF) repeat scroll 0 0 transparent; + background: -webkit-gradient(linear, center top, center bottom, from(#3399FF), to(#3333FF)); + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#3399FF', endColorstr='#3333FF'); + border: 1px solid #B7B7B7; + border-radius: 5px 5px 5px 5px; + color: #FFFFCC; + display: inline-block; + float: left; + font-weight: bold; + margin: 15px 20px 15px 0; + min-width: 150px; + padding: 0 15px 8px; + position: relative; + text-align: center; + text-shadow: 1px 1px 1px #777777; + white-space: nowrap; +} + +#BW_citations a,#BW_critiques a,#BW_critiques_pro a { + color: #FFFFCC; +} + +*/ --- a/koha-tmpl/opac-tmpl/prog/en/includes/opac-bottom.inc +++ a/koha-tmpl/opac-tmpl/prog/en/includes/opac-bottom.inc @@ -53,9 +53,5 @@ [% END %] -[% IF ( Babeltheque ) %] - -[% END %] - --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt +++ a/koha-tmpl/opac-tmpl/prog/en/modules/opac-detail.tt @@ -1,6 +1,11 @@ [% INCLUDE 'doc-head-open.inc' %][% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha Online[% END %] Catalog › Details for: [% title |html %][% FOREACH subtitl IN subtitle %], [% subtitl.subfield |html %][% END %] [% INCLUDE 'doc-head-close.inc' %] + + + [% END %] + +[% IF ( Babeltheque ) %] + +[% END %] + [% INCLUDE 'opac-bottom.inc' %] --- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt +++ a/koha-tmpl/opac-tmpl/prog/en/modules/opac-results.tt @@ -389,6 +389,9 @@ $(document).ready(function(){ [% IF ( SEARCH_RESULT.imageurl ) %] [% SEARCH_RESULT.description %] [% END %] + [% IF ( SEARCH_RESULT.score_avg ) %] + + [% END %] [% END %] [% END %] @@ -477,6 +480,23 @@ $(document).ready(function(){ [% END %] + [% IF ( SEARCH_RESULT.score_avg ) %] + + [% SEARCH_RESULT.score_avg %] / 5 (on [% SEARCH_RESULT.num_scores %] rates) + [% IF ( SEARCH_RESULT.num_critics ) %] + + [% END %] + [% IF ( SEARCH_RESULT.num_critics_pro ) %] + + [% END %] + [% IF ( SEARCH_RESULT.num_videos ) %] + + [% END %] + [% IF ( SEARCH_RESULT.num_quotations ) %] + + [% END %] + + [% END %] [% IF ( LibraryThingForLibrariesID ) %]
[% END %] [% IF ( opacuserlogin ) %][% IF ( TagsEnabled ) %] [% IF ( TagsShowOnList ) %] --- a/misc/cronjobs/social_data/get_report_social_data.pl +++ a/misc/cronjobs/social_data/get_report_social_data.pl @@ -0,0 +1,16 @@ +#!/bin/perl + +use Modern::Perl; +use C4::SocialData; + +my $results = C4::SocialData::get_report; + +say "==== Social Data report ===="; +say "Matched : (" . scalar( @{ $results->{with} } ) . ")"; +say "biblionumber = $_->{biblionumber},\toriginal = $_->{original},\tisbn = $_->{isbn}" for @{ $results->{with} }; + +say "No Match : (" . scalar( @{ $results->{without} } ) . ")"; +say "biblionumber = $_->{biblionumber},\toriginal = $_->{original},\tisbn = $_->{isbn}" for @{ $results->{without} }; + +say "Without ISBN : (" . scalar( @{ $results->{no_isbn} } ) . ")"; +say "biblionumber = $_->{biblionumber}" for @{ $results->{no_isbn} }; --- a/misc/cronjobs/social_data/update_social_data.pl +++ a/misc/cronjobs/social_data/update_social_data.pl @@ -0,0 +1,16 @@ +#!/usr/bin/perl + +use Modern::Perl; +use C4::Context; +use C4::SocialData; + +my $url = C4::Context->preference( "Babeltheque_url_update" ); +my $output_dir = qq{/tmp}; +my $output_filepath = qq{$output_dir/social_data.csv}; +system( qq{/bin/rm -f $output_filepath} ); +system( qq{/bin/rm -f $output_dir/social_data.csv.bz2} ); +system( qq{/usr/bin/wget $url -O $output_dir/social_data.csv.bz2 } ) == 0 or die "Can't get bz2 file from url $url ($?)"; +system( qq{/bin/bunzip2 $output_dir/social_data.csv.bz2 } ) == 0 or die "Can't extract bz2 file ($?)"; + + +C4::SocialData::update_data $output_filepath; --- a/opac/opac-detail.pl +++ a/opac/opac-detail.pl @@ -836,9 +836,16 @@ $template->param(NovelistSelectView => C4::Context->preference('NovelistSelectVi if ( C4::Context->preference("Babeltheque") ) { $template->param( Babeltheque => 1, + Babeltheque_url_js => C4::Context->preference("Babeltheque_url_js"), ); } +# Social Networks +if ( C4::Context->preference( "SocialNetworks" ) ) { + $template->param( current_url => C4::Context->preference('OPACBaseURL') . "/cgi-bin/koha/opac-detail.pl?biblionumber=$biblionumber" ); + $template->param( SocialNetworks => 1 ); +} + # Shelf Browser Stuff if (C4::Context->preference("OPACShelfBrowser")) { # pick the first itemnumber unless one was selected by the user --- a/opac/opac-search.pl +++ a/opac/opac-search.pl @@ -36,10 +36,11 @@ use C4::Biblio; # GetBiblioData use C4::Koha; use C4::Tags qw(get_tags); use C4::Branch; # GetBranches +use C4::SocialData; use POSIX qw(ceil floor strftime); use URI::Escape; use Storable qw(thaw freeze); - +use Business::ISBN; my $DisplayMultiPlaceHold = C4::Context->preference("DisplayMultiPlaceHold"); # create a new CGI object @@ -525,9 +526,23 @@ for (my $i=0;$i<@servers;$i++) { foreach (@newresults) { my $record = GetMarcBiblio($_->{'biblionumber'}); $_->{coins} = GetCOinSBiblio($record); + if ( C4::Context->preference( "Babeltheque" ) and $_->{normalized_isbn} ) { + my $isbn = Business::ISBN->new( $_->{normalized_isbn} ); + next if not $isbn; + $isbn = $isbn->as_isbn13->as_string; + $isbn =~ s/-//g; + my $social_datas = C4::SocialData::get_data( $isbn ); + next if not $social_datas; + for my $key ( keys %$social_datas ) { + $_->{$key} = $$social_datas{$key}; + if ( $key eq 'score_avg' ){ + $_->{score_int} = sprintf("%.0f", $$social_datas{score_avg} ); + } + } + } } } - + if ($results_hashref->{$server}->{"hits"}){ $total = $total + $results_hashref->{$server}->{"hits"}; } --