1 package SL::BackgroundJob::SyncWebDAV;
6 use parent qw(SL::BackgroundJob::Base);
8 use SL::DB::BackgroundJobHistory;
15 $_[0]->create_standard_job('0 3 * * *'); # daily at 3:00 am
22 my $options = $db_obj->data_as_hash;
23 my $DELETE_ONLY = 0 || $options->{delete};
25 return unless $::instance_conf->get_webdav_sync_extern;
29 my $dav = HTTP::DAV->new();
30 my $url = $::instance_conf->get_webdav_sync_extern_url;
31 $url =~ s|/\z||; # no trailing slashes
34 -user => $::instance_conf->get_webdav_sync_extern_login,
35 -pass => $::instance_conf->get_webdav_sync_extern_pass,
38 my $client_id = $options->{client_id} || $::auth->get_session_value('client_id');
45 my (@webdav_dir_temp, @webdav_dir, @webdav_files);
47 # chdir to client root
48 my $webdav = $cwd. "/webdav/$client_id/";
49 chdir($webdav) or die "couldn't change into webdav dir"; # TODO throw better error message (Permission denied, etc)
51 find( { wanted => sub { push @webdav_dir_temp, -d && $_}, no_chdir => 1 }, '.');
52 find( { wanted => sub { push @webdav_files, -f && $_}, no_chdir => 1 }, '.');
54 shift @webdav_dir_temp; # first element would be undef after substr
55 foreach (@webdav_dir_temp) {
57 push @webdav_dir, substr($_,2);
59 @webdav_files = map { substr($_,2) } grep { $_ =~ m/.*pdf/ } @webdav_files;
61 $ret = $dav->open(-url => $url) or die "Can't open url $url";
62 # Make a null lock on repo for 5minutes
63 #$ret = $dav->lock(-url => $url, -timeout => "30m") or die;
65 foreach (@webdav_dir) {
68 $ret = $dav->options(-url => $url . '/' . $_);
69 next unless $ret =~ m/MKCOL/;
71 unless ( $dav->mkcol($_) ) {
72 push(@fails, "Cannot make dir $_");
76 #$dav->unlock(-url => $url); # UNLOCK after DIR sync
77 # now we have all dirs in sync, therefore we can place files
78 foreach (@webdav_files) {
81 $ret = $dav->options(-url => $url . '/' . $_);
82 # $main::lxdebug->message(0, 'verzeichnis:'. $_ . '::' . $ret . ':' . $dav->message);
83 next unless $ret =~ m/MKCOL/; # file not there #owncloud gives DELETE even if file not there
84 #$dav->lock(-url => $url . '/' . $_); # UNLOCK after DIR sync
86 # $main::lxdebug->message(0, 'datei:'. $_);
87 unless ( $dav->put(-local => $_, -url => $url . '/' . $_) ) {
88 push(@fails, "Cannot put file $_");
90 #$dav->unlock(-url => $url . '/' . $_); # UNLOCK after put
93 # maybe we delete some stuff
94 # TODO delete stuff here
96 foreach (qw(anfragen bestellungen einkaufslieferscheine einkaufsrechnungen angebote
97 gutschriften lieferantenbestellungen rechnungen verkaufslieferscheine)) {
98 $ret = $dav->delete($url . "/$_");
101 # better, but not implemented - delete only local deleted stuff
102 # idea: propfind all the above dirs and check if child (rel_uri) exists locally
103 # if not, we can safely delete remote
104 # if (my $r=$dav->propfind( -url=>"$_/", -depth=>1) ) { ...
107 #$dav->unlock(-url => $url);
113 my $error = "dav: " . $dav->message . ", eval: " . $! . ", eval 2: " . $@;
114 # $dav->unlock(-url => $url); # unlock, just in case
116 die("Couldn't sync with external webdav repo at $url error code/protocol return:" . $error);
120 die join("\n", @fails);
134 SL::BackgroundJob::ExternalSyncWebDAV - Background job for
135 syncing all folders and files for current client to a external
140 This background job copies all files and folders for one client
141 to a external webdav-repo.
142 A optional param C<delete> can be set to 1 to delete (clean)
143 the external repo. If set to undef or 0 a folderwise copy will be
145 To test with different clients a param C<client_id> will overload
146 the current client id.
147 The settings for the external repo are in client config.
148 If a lock still exists, the job returns a Internal Server Error
149 from the webdav server.
150 Only pdf files are considered valid files to copy.
152 The job is supposed to run once a day.
160 Jan Büren E<lt>jan@kivitendo-premium.deE<gt>