Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision cd303dbe

Von Jan Büren vor mehr als 1 Jahr hinzugefügt

  • ID cd303dbe49cbe62870b2efd94a1abc1ac65069d1
  • Vorgänger 940b81b3
  • Nachfolger c5eb005a

Hintergrund-Job externe WebDAV-Synchronisation von um kivi-WebDAV-Ordnern

Unterschiede anzeigen:

SL/BackgroundJob/SyncWebDAV.pm
1
package SL::BackgroundJob::SyncWebDAV;
2

  
3
use strict;
4
use warnings;
5

  
6
use parent qw(SL::BackgroundJob::Base);
7

  
8
use SL::DB::BackgroundJobHistory;
9
use HTTP::DAV;
10
use File::Find;
11
use Cwd;
12
use Data::Dumper;
13

  
14
sub create_job {
15
  $_[0]->create_standard_job('0 3 * * *'); # daily at 3:00 am
16
}
17

  
18
sub run {
19
  my $self    = shift;
20
  my $db_obj  = shift;
21

  
22
  my $options     = $db_obj->data_as_hash;
23
  my $DELETE_ONLY = 0 || $options->{delete};
24

  
25
  return unless $::instance_conf->get_webdav_sync_extern;
26

  
27
  my $ret;
28

  
29
  my $dav     = HTTP::DAV->new();
30
  my $url     = $::instance_conf->get_webdav_sync_extern_url;
31
  $url        =~ s|/\z||;  # no trailing slashes
32

  
33
  $dav->credentials(
34
       -user  =>  $::instance_conf->get_webdav_sync_extern_login,
35
       -pass  =>  $::instance_conf->get_webdav_sync_extern_pass,
36
       -url   =>  $url,
37
  );
38
  my $client_id   = $options->{client_id} || $::auth->get_session_value('client_id');
39
  my $cwd = getcwd();
40

  
41
  my @fails;
42

  
43
  eval {
44

  
45
    my (@webdav_dir_temp, @webdav_dir, @webdav_files);
46

  
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)
50

  
51
    find( { wanted => sub { push @webdav_dir_temp, -d && $_}, no_chdir => 1 }, '.');
52
    find( { wanted => sub { push @webdav_files, -f && $_}, no_chdir => 1    }, '.');
53

  
54
    shift @webdav_dir_temp; # first element would be undef after substr
55
    foreach (@webdav_dir_temp) {
56
      next unless $_;
57
      push @webdav_dir, substr($_,2);
58
    }
59
    @webdav_files = map { substr($_,2) } grep { $_ =~ m/.*pdf/ } @webdav_files;
60

  
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;
64

  
65
    foreach (@webdav_dir) {
66
      last if $DELETE_ONLY;
67

  
68
      $ret             = $dav->options(-url => $url . '/' . $_);
69
      next unless $ret =~ m/MKCOL/;
70

  
71
      unless ( $dav->mkcol($_) ) {
72
        push(@fails, "Cannot make dir $_");
73
      };
74
    }
75

  
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) {
79
      last if $DELETE_ONLY;
80

  
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
85

  
86
      # $main::lxdebug->message(0, 'datei:'. $_);
87
      unless ( $dav->put(-local => $_, -url => $url . '/' . $_) ) {
88
        push(@fails, "Cannot put file $_");
89
      };
90
      #$dav->unlock(-url => $url . '/' . $_); # UNLOCK after put
91
    }
92

  
93
    # maybe we delete some stuff
94
    # TODO delete stuff here
95
    if ($DELETE_ONLY) {
96
      foreach (qw(anfragen bestellungen einkaufslieferscheine einkaufsrechnungen angebote
97
             gutschriften lieferantenbestellungen rechnungen verkaufslieferscheine)) {
98
        $ret = $dav->delete($url . "/$_");
99
      }
100

  
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) ) { ...
105
    }
106

  
107
    #$dav->unlock(-url => $url);
108
    chdir($cwd);
109

  
110
    1;
111

  
112
  } or do {
113
    my $error = "dav: " . $dav->message . ", eval: " . $! . ", eval 2: " . $@;
114
   # $dav->unlock(-url => $url);    # unlock, just in case
115
    # chdir($cwd);
116
    die("Couldn't sync with external webdav repo at $url error code/protocol return:" . $error);
117
  };
118

  
119
  if ( @fails ) {
120
    die join("\n", @fails);
121
  };
122

  
123
  return 1;
124
}
125

  
126
1;
127

  
128
__END__
129

  
130
=encoding utf8
131

  
132
=head1 NAME
133

  
134
SL::BackgroundJob::ExternalSyncWebDAV - Background job for
135
syncing all folders and files for current client to a external
136
webdav-repository
137

  
138
=head1 SYNOPSIS
139

  
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
144
executed.
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.
151

  
152
The job is supposed to run once a day.
153

  
154
=head1 BUGS
155

  
156
Nothing here yet.
157

  
158
=head1 AUTHOR
159

  
160
Jan Büren E<lt>jan@kivitendo-premium.deE<gt>
161

  
162
=cut
163

  
SL/DB/MetaSetup/Default.pm
223 223
  warn_no_delivery_order_for_invoice        => { type => 'boolean', default => 'false' },
224 224
  webdav                                    => { type => 'boolean', default => 'false' },
225 225
  webdav_documents                          => { type => 'boolean', default => 'false' },
226
  webdav_sync_extern                        => { type => 'boolean', default => 'false' },
227
  webdav_sync_extern_login                  => { type => 'text' },
228
  webdav_sync_extern_pass                   => { type => 'text' },
229
  webdav_sync_extern_url                    => { type => 'text' },
226 230
  weightunit                                => { type => 'varchar', length => 5 },
227 231
  workflow_po_ap_chart_id                   => { type => 'integer' },
228 232
);
SL/InstallationCheck.pm
77 77
);
78 78

  
79 79
@optional_modules = (
80
  { name => 'HTTP::DAV', version => 0.46,          url => 'http://search.cpan.org/~cosimo/',    debian => 'libhttp-dav-perl' },
80 81
  { name => "IO::Socket::SSL",                     url => "http://search.cpan.org/~sullr/",     debian => 'libio-socket-ssl-perl' },
81 82
  { name => "Net::LDAP",                           url => "http://search.cpan.org/~gbarr/",     debian => 'libnet-ldap-perl' },
82 83
  # Net::SMTP is core since 5.7.3
sql/Pg-upgrade2/defaults_webdav.sql
1
-- @tag: defaults_webdav
2
-- @description: Synchronisation mit externem WebDAV-Server
3
-- @depends: release_3_8_0
4
ALTER TABLE defaults ADD COLUMN webdav_sync_extern boolean DEFAULT false;
5
ALTER TABLE defaults ADD COLUMN webdav_sync_extern_url text;
6
ALTER TABLE defaults ADD COLUMN webdav_sync_extern_login text;
7
ALTER TABLE defaults ADD COLUMN webdav_sync_extern_pass text;
templates/design40_webpages/client_config/_features.html
34 34
        <td>[% L.yes_no_tag('defaults.webdav_documents', SELF.defaults.webdav_documents) %]</td>
35 35
        <td class="long-desc">[% LxERP.t8('Save document in WebDAV repository') %]</td>
36 36
      </tr>
37
      <tr>
38
        <th>[% LxERP.t8('WebDAV sync extern') %]</td>
39
        <td>[% L.yes_no_tag('defaults.webdav_sync_extern', SELF.defaults.webdav_sync_extern) %]</td>
40
        <td class="long-desc">[% LxERP.t8('Synchronize WebDAV with owncloud repository') %]</td>
41
      </tr>
42
      <tr>
43
        <th>[% LxERP.t8('Destination URL for sync') %]</td>
44
        <td class="long-desc"> [% L.input_tag('defaults.webdav_sync_extern_url', SELF.defaults.webdav_sync_extern_url, style=style) %]</td>
45
        <td>[% LxERP.t8('Complete URL for WebDAV sync external, including port and folders, i.e.: https://foo.com:4433/owncloud/kivitendo') %]</td>
46
      </tr>
47
      <tr>
48
        <th>[% LxERP.t8('Login for sync') %]</td>
49
        <td class="long-desc">[% L.input_tag('defaults.webdav_sync_extern_login', SELF.defaults.webdav_sync_extern_login, style=style) %]</td>
50
        <td>[% LxERP.t8('Login for WebDAV sync external') %]</td>
51
      </tr>
52
      <tr>
53
        <th>[% LxERP.t8('Password for sync') %]</td>
54
        <td class="long-desc">[% L.input_tag('defaults.webdav_sync_extern_pass', SELF.defaults.webdav_sync_extern_pass, style=style) %]</td>
55
        <td>[% LxERP.t8('Password for WebDAV sync external') %]</td>
56
      </tr>
37 57
      <tr>
38 58
        <th>[% LxERP.t8('Filemanagement') %]</th>
39 59
        <td>[% L.yes_no_tag('defaults.doc_storage', SELF.defaults.doc_storage) %]</td>
templates/webpages/client_config/_features.html
29 29
   <td>[% L.yes_no_tag('defaults.webdav_documents', SELF.defaults.webdav_documents) %]</td>
30 30
   <td>[% LxERP.t8('Save document in WebDAV repository') %]</td>
31 31
  </tr>
32
  <tr>
33
   <td align="right">[% LxERP.t8('WebDAV sync extern') %]</td>
34
   <td>[% L.yes_no_tag('defaults.webdav_sync_extern', SELF.defaults.webdav_sync_extern) %]</td>
35
   <td>[% LxERP.t8('Synchronize WebDAV with owncloud repository') %]</td>
36
  </tr>
37
  <tr>
38
   <td align="right">[% LxERP.t8('Destination URL for sync') %]</td>
39
   <td>[% L.input_tag('defaults.webdav_sync_extern_url', SELF.defaults.webdav_sync_extern_url, style=style) %]</td>
40
   <td>[% LxERP.t8('Complete URL for WebDAV sync external, including port and folders, i.e.: https://foo.com:4433/owncloud/kivitendo') %]</td>
41
  </tr>
42
  <tr>
43
   <td align="right">[% LxERP.t8('Login for sync') %]</td>
44
   <td>[% L.input_tag('defaults.webdav_sync_extern_login', SELF.defaults.webdav_sync_extern_login, style=style) %]</td>
45
   <td>[% LxERP.t8('Login for WebDAV sync external') %]</td>
46
  </tr>
47
  <tr>
48
   <td align="right">[% LxERP.t8('Password for sync') %]</td>
49
   <td>[% L.input_tag('defaults.webdav_sync_extern_pass', SELF.defaults.webdav_sync_extern_pass, style=style) %]</td>
50
   <td>[% LxERP.t8('Password for WebDAV sync external') %]</td>
51
  </tr>
32 52
  <tr>
33 53
   <td align="right">[% LxERP.t8('Filemanagement') %]</td>
34 54
   <td>[% L.yes_no_tag('defaults.doc_storage', SELF.defaults.doc_storage) %]</td>

Auch abrufbar als: Unified diff