Projekt

Allgemein

Profil

Herunterladen (4,54 KB) Statistiken
| Zweig: | Markierung: | Revision:
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

(27-27/30)