|
Lines 16-40
Link Here
|
| 16 |
# Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place, |
16 |
# Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place, |
| 17 |
# Suite 330, Boston, MA 02111-1307 USA |
17 |
# Suite 330, Boston, MA 02111-1307 USA |
| 18 |
|
18 |
|
| 19 |
|
19 |
use Modern::Perl; |
| 20 |
use strict; |
20 |
use List::MoreUtils qw(uniq); |
| 21 |
use warnings; |
21 |
use Getopt::Long; |
|
|
22 |
use CGI; |
| 22 |
use C4::Auth; |
23 |
use C4::Auth; |
|
|
24 |
use C4::AuthoritiesMarc; # GetAuthority |
| 25 |
use C4::Biblio; # GetMarcBiblio GetXmlBiblio |
| 26 |
use C4::Branch; # GetBranches |
| 27 |
use C4::Csv; |
| 28 |
use C4::Koha; # GetItemTypes |
| 23 |
use C4::Output; |
29 |
use C4::Output; |
| 24 |
use C4::Biblio; # GetMarcBiblio GetXmlBiblio |
|
|
| 25 |
use C4::AuthoritiesMarc; # GetAuthority |
| 26 |
use CGI; |
| 27 |
use C4::Koha; # GetItemTypes |
| 28 |
use C4::Branch; # GetBranches |
| 29 |
use C4::Record; |
30 |
use C4::Record; |
| 30 |
use Getopt::Long; |
|
|
| 31 |
|
31 |
|
| 32 |
my $query = new CGI; |
32 |
my $query = new CGI; |
| 33 |
|
33 |
|
| 34 |
my $op; |
|
|
| 35 |
my $filename; |
| 36 |
my $dbh = C4::Context->dbh; |
| 37 |
my $marcflavour = C4::Context->preference("marcflavour"); |
| 38 |
my $clean; |
34 |
my $clean; |
| 39 |
my $output_format; |
35 |
my $output_format; |
| 40 |
my $dont_export_items; |
36 |
my $dont_export_items; |
|
Lines 42-47
my $deleted_barcodes;
Link Here
|
| 42 |
my $timestamp; |
38 |
my $timestamp; |
| 43 |
my $record_type; |
39 |
my $record_type; |
| 44 |
my $help; |
40 |
my $help; |
|
|
41 |
my $op = $query->param("op") || ''; |
| 42 |
my $filename = $query->param("filename") || 'koha.mrc'; |
| 43 |
my $dbh = C4::Context->dbh; |
| 44 |
my $marcflavour = C4::Context->preference("marcflavour"); |
| 45 |
my $format = $query->param("format") || 'iso2709'; |
| 45 |
|
46 |
|
| 46 |
# Checks if the script is called from commandline |
47 |
# Checks if the script is called from commandline |
| 47 |
my $commandline = not defined $ENV{GATEWAY_INTERFACE}; |
48 |
my $commandline = not defined $ENV{GATEWAY_INTERFACE}; |
|
Lines 51-64
if ( $commandline ) {
Link Here
|
| 51 |
# Getting parameters |
52 |
# Getting parameters |
| 52 |
$op = 'export'; |
53 |
$op = 'export'; |
| 53 |
GetOptions( |
54 |
GetOptions( |
| 54 |
'format=s' => \$output_format, |
55 |
'format=s' => \$output_format, |
| 55 |
'date=s' => \$timestamp, |
56 |
'date=s' => \$timestamp, |
| 56 |
'dont_export_items' => \$dont_export_items, |
57 |
'dont_export_items' => \$dont_export_items, |
| 57 |
'deleted_barcodes' => \$deleted_barcodes, |
58 |
'deleted_barcodes' => \$deleted_barcodes, |
| 58 |
'clean' => \$clean, |
59 |
'clean' => \$clean, |
| 59 |
'filename=s' => \$filename, |
60 |
'filename=s' => \$filename, |
| 60 |
'record-type=s' => \$record_type, |
61 |
'record-type=s' => \$record_type, |
| 61 |
'help|?' => \$help |
62 |
'help|?' => \$help |
| 62 |
); |
63 |
); |
| 63 |
|
64 |
|
| 64 |
if ($help) { |
65 |
if ($help) { |
|
Lines 95-407
_USAGE_
Link Here
|
| 95 |
# Redirect stdout |
96 |
# Redirect stdout |
| 96 |
open STDOUT, '>', $filename if $filename; |
97 |
open STDOUT, '>', $filename if $filename; |
| 97 |
|
98 |
|
| 98 |
} else { |
99 |
} |
|
|
100 |
else { |
| 99 |
|
101 |
|
| 100 |
$op = $query->param("op") || ''; |
102 |
$op = $query->param("op") || ''; |
| 101 |
$filename = $query->param("filename") || 'koha.mrc'; |
103 |
$filename = $query->param("filename") || 'koha.mrc'; |
| 102 |
$filename =~ s/(\r|\n)//; |
104 |
$filename =~ s/(\r|\n)//; |
| 103 |
|
105 |
|
| 104 |
} |
106 |
} |
| 105 |
|
107 |
|
| 106 |
my ($template, $loggedinuser, $cookie, $flags) = get_template_and_user( |
108 |
my ( $template, $loggedinuser, $cookie, $flags ) = get_template_and_user( |
| 107 |
{ |
109 |
{ |
| 108 |
template_name => "tools/export.tmpl", |
110 |
template_name => "tools/export.tmpl", |
| 109 |
query => $query, |
111 |
query => $query, |
| 110 |
type => "intranet", |
112 |
type => "intranet", |
| 111 |
authnotrequired => $commandline, |
113 |
authnotrequired => $commandline, |
| 112 |
flagsrequired => {tools => 'export_catalog'}, |
114 |
flagsrequired => { tools => 'export_catalog' }, |
| 113 |
debug => 1, |
115 |
debug => 1, |
| 114 |
} |
116 |
} |
| 115 |
); |
117 |
); |
| 116 |
|
118 |
|
| 117 |
my $limit_ind_branch = ( |
119 |
my $limit_ind_branch = |
| 118 |
C4::Context->preference('IndependantBranches') && |
120 |
( C4::Context->preference('IndependantBranches') |
| 119 |
C4::Context->userenv && |
121 |
&& C4::Context->userenv |
| 120 |
!(C4::Context->userenv->{flags} & 1) && |
122 |
&& !( C4::Context->userenv->{flags} & 1 ) |
| 121 |
C4::Context->userenv->{branch} |
123 |
&& C4::Context->userenv->{branch} ) ? 1 : 0; |
| 122 |
) ? 1 : 0; |
|
|
| 123 |
|
124 |
|
| 124 |
my $branch = $query->param("branch") || ''; |
125 |
my $branch = $query->param("branch") || ''; |
| 125 |
if ( C4::Context->preference("IndependantBranches") && |
126 |
if ( C4::Context->preference("IndependantBranches") |
| 126 |
C4::Context->userenv && |
127 |
&& C4::Context->userenv |
| 127 |
!(C4::Context->userenv->{flags} & 1) ) { |
128 |
&& !( C4::Context->userenv->{flags} & 1 ) ) |
|
|
129 |
{ |
| 128 |
$branch = C4::Context->userenv->{'branch'}; |
130 |
$branch = C4::Context->userenv->{'branch'}; |
| 129 |
} |
131 |
} |
| 130 |
|
132 |
|
| 131 |
my $backupdir = C4::Context->config('backupdir'); |
133 |
my $backupdir = C4::Context->config('backupdir'); |
| 132 |
|
134 |
|
| 133 |
if ($op eq "export") { |
135 |
if ( $op eq "export" ) { |
| 134 |
my $charset = 'utf-8'; |
136 |
if ( $format eq "iso2709" or $format eq "xml" ) { |
| 135 |
my $mimetype = 'application/octet-stream'; |
137 |
my $charset = 'utf-8'; |
| 136 |
binmode STDOUT, ':encoding(UTF-8)'; |
138 |
my $mimetype = 'application/octet-stream'; |
| 137 |
if ( $filename =~ m/\.gz$/ ) { |
139 |
binmode STDOUT, ':encoding(UTF-8)'; |
| 138 |
$mimetype = 'application/x-gzip'; |
140 |
if ( $filename =~ m/\.gz$/ ) { |
| 139 |
$charset = ''; |
141 |
$mimetype = 'application/x-gzip'; |
| 140 |
binmode STDOUT; |
142 |
$charset = ''; |
| 141 |
} elsif ( $filename =~ m/\.bz2$/ ) { |
143 |
binmode STDOUT; |
| 142 |
$mimetype = 'application/x-bzip2'; |
144 |
} |
| 143 |
binmode STDOUT; |
145 |
elsif ( $filename =~ m/\.bz2$/ ) { |
| 144 |
$charset = ''; |
146 |
$mimetype = 'application/x-bzip2'; |
| 145 |
} |
147 |
binmode STDOUT; |
| 146 |
print $query->header( |
148 |
$charset = ''; |
| 147 |
-type => $mimetype, |
149 |
} |
| 148 |
-charset => $charset, |
150 |
print $query->header( |
| 149 |
-attachment => $filename |
151 |
-type => $mimetype, |
| 150 |
) unless ($commandline); |
152 |
-charset => $charset, |
| 151 |
|
153 |
-attachment => $filename |
| 152 |
$record_type = $query->param("record_type") unless ($commandline); |
154 |
) unless ($commandline); |
| 153 |
$output_format = $query->param("output_format") || 'marc' unless ($commandline); |
155 |
|
| 154 |
my $dont_export_fields = $query->param("dont_export_fields"); |
156 |
$record_type = $query->param("record_type") unless ($commandline); |
| 155 |
my @sql_params; |
157 |
$output_format = $query->param("output_format") || 'marc' |
| 156 |
my $sql_query; |
158 |
unless ($commandline); |
| 157 |
|
159 |
my $dont_export_fields = $query->param("dont_export_fields"); |
| 158 |
my $StartingBiblionumber = $query->param("StartingBiblionumber"); |
160 |
my @biblionumbers = $query->param("biblionumbers"); |
| 159 |
my $EndingBiblionumber = $query->param("EndingBiblionumber"); |
161 |
my @itemnumbers = $query->param("itemnumbers"); |
| 160 |
my $itemtype = $query->param("itemtype"); |
162 |
my @sql_params; |
| 161 |
my $start_callnumber = $query->param("start_callnumber"); |
163 |
my $sql_query; |
| 162 |
my $end_callnumber = $query->param("end_callnumber"); |
164 |
my @recordids; |
| 163 |
$timestamp = ($timestamp) ? C4::Dates->new($timestamp) : '' if ($commandline); |
165 |
|
| 164 |
my $start_accession = |
166 |
my $StartingBiblionumber = $query->param("StartingBiblionumber"); |
| 165 |
( $query->param("start_accession") ) |
167 |
my $EndingBiblionumber = $query->param("EndingBiblionumber"); |
| 166 |
? C4::Dates->new( $query->param("start_accession") ) |
168 |
my $itemtype = $query->param("itemtype"); |
| 167 |
: ''; |
169 |
my $start_callnumber = $query->param("start_callnumber"); |
| 168 |
my $end_accession = |
170 |
my $end_callnumber = $query->param("end_callnumber"); |
| 169 |
( $query->param("end_accession") ) |
171 |
$timestamp = ($timestamp) ? C4::Dates->new($timestamp) : '' |
| 170 |
? C4::Dates->new( $query->param("end_accession") ) |
172 |
if ($commandline); |
| 171 |
: ''; |
173 |
my $start_accession = |
| 172 |
$dont_export_items = $query->param("dont_export_item") unless ($commandline); |
174 |
( $query->param("start_accession") ) |
| 173 |
my $strip_nonlocal_items = $query->param("strip_nonlocal_items"); |
175 |
? C4::Dates->new( $query->param("start_accession") ) |
| 174 |
|
176 |
: ''; |
| 175 |
my $biblioitemstable = ($commandline and $deleted_barcodes) |
177 |
my $end_accession = |
| 176 |
? 'deletedbiblioitems' |
178 |
( $query->param("end_accession") ) |
| 177 |
: 'biblioitems'; |
179 |
? C4::Dates->new( $query->param("end_accession") ) |
| 178 |
my $itemstable = ($commandline and $deleted_barcodes) |
180 |
: ''; |
| 179 |
? 'deleteditems' |
181 |
$dont_export_items = $query->param("dont_export_item") |
| 180 |
: 'items'; |
182 |
unless ($commandline); |
| 181 |
|
183 |
|
| 182 |
my $starting_authid = $query->param('starting_authid'); |
184 |
my $strip_nonlocal_items = $query->param("strip_nonlocal_items"); |
| 183 |
my $ending_authid = $query->param('ending_authid'); |
185 |
|
| 184 |
my $authtype = $query->param('authtype'); |
186 |
my $biblioitemstable = |
| 185 |
|
187 |
( $commandline and $deleted_barcodes ) |
| 186 |
if ( $record_type eq 'bibs' ) { |
188 |
? 'deletedbiblioitems' |
| 187 |
if ($timestamp) { |
189 |
: 'biblioitems'; |
|
|
190 |
my $itemstable = |
| 191 |
( $commandline and $deleted_barcodes ) |
| 192 |
? 'deleteditems' |
| 193 |
: 'items'; |
| 194 |
|
| 195 |
my $starting_authid = $query->param('starting_authid'); |
| 196 |
my $ending_authid = $query->param('ending_authid'); |
| 197 |
my $authtype = $query->param('authtype'); |
| 198 |
|
| 199 |
if ( $record_type eq 'bibs' and not @biblionumbers ) { |
| 200 |
if ($timestamp) { |
| 201 |
|
| 188 |
# Specific query when timestamp is used |
202 |
# Specific query when timestamp is used |
| 189 |
# Actually it's used only with CLI and so all previous filters |
203 |
# Actually it's used only with CLI and so all previous filters |
| 190 |
# are not used. |
204 |
# are not used. |
| 191 |
# If one day timestamp is used via the web interface, this part will |
205 |
# If one day timestamp is used via the web interface, this part will |
| 192 |
# certainly have to be rewrited |
206 |
# certainly have to be rewrited |
| 193 |
$sql_query = " ( |
207 |
my ( $query, $params ) = construct_query( |
| 194 |
SELECT biblionumber |
208 |
{ |
| 195 |
FROM $biblioitemstable |
209 |
recordtype => $record_type, |
| 196 |
LEFT JOIN items USING(biblionumber) |
210 |
timestamp => $timestamp, |
| 197 |
WHERE $biblioitemstable.timestamp >= ? |
211 |
biblioitemstable => $biblioitemstable, |
| 198 |
OR items.timestamp >= ? |
212 |
} |
| 199 |
) UNION ( |
213 |
); |
| 200 |
SELECT biblionumber |
214 |
$sql_query = $query; |
| 201 |
FROM $biblioitemstable |
215 |
@sql_params = @$params; |
| 202 |
LEFT JOIN deleteditems USING(biblionumber) |
|
|
| 203 |
WHERE $biblioitemstable.timestamp >= ? |
| 204 |
OR deleteditems.timestamp >= ? |
| 205 |
) "; |
| 206 |
my $ts = $timestamp->output('iso'); |
| 207 |
@sql_params = ($ts, $ts, $ts, $ts); |
| 208 |
} else { |
| 209 |
my $items_filter = |
| 210 |
$branch || $start_callnumber || $end_callnumber || |
| 211 |
$start_accession || $timestamp || $end_accession || |
| 212 |
($itemtype && C4::Context->preference('item-level_itypes')); |
| 213 |
$sql_query = $items_filter ? |
| 214 |
"SELECT DISTINCT $biblioitemstable.biblionumber |
| 215 |
FROM $biblioitemstable JOIN $itemstable |
| 216 |
USING (biblionumber) WHERE 1" |
| 217 |
: |
| 218 |
"SELECT $biblioitemstable.biblionumber FROM $biblioitemstable WHERE biblionumber >0 "; |
| 219 |
|
| 220 |
if ( $StartingBiblionumber ) { |
| 221 |
$sql_query .= " AND $biblioitemstable.biblionumber >= ? "; |
| 222 |
push @sql_params, $StartingBiblionumber; |
| 223 |
} |
| 224 |
|
| 225 |
if ( $EndingBiblionumber ) { |
| 226 |
$sql_query .= " AND $biblioitemstable.biblionumber <= ? "; |
| 227 |
push @sql_params, $EndingBiblionumber; |
| 228 |
} |
| 229 |
|
216 |
|
| 230 |
if ($branch) { |
|
|
| 231 |
$sql_query .= " AND homebranch = ? "; |
| 232 |
push @sql_params, $branch; |
| 233 |
} |
217 |
} |
| 234 |
|
218 |
else { |
| 235 |
if ($start_callnumber) { |
219 |
my ( $query, $params ) = construct_query( |
| 236 |
$sql_query .= " AND itemcallnumber <= ? "; |
220 |
{ |
| 237 |
push @sql_params, $start_callnumber; |
221 |
recordtype => $record_type, |
|
|
222 |
biblioitemstable => $biblioitemstable, |
| 223 |
itemstable => $itemstable, |
| 224 |
StartingBiblionumber => $StartingBiblionumber, |
| 225 |
EndingBiblionumber => $EndingBiblionumber, |
| 226 |
branch => $branch, |
| 227 |
start_callnumber => $start_callnumber, |
| 228 |
end_callnumber => $end_callnumber, |
| 229 |
start_accession => $start_accession, |
| 230 |
end_accession => $end_accession, |
| 231 |
itemtype => $itemtype, |
| 232 |
} |
| 233 |
); |
| 234 |
$sql_query = $query; |
| 235 |
@sql_params = @$params; |
| 238 |
} |
236 |
} |
|
|
237 |
} |
| 238 |
elsif ( $record_type eq 'auths' ) { |
| 239 |
my ( $query, $params ) = construct_query( |
| 240 |
{ |
| 241 |
recordtype => $record_type, |
| 242 |
starting_authid => $starting_authid, |
| 243 |
ending_authid => $ending_authid, |
| 244 |
authtype => $authtype, |
| 245 |
} |
| 246 |
); |
| 247 |
$sql_query = $query; |
| 248 |
@sql_params = @$params; |
| 239 |
|
249 |
|
| 240 |
if ($end_callnumber) { |
250 |
} |
| 241 |
$sql_query .= " AND itemcallnumber >= ? "; |
251 |
elsif ( $record_type eq 'db' ) { |
| 242 |
push @sql_params, $end_callnumber; |
252 |
my $successful_export; |
|
|
253 |
if ( $flags->{superlibrarian} |
| 254 |
&& C4::Context->config('backup_db_via_tools') ) |
| 255 |
{ |
| 256 |
$successful_export = download_backup( |
| 257 |
{ |
| 258 |
directory => "$backupdir", |
| 259 |
extension => 'sql', |
| 260 |
filename => "$filename" |
| 261 |
} |
| 262 |
); |
| 243 |
} |
263 |
} |
| 244 |
if ($start_accession) { |
264 |
unless ($successful_export) { |
| 245 |
$sql_query .= " AND dateaccessioned >= ? "; |
265 |
my $remotehost = $query->remote_host(); |
| 246 |
push @sql_params, $start_accession->output('iso'); |
266 |
$remotehost =~ s/(\n|\r)//; |
|
|
267 |
warn |
| 268 |
"A suspicious attempt was made to download the db at '$filename' by someone at " |
| 269 |
. $remotehost . "\n"; |
| 247 |
} |
270 |
} |
| 248 |
|
271 |
exit; |
| 249 |
if ($end_accession) { |
272 |
} |
| 250 |
$sql_query .= " AND dateaccessioned <= ? "; |
273 |
elsif ( $record_type eq 'conf' ) { |
| 251 |
push @sql_params, $end_accession->output('iso'); |
274 |
my $successful_export; |
|
|
275 |
if ( $flags->{superlibrarian} |
| 276 |
&& C4::Context->config('backup_conf_via_tools') ) |
| 277 |
{ |
| 278 |
$successful_export = download_backup( |
| 279 |
{ |
| 280 |
directory => "$backupdir", |
| 281 |
extension => 'tar', |
| 282 |
filename => "$filename" |
| 283 |
} |
| 284 |
); |
| 252 |
} |
285 |
} |
| 253 |
|
286 |
unless ($successful_export) { |
| 254 |
if ( $itemtype ) { |
287 |
my $remotehost = $query->remote_host(); |
| 255 |
$sql_query .= (C4::Context->preference('item-level_itypes')) ? " AND items.itype = ? " : " AND biblioitems.itemtype = ?"; |
288 |
$remotehost =~ s/(\n|\r)//; |
| 256 |
push @sql_params, $itemtype; |
289 |
warn |
|
|
290 |
"A suspicious attempt was made to download the configuration at '$filename' by someone at " |
| 291 |
. $remotehost . "\n"; |
| 257 |
} |
292 |
} |
|
|
293 |
exit; |
| 258 |
} |
294 |
} |
| 259 |
} |
295 |
elsif (@biblionumbers) { |
| 260 |
elsif ( $record_type eq 'auths' ) { |
296 |
push @recordids, (@biblionumbers); |
| 261 |
$sql_query = |
|
|
| 262 |
"SELECT DISTINCT auth_header.authid FROM auth_header WHERE 1"; |
| 263 |
|
| 264 |
if ($starting_authid) { |
| 265 |
$sql_query .= " AND auth_header.authid >= ? "; |
| 266 |
push @sql_params, $starting_authid; |
| 267 |
} |
297 |
} |
|
|
298 |
else { |
| 268 |
|
299 |
|
| 269 |
if ($ending_authid) { |
300 |
# Someone is trying to mess us up |
| 270 |
$sql_query .= " AND auth_header.authid <= ? "; |
301 |
exit; |
| 271 |
push @sql_params, $ending_authid; |
|
|
| 272 |
} |
302 |
} |
| 273 |
|
303 |
|
| 274 |
if ($authtype) { |
304 |
unless (@biblionumbers) { |
| 275 |
$sql_query .= " AND auth_header.authtypecode = ? "; |
305 |
my $sth = $dbh->prepare($sql_query); |
| 276 |
push @sql_params, $authtype; |
306 |
$sth->execute(@sql_params); |
| 277 |
} |
307 |
push @recordids, map { |
| 278 |
} |
308 |
map { $$_[0] } $_ |
| 279 |
elsif ( $record_type eq 'db' ) { |
309 |
} @{ $sth->fetchall_arrayref }; |
| 280 |
my $successful_export; |
|
|
| 281 |
if ( $flags->{superlibrarian} && C4::Context->config('backup_db_via_tools') ) { |
| 282 |
$successful_export = download_backup( { directory => "$backupdir", extension => 'sql', filename => "$filename" } ) |
| 283 |
} |
| 284 |
unless ( $successful_export ) { |
| 285 |
my $remotehost = $query->remote_host(); |
| 286 |
$remotehost =~ s/(\n|\r)//; |
| 287 |
warn "A suspicious attempt was made to download the db at '$filename' by someone at " . $remotehost . "\n"; |
| 288 |
} |
| 289 |
exit; |
| 290 |
} |
| 291 |
elsif ( $record_type eq 'conf' ) { |
| 292 |
my $successful_export; |
| 293 |
if ( $flags->{superlibrarian} && C4::Context->config('backup_conf_via_tools') ) { |
| 294 |
$successful_export = download_backup( { directory => "$backupdir", extension => 'tar', filename => "$filename" } ) |
| 295 |
} |
| 296 |
unless ( $successful_export ) { |
| 297 |
my $remotehost = $query->remote_host(); |
| 298 |
$remotehost =~ s/(\n|\r)//; |
| 299 |
warn "A suspicious attempt was made to download the configuration at '$filename' by someone at " . $remotehost . "\n"; |
| 300 |
} |
310 |
} |
| 301 |
exit; |
|
|
| 302 |
} |
| 303 |
else { |
| 304 |
# Someone is trying to mess us up |
| 305 |
exit; |
| 306 |
} |
| 307 |
|
| 308 |
my $sth = $dbh->prepare($sql_query); |
| 309 |
$sth->execute(@sql_params); |
| 310 |
|
| 311 |
while ( my ($recordid) = $sth->fetchrow ) { |
| 312 |
if ( $deleted_barcodes ) { |
| 313 |
my $q = " |
| 314 |
SELECT DISTINCT barcode |
| 315 |
FROM deleteditems |
| 316 |
WHERE deleteditems.biblionumber = ? |
| 317 |
"; |
| 318 |
my $sth = $dbh->prepare($q); |
| 319 |
$sth->execute($recordid); |
| 320 |
while (my $row = $sth->fetchrow_array) { |
| 321 |
print "$row\n"; |
| 322 |
} |
| 323 |
} else { |
| 324 |
my $record; |
| 325 |
if ( $record_type eq 'bibs' ) { |
| 326 |
$record = eval { GetMarcBiblio($recordid); }; |
| 327 |
|
311 |
|
| 328 |
if ($@) { |
312 |
for my $recordid ( uniq @recordids ) { |
| 329 |
next; |
313 |
if ($deleted_barcodes) { |
|
|
314 |
my $q = " |
| 315 |
SELECT DISTINCT barcode |
| 316 |
FROM deleteditems |
| 317 |
WHERE deleteditems.biblionumber = ? |
| 318 |
"; |
| 319 |
my $sth = $dbh->prepare($q); |
| 320 |
$sth->execute($recordid); |
| 321 |
while ( my $row = $sth->fetchrow_array ) { |
| 322 |
print "$row\n"; |
| 330 |
} |
323 |
} |
| 331 |
next if not defined $record; |
324 |
} |
| 332 |
C4::Biblio::EmbedItemsInMarcBiblio( $record, $recordid ) |
325 |
else { |
| 333 |
unless $dont_export_items; |
326 |
my $record; |
| 334 |
if ( $strip_nonlocal_items || $limit_ind_branch ) { |
327 |
if ( $record_type eq 'bibs' ) { |
| 335 |
my ( $homebranchfield, $homebranchsubfield ) = |
328 |
$record = eval { GetMarcBiblio($recordid); }; |
| 336 |
GetMarcFromKohaField( 'items.homebranch', '' ); |
329 |
|
| 337 |
for my $itemfield ( $record->field($homebranchfield) ) { |
330 |
next if $@; |
| 338 |
|
331 |
next if not defined $record; |
| 339 |
# if stripping nonlocal items, use loggedinuser's branch if they didn't select one |
332 |
C4::Biblio::EmbedItemsInMarcBiblio( $record, $recordid, |
| 340 |
$branch = C4::Context->userenv->{'branch'} unless $branch; |
333 |
\@itemnumbers ) |
| 341 |
$record->delete_field($itemfield) |
334 |
unless $dont_export_items; |
| 342 |
if ( |
335 |
if ( $strip_nonlocal_items |
| 343 |
$itemfield->subfield($homebranchsubfield) ne $branch ); |
336 |
|| $limit_ind_branch |
|
|
337 |
|| $dont_export_items ) |
| 338 |
{ |
| 339 |
my ( $homebranchfield, $homebranchsubfield ) = |
| 340 |
GetMarcFromKohaField( 'items.homebranch', '' ); |
| 341 |
for my $itemfield ( $record->field($homebranchfield) ) { |
| 342 |
|
| 343 |
# if stripping nonlocal items, use loggedinuser's branch if they didn't select one |
| 344 |
$branch = C4::Context->userenv->{'branch'} |
| 345 |
unless $branch; |
| 346 |
$record->delete_field($itemfield) |
| 347 |
if ( $dont_export_items |
| 348 |
|| $itemfield->subfield($homebranchsubfield) ne |
| 349 |
$branch ); |
| 350 |
} |
| 344 |
} |
351 |
} |
| 345 |
} |
352 |
} |
| 346 |
} |
353 |
elsif ( $record_type eq 'auths' ) { |
| 347 |
elsif ( $record_type eq 'auths' ) { |
354 |
$record = C4::AuthoritiesMarc::GetAuthority($recordid); |
| 348 |
$record = C4::AuthoritiesMarc::GetAuthority($recordid); |
355 |
next if not defined $record; |
| 349 |
next if not defined $record; |
356 |
} |
| 350 |
} |
|
|
| 351 |
|
357 |
|
| 352 |
if ( $dont_export_fields ) { |
358 |
if ($dont_export_fields) { |
| 353 |
my @fields = split " ", $dont_export_fields; |
359 |
my @fields = split " ", $dont_export_fields; |
| 354 |
foreach ( @fields ) { |
360 |
foreach (@fields) { |
| 355 |
/^(\d*)(\w)?$/; |
361 |
/^(\d*)(\w)?$/; |
| 356 |
my $field = $1; |
362 |
my $field = $1; |
| 357 |
my $subfield = $2; |
363 |
my $subfield = $2; |
| 358 |
# skip if this record doesn't have this field |
364 |
|
| 359 |
next if not defined $record->field($field); |
365 |
# skip if this record doesn't have this field |
| 360 |
if( $subfield ) { |
366 |
next if not defined $record->field($field); |
| 361 |
$record->field($field)->delete_subfields($subfield); |
367 |
if ($subfield) { |
|
|
368 |
$record->field($field)->delete_subfields($subfield); |
| 369 |
} |
| 370 |
else { |
| 371 |
$record->delete_field( $record->field($field) ); |
| 372 |
} |
| 373 |
} |
| 374 |
} |
| 375 |
RemoveAllNsb($record) if ($clean); |
| 376 |
if ( $output_format eq "xml" ) { |
| 377 |
if ( $marcflavour eq 'UNIMARC' && $record_type eq 'auths' ) |
| 378 |
{ |
| 379 |
print $record->as_xml_record('UNIMARCAUTH'); |
| 362 |
} |
380 |
} |
| 363 |
else { |
381 |
else { |
| 364 |
$record->delete_field($record->field($field)); |
382 |
print $record->as_xml_record($marcflavour); |
| 365 |
} |
383 |
} |
| 366 |
} |
384 |
} |
| 367 |
} |
385 |
else { |
| 368 |
RemoveAllNsb($record) if ($clean); |
386 |
print $record->as_usmarc(); |
| 369 |
if ( $output_format eq "xml" ) { |
|
|
| 370 |
if ($marcflavour eq 'UNIMARC' && $record_type eq 'auths') { |
| 371 |
print $record->as_xml_record('UNIMARCAUTH'); |
| 372 |
} else { |
| 373 |
print $record->as_xml_record($marcflavour); |
| 374 |
} |
387 |
} |
| 375 |
} |
388 |
} |
| 376 |
else { |
|
|
| 377 |
print $record->as_usmarc(); |
| 378 |
} |
| 379 |
} |
389 |
} |
|
|
390 |
exit; |
| 391 |
} |
| 392 |
elsif ( $format eq "csv" ) { |
| 393 |
my @biblionumbers = uniq $query->param("biblionumbers"); |
| 394 |
my @itemnumbers = $query->param("itemnumbers"); |
| 395 |
my $output = |
| 396 |
marc2csv( \@biblionumbers, |
| 397 |
GetCsvProfileId( C4::Context->preference('CsvProfileForExport') ), |
| 398 |
\@itemnumbers, ); |
| 399 |
print $query->header( |
| 400 |
-type => 'application/octet-stream', |
| 401 |
-'Content-Transfer-Encoding' => 'binary', |
| 402 |
-attachment => "export.csv" |
| 403 |
); |
| 404 |
print $output; |
| 405 |
exit; |
| 380 |
} |
406 |
} |
| 381 |
exit; |
|
|
| 382 |
|
| 383 |
} # if export |
407 |
} # if export |
| 384 |
|
408 |
|
| 385 |
else { |
409 |
else { |
| 386 |
|
410 |
|
| 387 |
my $itemtypes = GetItemTypes; |
411 |
my $itemtypes = GetItemTypes; |
| 388 |
my @itemtypesloop; |
412 |
my @itemtypesloop; |
| 389 |
foreach my $thisitemtype (sort keys %$itemtypes) { |
413 |
foreach my $thisitemtype ( sort keys %$itemtypes ) { |
| 390 |
my %row = |
414 |
my %row = ( |
| 391 |
( |
415 |
value => $thisitemtype, |
| 392 |
value => $thisitemtype, |
416 |
description => $itemtypes->{$thisitemtype}->{'description'}, |
| 393 |
description => $itemtypes->{$thisitemtype}->{'description'}, |
417 |
); |
| 394 |
); |
418 |
push @itemtypesloop, \%row; |
| 395 |
push @itemtypesloop, \%row; |
|
|
| 396 |
} |
419 |
} |
| 397 |
my $branches = GetBranches($limit_ind_branch); |
420 |
my $branches = GetBranches($limit_ind_branch); |
| 398 |
my @branchloop; |
421 |
my @branchloop; |
| 399 |
for my $thisbranch ( |
422 |
for my $thisbranch ( |
| 400 |
sort { $branches->{$a}->{branchname} cmp $branches->{$b}->{branchname} } |
423 |
sort { $branches->{$a}->{branchname} cmp $branches->{$b}->{branchname} } |
| 401 |
keys %{$branches} |
424 |
keys %{$branches} |
| 402 |
) { |
425 |
) |
|
|
426 |
{ |
| 403 |
push @branchloop, |
427 |
push @branchloop, |
| 404 |
{ value => $thisbranch, |
428 |
{ |
|
|
429 |
value => $thisbranch, |
| 405 |
selected => $thisbranch eq $branch, |
430 |
selected => $thisbranch eq $branch, |
| 406 |
branchname => $branches->{$thisbranch}->{'branchname'}, |
431 |
branchname => $branches->{$thisbranch}->{'branchname'}, |
| 407 |
}; |
432 |
}; |
|
Lines 418-431
else {
Link Here
|
| 418 |
push @authtypesloop, \%row; |
443 |
push @authtypesloop, \%row; |
| 419 |
} |
444 |
} |
| 420 |
|
445 |
|
| 421 |
if ( $flags->{superlibrarian} && C4::Context->config('backup_db_via_tools') && $backupdir && -d $backupdir ) { |
446 |
if ( $flags->{superlibrarian} |
|
|
447 |
&& C4::Context->config('backup_db_via_tools') |
| 448 |
&& $backupdir |
| 449 |
&& -d $backupdir ) |
| 450 |
{ |
| 422 |
$template->{VARS}->{'allow_db_export'} = 1; |
451 |
$template->{VARS}->{'allow_db_export'} = 1; |
| 423 |
$template->{VARS}->{'dbfiles'} = getbackupfilelist( { directory => "$backupdir", extension => 'sql' } ); |
452 |
$template->{VARS}->{'dbfiles'} = getbackupfilelist( |
|
|
453 |
{ directory => "$backupdir", extension => 'sql' } ); |
| 424 |
} |
454 |
} |
| 425 |
|
455 |
|
| 426 |
if ( $flags->{superlibrarian} && C4::Context->config('backup_conf_via_tools') && $backupdir && -d $backupdir ) { |
456 |
if ( $flags->{superlibrarian} |
|
|
457 |
&& C4::Context->config('backup_conf_via_tools') |
| 458 |
&& $backupdir |
| 459 |
&& -d $backupdir ) |
| 460 |
{ |
| 427 |
$template->{VARS}->{'allow_conf_export'} = 1; |
461 |
$template->{VARS}->{'allow_conf_export'} = 1; |
| 428 |
$template->{VARS}->{'conffiles'} = getbackupfilelist( { directory => "$backupdir", extension => 'tar' } ); |
462 |
$template->{VARS}->{'conffiles'} = getbackupfilelist( |
|
|
463 |
{ directory => "$backupdir", extension => 'tar' } ); |
| 429 |
} |
464 |
} |
| 430 |
|
465 |
|
| 431 |
$template->param( |
466 |
$template->param( |
|
Lines 439-454
else {
Link Here
|
| 439 |
output_html_with_http_headers $query, $cookie, $template->output; |
474 |
output_html_with_http_headers $query, $cookie, $template->output; |
| 440 |
} |
475 |
} |
| 441 |
|
476 |
|
|
|
477 |
sub construct_query { |
| 478 |
my ($params) = @_; |
| 479 |
|
| 480 |
my ( $sql_query, @sql_params ); |
| 481 |
|
| 482 |
if ( $params->{recordtype} eq "bibs" ) { |
| 483 |
if ( $params->{timestamp} ) { |
| 484 |
my $biblioitemstable = $params->{biblioitemstable}; |
| 485 |
$sql_query = " ( |
| 486 |
SELECT biblionumber |
| 487 |
FROM $biblioitemstable |
| 488 |
LEFT JOIN items USING(biblionumber) |
| 489 |
WHERE $biblioitemstable.timestamp >= ? |
| 490 |
OR items.timestamp >= ? |
| 491 |
) UNION ( |
| 492 |
SELECT biblionumber |
| 493 |
FROM $biblioitemstable |
| 494 |
LEFT JOIN deleteditems USING(biblionumber) |
| 495 |
WHERE $biblioitemstable.timestamp >= ? |
| 496 |
OR deleteditems.timestamp >= ? |
| 497 |
) "; |
| 498 |
my $ts = $timestamp->output('iso'); |
| 499 |
@sql_params = ( $ts, $ts, $ts, $ts ); |
| 500 |
} |
| 501 |
else { |
| 502 |
my $biblioitemstable = $params->{biblioitemstable}; |
| 503 |
my $itemstable = $params->{itemstable}; |
| 504 |
my $StartingBiblionumber = $params->{StartingBiblionumber}; |
| 505 |
my $EndingBiblionumber = $params->{EndingBiblionumber}; |
| 506 |
my $branch = $params->{branch}; |
| 507 |
my $start_callnumber = $params->{start_callnumber}; |
| 508 |
my $end_callnumber = $params->{end_callnumber}; |
| 509 |
my $start_accession = $params->{star_accession}; |
| 510 |
my $end_accession = $params->{end_accession}; |
| 511 |
my $itemtype = $params->{itemtype}; |
| 512 |
my $items_filter = |
| 513 |
$branch |
| 514 |
|| $start_callnumber |
| 515 |
|| $end_callnumber |
| 516 |
|| $start_accession |
| 517 |
|| $end_accession |
| 518 |
|| ( $itemtype && C4::Context->preference('item-level_itypes') ); |
| 519 |
$sql_query = $items_filter |
| 520 |
? "SELECT DISTINCT $biblioitemstable.biblionumber |
| 521 |
FROM $biblioitemstable JOIN $itemstable |
| 522 |
USING (biblionumber) WHERE 1" |
| 523 |
: "SELECT $biblioitemstable.biblionumber FROM $biblioitemstable WHERE biblionumber >0 "; |
| 524 |
|
| 525 |
if ($StartingBiblionumber) { |
| 526 |
$sql_query .= " AND $biblioitemstable.biblionumber >= ? "; |
| 527 |
push @sql_params, $StartingBiblionumber; |
| 528 |
} |
| 529 |
|
| 530 |
if ($EndingBiblionumber) { |
| 531 |
$sql_query .= " AND $biblioitemstable.biblionumber <= ? "; |
| 532 |
push @sql_params, $EndingBiblionumber; |
| 533 |
} |
| 534 |
|
| 535 |
if ($branch) { |
| 536 |
$sql_query .= " AND homebranch = ? "; |
| 537 |
push @sql_params, $branch; |
| 538 |
} |
| 539 |
|
| 540 |
if ($start_callnumber) { |
| 541 |
$sql_query .= " AND itemcallnumber <= ? "; |
| 542 |
push @sql_params, $start_callnumber; |
| 543 |
} |
| 544 |
|
| 545 |
if ($end_callnumber) { |
| 546 |
$sql_query .= " AND itemcallnumber >= ? "; |
| 547 |
push @sql_params, $end_callnumber; |
| 548 |
} |
| 549 |
if ($start_accession) { |
| 550 |
$sql_query .= " AND dateaccessioned >= ? "; |
| 551 |
push @sql_params, $start_accession->output('iso'); |
| 552 |
} |
| 553 |
|
| 554 |
if ($end_accession) { |
| 555 |
$sql_query .= " AND dateaccessioned <= ? "; |
| 556 |
push @sql_params, $end_accession->output('iso'); |
| 557 |
} |
| 558 |
|
| 559 |
if ($itemtype) { |
| 560 |
$sql_query .= |
| 561 |
( C4::Context->preference('item-level_itypes') ) |
| 562 |
? " AND items.itype = ? " |
| 563 |
: " AND biblioitems.itemtype = ?"; |
| 564 |
push @sql_params, $itemtype; |
| 565 |
} |
| 566 |
} |
| 567 |
} |
| 568 |
elsif ( $params->{recordtype} eq "auths" ) { |
| 569 |
if ( $params->{timestamp} ) { |
| 570 |
|
| 571 |
#TODO |
| 572 |
} |
| 573 |
else { |
| 574 |
my $starting_authid = $params->{starting_authid}; |
| 575 |
my $ending_authid = $params->{ending_authid}; |
| 576 |
my $authtype = $params->{authtype}; |
| 577 |
$sql_query = |
| 578 |
"SELECT DISTINCT auth_header.authid FROM auth_header WHERE 1"; |
| 579 |
|
| 580 |
if ($starting_authid) { |
| 581 |
$sql_query .= " AND auth_header.authid >= ? "; |
| 582 |
push @sql_params, $starting_authid; |
| 583 |
} |
| 584 |
|
| 585 |
if ($ending_authid) { |
| 586 |
$sql_query .= " AND auth_header.authid <= ? "; |
| 587 |
push @sql_params, $ending_authid; |
| 588 |
} |
| 589 |
|
| 590 |
if ($authtype) { |
| 591 |
$sql_query .= " AND auth_header.authtypecode = ? "; |
| 592 |
push @sql_params, $authtype; |
| 593 |
} |
| 594 |
} |
| 595 |
} |
| 596 |
return ( $sql_query, \@sql_params ); |
| 597 |
} |
| 598 |
|
| 442 |
sub getbackupfilelist { |
599 |
sub getbackupfilelist { |
| 443 |
my $args = shift; |
600 |
my $args = shift; |
| 444 |
my $directory = $args->{directory}; |
601 |
my $directory = $args->{directory}; |
| 445 |
my $extension = $args->{extension}; |
602 |
my $extension = $args->{extension}; |
| 446 |
my @files; |
603 |
my @files; |
| 447 |
|
604 |
|
| 448 |
if ( opendir(my $dir, $directory) ) { |
605 |
if ( opendir( my $dir, $directory ) ) { |
| 449 |
while (my $file = readdir($dir)) { |
606 |
while ( my $file = readdir($dir) ) { |
| 450 |
next unless ( $file =~ m/\.$extension(\.(gz|bz2|xz))?/ ); |
607 |
next unless ( $file =~ m/\.$extension(\.(gz|bz2|xz))?/ ); |
| 451 |
push @files, $file if ( -f "$directory/$file" && -r "$directory/$file" ); |
608 |
push @files, $file |
|
|
609 |
if ( -f "$directory/$file" && -r "$directory/$file" ); |
| 452 |
} |
610 |
} |
| 453 |
closedir($dir); |
611 |
closedir($dir); |
| 454 |
} |
612 |
} |
|
Lines 456-475
sub getbackupfilelist {
Link Here
|
| 456 |
} |
614 |
} |
| 457 |
|
615 |
|
| 458 |
sub download_backup { |
616 |
sub download_backup { |
| 459 |
my $args = shift; |
617 |
my $args = shift; |
| 460 |
my $directory = $args->{directory}; |
618 |
my $directory = $args->{directory}; |
| 461 |
my $extension = $args->{extension}; |
619 |
my $extension = $args->{extension}; |
| 462 |
my $filename = $args->{filename}; |
620 |
my $filename = $args->{filename}; |
| 463 |
|
621 |
|
| 464 |
return unless ( $directory && -d $directory ); |
622 |
return unless ( $directory && -d $directory ); |
| 465 |
return unless ( $filename =~ m/$extension(\.(gz|bz2|xz))?$/ && not $filename =~ m#|# ); |
623 |
return |
|
|
624 |
unless ( $filename =~ m/$extension(\.(gz|bz2|xz))?$/ |
| 625 |
&& not $filename =~ m#|# ); |
| 466 |
$filename = "$directory/$filename"; |
626 |
$filename = "$directory/$filename"; |
| 467 |
return unless ( -f $filename && -r $filename ); |
627 |
return unless ( -f $filename && -r $filename ); |
| 468 |
return unless ( open(my $dump, '<', $filename) ); |
628 |
return unless ( open( my $dump, '<', $filename ) ); |
| 469 |
binmode $dump; |
629 |
binmode $dump; |
| 470 |
while (read($dump, my $data, 64 * 1024)) { |
630 |
|
|
|
631 |
while ( read( $dump, my $data, 64 * 1024 ) ) { |
| 471 |
print $data; |
632 |
print $data; |
| 472 |
} |
633 |
} |
| 473 |
close ($dump); |
634 |
close($dump); |
| 474 |
return 1; |
635 |
return 1; |
| 475 |
} |
636 |
} |
| 476 |
- |
|
|