|
Lines 20-27
package Koha::ArticleRequests;
Link Here
|
| 20 |
use Modern::Perl; |
20 |
use Modern::Perl; |
| 21 |
|
21 |
|
| 22 |
use Carp; |
22 |
use Carp; |
|
|
23 |
use Data::Dumper qw/Dumper/; |
| 23 |
|
24 |
|
| 24 |
use Koha::Database; |
25 |
use Koha::Database; |
|
|
26 |
use Koha::DateUtils qw/dt_from_string/; |
| 25 |
|
27 |
|
| 26 |
use Koha::ArticleRequest; |
28 |
use Koha::ArticleRequest; |
| 27 |
use Koha::ArticleRequest::Status; |
29 |
use Koha::ArticleRequest::Status; |
|
Lines 82-87
sub canceled {
Link Here
|
| 82 |
return Koha::ArticleRequests->search( $params ); |
84 |
return Koha::ArticleRequests->search( $params ); |
| 83 |
} |
85 |
} |
| 84 |
|
86 |
|
|
|
87 |
=head3 match_scans |
| 88 |
|
| 89 |
$class->match_scans({ uploadcategory => 'SCANS' }); |
| 90 |
|
| 91 |
Match all requests in processing stage with uploaded files in the |
| 92 |
specified category submitted later than the first request was set |
| 93 |
to processing. Save upload URL in the requests and mark complete. |
| 94 |
|
| 95 |
Groups of uploaded files submitted within the same interval as described |
| 96 |
by the optional interval parameter (default 10) are considered as |
| 97 |
batches to be sorted on filename. Disable this behavior by passing -1. |
| 98 |
In that case the strict upload order is followed. |
| 99 |
|
| 100 |
=cut |
| 101 |
|
| 102 |
sub match_scans { |
| 103 |
my ( $class, $params ) = @_; |
| 104 |
my $category = $params->{uploadcategory}; |
| 105 |
my $interval = $params->{interval} // 10; # minutes |
| 106 |
|
| 107 |
my $requests = $class->search_scans_in_process->as_list; |
| 108 |
return if !@$requests; # no requests to match |
| 109 |
|
| 110 |
# Find time to start looking for uploads |
| 111 |
my $first_processed = $requests->[0]->updated_on; |
| 112 |
|
| 113 |
#FIXME Replace with Koha::UploadedFiles |
| 114 |
# Public should be true, since we will create OPAC URLs |
| 115 |
my $uploads = C4::Context->dbh->selectall_arrayref("SELECT filename,hashvalue,dtcreated FROM uploaded_files WHERE uploadcategorycode=? AND dtcreated>? AND public=1 ORDER BY id", undef, ( $category, $first_processed )); |
| 116 |
return if !@$uploads; |
| 117 |
|
| 118 |
# Split uploads in batches (based on interval). We can assume that the |
| 119 |
# uploads have ascending timestamps. |
| 120 |
my @batches; |
| 121 |
my $n = 0; |
| 122 |
my $dt_last; |
| 123 |
foreach my $u (@$uploads) { |
| 124 |
my $dt = dt_from_string( $u->[2], 'sql' ); |
| 125 |
if( !defined $dt_last ) { |
| 126 |
$dt_last = $dt; |
| 127 |
} elsif( $dt_last->delta_ms( $dt )->in_units('minutes') > $interval ) { |
| 128 |
# delta_ms returns non-negative values only |
| 129 |
$dt_last = $dt; |
| 130 |
push @batches, $n; |
| 131 |
$n = 0; |
| 132 |
} |
| 133 |
$n++; |
| 134 |
} |
| 135 |
push @batches, $n if $n; |
| 136 |
|
| 137 |
# Rearrange order of uploads within a batch on filename |
| 138 |
# This is done since the order of multiple selected files in the file |
| 139 |
# upload control is not reliable (often in reverse). |
| 140 |
my $pos = 0; |
| 141 |
foreach my $s (@batches) { |
| 142 |
@$uploads[$pos..$pos+$s-1] = sort { lc($a->[0]) cmp lc($b->[0]) } @$uploads[$pos..$pos+$s-1] if $s > 1; |
| 143 |
$pos += $s; |
| 144 |
} |
| 145 |
|
| 146 |
# Match while we have uploads or requests |
| 147 |
my $result = {}; |
| 148 |
while( @$uploads && @$requests ) { |
| 149 |
my $upload = shift @$uploads; |
| 150 |
my $req = shift @$requests; |
| 151 |
my $url = C4::Context->preference('OPACBaseURL').'/cgi-bin/koha/opac-retrieve-file.pl?id='.$upload->[1]; |
| 152 |
$req->urls($url)->store; |
| 153 |
$req->complete; |
| 154 |
} |
| 155 |
} |
| 156 |
|
| 157 |
=head3 search_scans_in_process |
| 158 |
|
| 159 |
$class->search_scans_in_process({ list => 1 }); |
| 160 |
|
| 161 |
Search for article requests with status in processing, format SCAN |
| 162 |
and empty urls field. Order by last change. |
| 163 |
|
| 164 |
The optional list parameter (used in opac/svc/scan_requests) makes |
| 165 |
that an arrayref of request id's is returned. |
| 166 |
Without it, a Koha::Objects search is returned (used by match_scans). |
| 167 |
|
| 168 |
=cut |
| 169 |
|
| 170 |
sub search_scans_in_process { |
| 171 |
my ( $class, $params ) = @_; |
| 172 |
my $req_in_process = $class->search( |
| 173 |
{ status => 'PROCESSING', format => 'SCAN', urls => [ '', undef ] }, |
| 174 |
{ order_by => 'updated_on' }, |
| 175 |
); |
| 176 |
if( $params->{list} ) { |
| 177 |
return [ map { $_->id } $req_in_process->as_list ]; |
| 178 |
} |
| 179 |
return $req_in_process; |
| 180 |
} |
| 181 |
|
| 182 |
=head3 complete_scans |
| 183 |
|
| 184 |
Save URLs in scan requests and mark them as completed. |
| 185 |
|
| 186 |
The $scans parameter is a hashref of the form { request_id => url, ... } |
| 187 |
|
| 188 |
Returns the number of completed scan requests. |
| 189 |
|
| 190 |
Note: The routine is called by opac/svc/scan_requests?op=complete when |
| 191 |
you pass the results of external matching (as opposed to match_scans) |
| 192 |
back to Koha. This allows for customization with external web services. |
| 193 |
|
| 194 |
=cut |
| 195 |
|
| 196 |
sub complete_scans { |
| 197 |
my ( $class, $scans ) = @_; |
| 198 |
my $n = 0; |
| 199 |
foreach my $id ( keys %$scans ) { |
| 200 |
my $req = Koha::ArticleRequests->find( $id ); |
| 201 |
if( $req ) { |
| 202 |
$req->urls( $scans->{$id} )->store; |
| 203 |
$req->complete; |
| 204 |
$n++; |
| 205 |
} |
| 206 |
} |
| 207 |
return $n; |
| 208 |
} |
| 209 |
|
| 85 |
=head3 _type |
210 |
=head3 _type |
| 86 |
|
211 |
|
| 87 |
=cut |
212 |
=cut |