kivitendo/SL/BackgroundJob/SyncWebDAV.pm @ 445d1d8b
cd303dbe | Jan Büren | package SL::BackgroundJob::SyncWebDAV;
|
|
use strict;
|
|||
use warnings;
|
|||
use parent qw(SL::BackgroundJob::Base);
|
|||
use SL::DB::BackgroundJobHistory;
|
|||
use HTTP::DAV;
|
|||
use File::Find;
|
|||
use Cwd;
|
|||
use Data::Dumper;
|
|||
sub create_job {
|
|||
$_[0]->create_standard_job('0 3 * * *'); # daily at 3:00 am
|
|||
}
|
|||
sub run {
|
|||
my $self = shift;
|
|||
my $db_obj = shift;
|
|||
my $options = $db_obj->data_as_hash;
|
|||
my $DELETE_ONLY = 0 || $options->{delete};
|
|||
return unless $::instance_conf->get_webdav_sync_extern;
|
|||
my $ret;
|
|||
my $dav = HTTP::DAV->new();
|
|||
my $url = $::instance_conf->get_webdav_sync_extern_url;
|
|||
$url =~ s|/\z||; # no trailing slashes
|
|||
$dav->credentials(
|
|||
-user => $::instance_conf->get_webdav_sync_extern_login,
|
|||
-pass => $::instance_conf->get_webdav_sync_extern_pass,
|
|||
-url => $url,
|
|||
);
|
|||
my $client_id = $options->{client_id} || $::auth->get_session_value('client_id');
|
|||
my $cwd = getcwd();
|
|||
my @fails;
|
|||
eval {
|
|||
my (@webdav_dir_temp, @webdav_dir, @webdav_files);
|
|||
# chdir to client root
|
|||
my $webdav = $cwd. "/webdav/$client_id/";
|
|||
chdir($webdav) or die "couldn't change into webdav dir"; # TODO throw better error message (Permission denied, etc)
|
|||
find( { wanted => sub { push @webdav_dir_temp, -d && $_}, no_chdir => 1 }, '.');
|
|||
find( { wanted => sub { push @webdav_files, -f && $_}, no_chdir => 1 }, '.');
|
|||
shift @webdav_dir_temp; # first element would be undef after substr
|
|||
foreach (@webdav_dir_temp) {
|
|||
next unless $_;
|
|||
push @webdav_dir, substr($_,2);
|
|||
}
|
|||
@webdav_files = map { substr($_,2) } grep { $_ =~ m/.*pdf/ } @webdav_files;
|
|||
$ret = $dav->open(-url => $url) or die "Can't open url $url";
|
|||
# Make a null lock on repo for 5minutes
|
|||
#$ret = $dav->lock(-url => $url, -timeout => "30m") or die;
|
|||
foreach (@webdav_dir) {
|
|||
last if $DELETE_ONLY;
|
|||
$ret = $dav->options(-url => $url . '/' . $_);
|
|||
next unless $ret =~ m/MKCOL/;
|
|||
unless ( $dav->mkcol($_) ) {
|
|||
push(@fails, "Cannot make dir $_");
|
|||
};
|
|||
}
|
|||
#$dav->unlock(-url => $url); # UNLOCK after DIR sync
|
|||
# now we have all dirs in sync, therefore we can place files
|
|||
foreach (@webdav_files) {
|
|||
last if $DELETE_ONLY;
|
|||
$ret = $dav->options(-url => $url . '/' . $_);
|
|||
# $main::lxdebug->message(0, 'verzeichnis:'. $_ . '::' . $ret . ':' . $dav->message);
|
|||
next unless $ret =~ m/MKCOL/; # file not there #owncloud gives DELETE even if file not there
|
|||
#$dav->lock(-url => $url . '/' . $_); # UNLOCK after DIR sync
|
|||
# $main::lxdebug->message(0, 'datei:'. $_);
|
|||
unless ( $dav->put(-local => $_, -url => $url . '/' . $_) ) {
|
|||
push(@fails, "Cannot put file $_");
|
|||
};
|
|||
#$dav->unlock(-url => $url . '/' . $_); # UNLOCK after put
|
|||
}
|
|||
# maybe we delete some stuff
|
|||
# TODO delete stuff here
|
|||
if ($DELETE_ONLY) {
|
|||
foreach (qw(anfragen bestellungen einkaufslieferscheine einkaufsrechnungen angebote
|
|||
gutschriften lieferantenbestellungen rechnungen verkaufslieferscheine)) {
|
|||
$ret = $dav->delete($url . "/$_");
|
|||
}
|
|||
# better, but not implemented - delete only local deleted stuff
|
|||
# idea: propfind all the above dirs and check if child (rel_uri) exists locally
|
|||
# if not, we can safely delete remote
|
|||
# if (my $r=$dav->propfind( -url=>"$_/", -depth=>1) ) { ...
|
|||
}
|
|||
#$dav->unlock(-url => $url);
|
|||
chdir($cwd);
|
|||
1;
|
|||
} or do {
|
|||
my $error = "dav: " . $dav->message . ", eval: " . $! . ", eval 2: " . $@;
|
|||
# $dav->unlock(-url => $url); # unlock, just in case
|
|||
# chdir($cwd);
|
|||
die("Couldn't sync with external webdav repo at $url error code/protocol return:" . $error);
|
|||
};
|
|||
if ( @fails ) {
|
|||
die join("\n", @fails);
|
|||
};
|
|||
return 1;
|
|||
}
|
|||
1;
|
|||
__END__
|
|||
=encoding utf8
|
|||
=head1 NAME
|
|||
SL::BackgroundJob::ExternalSyncWebDAV - Background job for
|
|||
syncing all folders and files for current client to a external
|
|||
webdav-repository
|
|||
=head1 SYNOPSIS
|
|||
This background job copies all files and folders for one client
|
|||
to a external webdav-repo.
|
|||
A optional param C<delete> can be set to 1 to delete (clean)
|
|||
the external repo. If set to undef or 0 a folderwise copy will be
|
|||
executed.
|
|||
To test with different clients a param C<client_id> will overload
|
|||
the current client id.
|
|||
The settings for the external repo are in client config.
|
|||
If a lock still exists, the job returns a Internal Server Error
|
|||
from the webdav server.
|
|||
Only pdf files are considered valid files to copy.
|
|||
The job is supposed to run once a day.
|
|||
=head1 BUGS
|
|||
Nothing here yet.
|
|||
=head1 AUTHOR
|
|||
Jan Büren E<lt>jan@kivitendo-premium.deE<gt>
|
|||
=cut
|