|
Lines 89-119
sub deduplicate {
Link Here
|
| 89 |
my $verbose = $self->{verbose}; |
89 |
my $verbose = $self->{verbose}; |
| 90 |
my $biblionumbers = C4::Biblio::GetBiblionumberSlice( $self->{limit}, $self->{offset}, $self->{biblionumber} ); |
90 |
my $biblionumbers = C4::Biblio::GetBiblionumberSlice( $self->{limit}, $self->{offset}, $self->{biblionumber} ); |
| 91 |
|
91 |
|
| 92 |
my @duplicates; |
92 |
$self->{duplicates} = []; |
| 93 |
foreach my $biblionumber (@$biblionumbers) { |
93 |
foreach my $biblionumber (@$biblionumbers) { |
| 94 |
my $marc = C4::Biblio::GetMarcBiblio($biblionumber); |
94 |
my $marc = C4::Biblio::GetMarcBiblio($biblionumber); |
| 95 |
my @matches = $self->{matcher}->get_matches( $marc, $self->{max_matches} ); |
95 |
my @matches = $self->{matcher}->get_matches( $marc, $self->{max_matches} ); |
| 96 |
|
96 |
|
| 97 |
if (scalar(@matches) > 1) { |
97 |
if (scalar(@matches) > 1) { |
| 98 |
foreach my $match (@matches) { |
98 |
for (my $i=0 ; $i<scalar(@matches) ; $i++) { |
|
|
99 |
my $match = $matches[$i]; |
| 99 |
my $itemsCount = C4::Items::GetItemsCount($match->{record_id}); |
100 |
my $itemsCount = C4::Items::GetItemsCount($match->{record_id}); |
| 100 |
$match->{itemsCount} = $itemsCount; |
101 |
$match->{itemsCount} = $itemsCount; |
| 101 |
_buildSlimBiblio($match->{record_id}, $match, C4::Biblio::GetMarcBiblio($match->{record_id})); |
102 |
unless( _buildSlimBiblio($match->{record_id}, $match, C4::Biblio::GetMarcBiblio($match->{record_id})) ) { |
|
|
103 |
#Sometimes we get an error where the marcxml is not available. |
| 104 |
splice(@matches, $i, 1); |
| 105 |
$i--; #Don't advance the iterator after this round or we will skip one record! |
| 106 |
next(); |
| 107 |
} |
| 102 |
if ($match->{record_id} == $biblionumber) { |
108 |
if ($match->{record_id} == $biblionumber) { |
| 103 |
$match->{matchSource} = 'matchSource'; |
109 |
$match->{matchSource} = 'matchSource'; |
| 104 |
} |
110 |
} |
| 105 |
|
|
|
| 106 |
} |
111 |
} |
| 107 |
my $biblio = _buildSlimBiblio($biblionumber, undef, $marc); |
112 |
my $biblio = _buildSlimBiblio($biblionumber, undef, $marc); |
|
|
113 |
unless ($biblio) { #Sometimes we get an error where the marcxml is not available. |
| 114 |
next(); |
| 115 |
} |
| 108 |
$biblio->{matches} = \@matches; |
116 |
$biblio->{matches} = \@matches; |
| 109 |
|
117 |
|
| 110 |
push @duplicates, $biblio; |
118 |
push @{$self->{duplicates}}, $biblio; |
| 111 |
} |
119 |
} |
| 112 |
if ($verbose) { |
120 |
if ($verbose) { |
| 113 |
print $biblionumber."\n"; |
121 |
print $biblionumber."\n"; |
| 114 |
} |
122 |
} |
| 115 |
} |
123 |
} |
| 116 |
return \@duplicates; |
124 |
return $self->{duplicates}; |
| 117 |
} |
125 |
} |
| 118 |
|
126 |
|
| 119 |
sub _buildSlimBiblio { |
127 |
sub _buildSlimBiblio { |
|
Lines 127-133
sub _buildSlimBiblio {
Link Here
|
| 127 |
} |
135 |
} |
| 128 |
if (not($marc)) { |
136 |
if (not($marc)) { |
| 129 |
warn "C4::Deduplicator::_buildSlimBiblio(), No MARC::Record for bn:$biblionumber"; |
137 |
warn "C4::Deduplicator::_buildSlimBiblio(), No MARC::Record for bn:$biblionumber"; |
| 130 |
return $biblio; |
138 |
return undef; |
| 131 |
} |
139 |
} |
| 132 |
|
140 |
|
| 133 |
$biblio->{marc} = $marc; |
141 |
$biblio->{marc} = $marc; |
|
Lines 153-160
sub _buildSlimBiblio {
Link Here
|
| 153 |
my $author = $marc->subfield('100','a'); |
161 |
my $author = $marc->subfield('100','a'); |
| 154 |
$author = $marc->subfield('110','a') unless $author; |
162 |
$author = $marc->subfield('110','a') unless $author; |
| 155 |
|
163 |
|
| 156 |
$biblio->{author} = $author; |
164 |
$biblio->{author} = ($author) ? $author : ''; |
| 157 |
$biblio->{title} = join(' ', @titles); |
165 |
$biblio->{title} = join(' ', @titles); |
|
|
166 |
$biblio->{title} = '' unless $biblio->{title}; |
| 158 |
|
167 |
|
| 159 |
return $biblio; |
168 |
return $biblio; |
| 160 |
} |
169 |
} |
|
Lines 167-184
sub _buildSlimBiblio {
Link Here
|
| 167 |
sub batchMergeDuplicates { |
176 |
sub batchMergeDuplicates { |
| 168 |
my ($self, $duplicates, $mergeTargetFindingAlgorithm) = @_; |
177 |
my ($self, $duplicates, $mergeTargetFindingAlgorithm) = @_; |
| 169 |
|
178 |
|
| 170 |
my @errors; |
179 |
$self->{mergeErrors} = []; |
| 171 |
_findMergeTargets($duplicates, $mergeTargetFindingAlgorithm, \@errors); |
180 |
_findMergeTargets($duplicates, $mergeTargetFindingAlgorithm, $self->{mergeErrors}); |
| 172 |
|
181 |
|
| 173 |
foreach my $duplicate (@$duplicates) { |
182 |
foreach my $duplicate (@$duplicates) { |
| 174 |
foreach my $match (@{$duplicate->{matches}}) { |
183 |
foreach my $match (@{$duplicate->{matches}}) { |
| 175 |
if ($match eq $duplicate->{'mergeTarget'}) { #Comparing Perl references, if htey point to the same object. |
184 |
if ($match eq $duplicate->{'mergeTarget'}) { #Comparing Perl references, if htey point to the same object. |
| 176 |
next(); #Don't merge itself to oneself. |
185 |
next(); #Don't merge itself to oneself. |
| 177 |
} |
186 |
} |
| 178 |
merge($match, $duplicate->{'mergeTarget'}, \@errors); |
187 |
merge($match, $duplicate->{'mergeTarget'}, $self->{mergeErrors}); |
| 179 |
} |
188 |
} |
| 180 |
} |
189 |
} |
| 181 |
return \@errors if scalar @errors > 0; |
190 |
return $self->{mergeErrors} if scalar @{$self->{mergeErrors}} > 0; |
| 182 |
return undef; |
191 |
return undef; |
| 183 |
} |
192 |
} |
| 184 |
|
193 |
|
|
Lines 188-193
sub _findMergeTargets {
Link Here
|
| 188 |
if ($mergeTargetFindingAlgorithm eq 'newest') { |
197 |
if ($mergeTargetFindingAlgorithm eq 'newest') { |
| 189 |
_mergeTargetFindingAlgorithm_newest( $duplicates ); |
198 |
_mergeTargetFindingAlgorithm_newest( $duplicates ); |
| 190 |
} |
199 |
} |
|
|
200 |
else { |
| 201 |
warn "Unknown merge target finding algorithm given: '$mergeTargetFindingAlgorithm'"; |
| 202 |
} |
| 191 |
} |
203 |
} |
| 192 |
|
204 |
|
| 193 |
sub _mergeTargetFindingAlgorithm_newest { |
205 |
sub _mergeTargetFindingAlgorithm_newest { |
|
Lines 224-230
sub merge {
Link Here
|
| 224 |
my $dbh = C4::Context->dbh; |
236 |
my $dbh = C4::Context->dbh; |
| 225 |
my $sth; |
237 |
my $sth; |
| 226 |
|
238 |
|
| 227 |
# Creating a new record from the html code |
|
|
| 228 |
my $tobiblio = $mergeTarget->{biblionumber}; |
239 |
my $tobiblio = $mergeTarget->{biblionumber}; |
| 229 |
my $frombiblio = $match->{biblionumber}; |
240 |
my $frombiblio = $match->{biblionumber}; |
| 230 |
if ($tobiblio == $frombiblio) { |
241 |
if ($tobiblio == $frombiblio) { |
|
Lines 286-289
sub merge {
Link Here
|
| 286 |
push @$errors, $error if ($error); |
297 |
push @$errors, $error if ($error); |
| 287 |
} |
298 |
} |
| 288 |
} |
299 |
} |
|
|
300 |
|
| 301 |
sub printDuplicatesAsText { |
| 302 |
my ($self) = @_; |
| 303 |
|
| 304 |
foreach my $duplicate (@{$self->{duplicates}}) { |
| 305 |
print 'Match source: '.$duplicate->{biblionumber}.' - '.$duplicate->{title}.' '.$duplicate->{author}."\n"; |
| 306 |
foreach my $match (@{$duplicate->{matches}}) { |
| 307 |
print $match->{record_id}.' - '.$match->{score}.' '.$match->{itemsCount}.' '.$match->{title}.' '.$match->{author}."\n"; |
| 308 |
} |
| 309 |
print "\n\n"; |
| 310 |
} |
| 311 |
} |
| 312 |
|
| 313 |
sub printMergesAsText { |
| 314 |
my ($self) = @_; |
| 315 |
foreach my $error (@{$self->{mergeErrors}}) { |
| 316 |
print $error; |
| 317 |
} |
| 318 |
} |
| 289 |
1; |
319 |
1; |