Bug 9988: Refactor the cron script

The cron job is moved from migration tools to cronjobs. And renamed to
a plural form. The script is now based on Koha objects. It does no longer
include the code to merge one record. This can be done via the interface,
and will be added to a maintenance script on bug 18071. Should not be part
of this cron job.

Adding a cron_cleanup method to MergeRequests; this method is called from
the cron script to reset older entries still marked in progress and to
also remove old processed entries. Tested in a separate unit test.

Test plan:
[1] Run t/db_dependent/Authorities/MergeRequests.t
[2] Set AuthorityMergeLimit to 0. (All merges are postponed.)
[3] Modify an authority linked to a few records.
[4] Delete an authority linked to a few records with batch delete tool.
[5] And select two auth records with linked records.
    Merge these two records with authority/merge.pl.
    Note: Do not select Default. See also bug 17380.
[6] Check the need_merge_authorities table for inserted records.
[7] Run misc/cronjobs/merge_authorities.pl -b and inspect the linked
    records and the record status in need_merge_authorities.

Signed-off-by: Marc Véron <veron@veron.ch>
Signed-off-by: Jacek Ablewicz <abl@biblos.pk.edu.pl>
Signed-off-by: Julian Maurice <julian.maurice@biblibre.com>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
This commit is contained in:
Marcel de Rooy 2017-02-22 16:51:58 +01:00 committed by Kyle M Hall
parent d49e8bd5e2
commit dea93375dc
4 changed files with 169 additions and 104 deletions

View file

@ -23,6 +23,8 @@ use MARC::Record;
use C4::Context;
use Koha::Authority::MergeRequest;
use Koha::Database;
use Koha::DateUtils;
use parent qw(Koha::Objects);
@ -69,6 +71,40 @@ sub reporting_tag_xml {
);
}
=head3 cron_cleanup
Koha::Authority::MergeRequests->cron_cleanup({
reset_hours => 24, remove_days => 90,
});
Removes all entries with status "done" older than remove_days.
Set all entries with status "in progress" back to 0 when the timestamp
is older than reset_hours.
Defaults: reset_hours = 1, remove_days = 30.
=cut
sub cron_cleanup {
my ( $class_or_self, $params ) = @_;
my $reset_hours = $params->{reset_hours} || 1;
my $remove_days = $params->{remove_days} || 30;
my $parser = Koha::Database->new->schema->storage->datetime_parser;
my $dt = dt_from_string;
$dt->subtract( hours => $reset_hours );
$class_or_self->search({
done => 2,
timestamp => { '<' => $parser->format_datetime($dt) },
})->update({ done => 0 });
$dt = dt_from_string;
$dt->subtract( days => $remove_days );
$class_or_self->search({
done => 1,
timestamp => { '<' => $parser->format_datetime($dt) },
})->delete;
}
=head3 _type
Returns name of corresponding DBIC resultset

View file

@ -0,0 +1,89 @@
#!/usr/bin/perl
use Modern::Perl;
use Getopt::Long;
use Pod::Usage;
use Time::HiRes qw(gettimeofday);
use C4::AuthoritiesMarc;
use Koha::Authority::MergeRequests;
use constant RESET_HOURS => 24;
use constant REMOVE_DAYS => 30;
my ( $params );
GetOptions(
'h' => \$params->{help},
'v' => \$params->{verbose},
'b' => \$params->{batch},
);
$|=1; # flushes output
if( $params->{batch} ) {
handle_batch( $params );
} else {
pod2usage(1);
}
sub handle_batch {
my $params = shift;
my $verbose = $params->{verbose};
my $starttime = gettimeofday;
print "Started merging\n" if $verbose;
Koha::Authority::MergeRequests->cron_cleanup({ reset_hours => RESET_HOURS, remove_days => REMOVE_DAYS });
my $rs = Koha::Authority::MergeRequests->search(
{ done => 0 },
{ order_by => { -asc => 'id' }}, # IMPORTANT
);
# For best results, postponed merges should be applied in right order.
# Similarly, we do not only select the last one for a specific id.
while( my $req = $rs->next ) {
$req->done(2)->store;
print "Merging auth " . $req->authid . " to " . ( $req->authid_new // 'NULL' ) . ".\n" if $verbose;
my $newmarc = $req->authid_new
? GetAuthority( $req->authid_new )
: undef;
# Following merge call handles both modifications and deletes
merge({
mergefrom => $req->authid,
MARCfrom => scalar $req->oldmarc,
mergeto => $req->authid_new,
MARCto => $newmarc,
override_limit => 1,
});
$req->done(1)->store;
}
my $timeneeded = gettimeofday - $starttime;
print "Done in $timeneeded seconds\n" if $verbose;
}
=head1 NAME
merge_authorities.pl
=head1 DESCRIPTION
Cron script to handle authority merge requests
=head1 SYNOPSIS
merge_authorities.pl -h
merge_authorities.pl -b -v
=head1 OPTIONS
-b : batch mode (You need to pass this parameter from crontab file)
-h : print usage statement
-v : verbose mode
=head1 AUTHOR
Koha Development Team
=cut

View file

@ -1,104 +0,0 @@
#!/usr/bin/perl
# script that rebuild thesaurus from biblio table.
use strict;
#use warnings; FIXME - Bug 2505
BEGIN {
# find Koha's Perl modules
# test carefully before changing this
use FindBin;
eval { require "$FindBin::Bin/kohalib.pl" };
}
# Koha modules used
use C4::Context;
use C4::Search;
use C4::Biblio;
use C4::AuthoritiesMarc;
use Koha::Authorities;
use Koha::Authority::MergeRequests;
use Time::HiRes qw(gettimeofday);
use Getopt::Long;
my ($version, $verbose, $mergefrom,$mergeto,$noconfirm,$batch);
GetOptions(
'h' => \$version,
'f:s' => \$mergefrom,
't:s' => \$mergeto,
'v' => \$verbose,
'n' => \$noconfirm,
'b' => \$batch,
);
if ($version || ($mergefrom eq '' && !$batch)) {
print <<EOF
Script to merge an authority into another
parameters :
\th : this version/help screen
\tv : verbose mode (show many things on screen)
\tf : the authority number to merge (the one that can be deleted after the merge).
\tt : the authority number where to merge
\tn : don't ask for confirmation (useful for batch mergings, should not be used on command line)
\tb : batch Merging
All biblios with the authority in -t will be modified to be "connected" to authority -f
SAMPLE :
./merge_authority.pl -f 2457 -t 531
Before doing anything, the script will show both authorities and ask for confirmation. Of course, you can merge only 2 authorities of the same kind.
EOF
;#
die;
}#/'
my $dbh = C4::Context->dbh;
$|=1; # flushes output
my $authfrom = GetAuthority($mergefrom);
my $authto = GetAuthority($mergeto);
die "Authority $mergefrom does not exist" unless $authfrom;
die "Authority $mergeto does not exist" unless $authto;
my $authtypecodefrom = Koha::Authorities->find($mergefrom)->authtypecode;
my $authtypecodeto = Koha::Authorities->find($mergeto)->authtypecode;
unless ($noconfirm || $batch) {
print "************\n";
print "You will merge authority : $mergefrom ($authtypecodefrom)\n".$authfrom->as_formatted;
print "\n*************\n";
print "Into authority : $mergeto ($authtypecodeto)\n".$authto->as_formatted;
print "\n\nDo you confirm (enter YES)?";
my $confirm = <STDIN>;
chop $confirm;
unless (uc($confirm) eq 'YES' and $authtypecodefrom eq $authtypecodeto) {
print "IMPOSSIBLE : authorities are not of the same type ($authtypecodefrom vs $authtypecodeto) !!!\n" if $authtypecodefrom ne $authtypecodeto;
print "Merge cancelled\n";
exit;
}
}
my $starttime = gettimeofday;
print "Merging\n" unless $noconfirm;
if ($batch) {
my $authref;
$dbh->do("update need_merge_authorities set done=2 where done=0"); #temporary status 2 means: selected for merge
$authref=$dbh->selectall_arrayref("select id,authid,authid_new from need_merge_authorities where done=2");
foreach my $row ( @$authref ) {
my $req = Koha::Authority::MergeRequests->find( $row->[0] );
my $marc = $req ? $req->oldmarc : undef;
my $authid = $row->[1];
my $authid_new = $row->[2];
print "managing $authid\n" if $verbose;
# Following merge call handles both modifications and deletes
merge({ mergefrom => $authid, MARCfrom => $marc, mergeto => $authid_new, MARCto => GetAuthority($authid_new), override_limit => 1 });
}
$dbh->do("update need_merge_authorities set done=1 where done=2"); #DONE
} else {
my $MARCfrom = GetAuthority($mergefrom);
my $MARCto = GetAuthority($mergeto);
&merge({ mergefrom => $mergefrom, MARCfrom => $MARCfrom, mergeto => $mergeto, MARCto => $MARCto });
#Could add mergefrom authority to mergeto rejected forms before deletion
DelAuthority({ authid => $mergefrom }) if ($mergefrom != $mergeto);
}
my $timeneeded = gettimeofday - $starttime;
print "Done in $timeneeded seconds" unless $noconfirm;

View file

@ -0,0 +1,44 @@
#!/usr/bin/perl
use Modern::Perl;
use Test::More tests => 1;
use Koha::Authority::MergeRequest;
use Koha::Authority::MergeRequests;
use Koha::Database;
use Koha::DateUtils qw/dt_from_string/;
my $schema = Koha::Database->new->schema;
$schema->storage->txn_begin;
subtest "Tests for cron_cleanup" => sub {
plan tests => 3;
my $dt = dt_from_string;
$dt->subtract( hours => 2 );
my $req1 = Koha::Authority::MergeRequest->new({
authid => 1,
done => 2,
timestamp => $dt,
})->store;
$dt->subtract( days => 30 );
my $req2 = Koha::Authority::MergeRequest->new({
authid => 2,
done => 1,
timestamp => $dt,
})->store;
# Now test two cleanup calls
# First call should only remove req2; second call should reset req1
Koha::Authority::MergeRequests->cron_cleanup({ reset_hours => 3 });
$req1->discard_changes; # requery
is( $req1->done, 2, 'My request was not touched' );
$req2->discard_changes; # requery
is( $req2->in_storage, 0, 'Second request removed' );
Koha::Authority::MergeRequests->cron_cleanup({ reset_hours => 1 });
$req1->discard_changes; # requery
is( $req1->done, 0, 'Yes, we got a reset' );
};
$schema->storage->txn_rollback;