Projekt

Allgemein

Profil

« Zurück | Weiter » 

Revision 0e9f27e4

Von Martin Helmling martin.helmling@octosoft.eu vor fast 8 Jahren hinzugefügt

  • ID 0e9f27e4397f0d7f22b61873d1cb2846854effed
  • Vorgänger 2e2ac4ba
  • Nachfolger 94b28d72

Dateimanagement: Webdav Backend (NICHT FERTIG !!!)

Dieses Backend bedarf noch Entwicklung

Die Synchronisierung ist noch nicht fertig implementiert und getestet

Unterschiede anzeigen:

SL/File/Backend/Webdav.pm
1
package SL::File::Backend::Webdav;
2

  
3
use strict;
4

  
5
use parent qw(SL::File::Backend);
6
use SL::DB::File;
7

  
8
#use SL::Webdav;
9
use File::Copy;
10
use File::Slurp;
11
use File::Basename;
12
use File::Path qw(make_path);
13
use File::MimeInfo::Magic;
14

  
15
#
16
# public methods
17
#
18

  
19
sub delete {
20
  my ($self, %params) = @_;
21
  $main::lxdebug->message(LXDebug->DEBUG2(), "del in backend " . $self . "  file " . $params{dbfile});
22
  $main::lxdebug->message(LXDebug->DEBUG2(), "file id=" . $params{dbfile}->id * 1);
23
  return 0 unless $params{dbfile};
24
  my ($file_path, undef, undef) = $self->webdav_path($params{dbfile});
25
  unlink($file_path);
26
  return 1;
27
}
28

  
29
sub rename {
30
  my ($self, %params) = @_;
31
  return 0 unless $params{dbfile};
32
  my (undef, $oldwebdavname) = split(/:/, $params{dbfile}->location, 2);
33
  my ($tofile, $basepath, $basename) = $self->webdav_path($params{dbfile});
34
  my $fromfile = File::Spec->catfile($basepath, $oldwebdavname);
35
  $main::lxdebug->message(LXDebug->DEBUG2(), "renamefrom=" . $fromfile . " to=" . $tofile);
36
  move($fromfile, $tofile);
37
}
38

  
39
sub save {
40
  my ($self, %params) = @_;
41
  die 'dbfile not exists' unless $params{dbfile};
42
  $main::lxdebug->message(LXDebug->DEBUG2(), "in backend " . $self . "  file " . $params{dbfile});
43
  $main::lxdebug->message(LXDebug->DEBUG2(), "file id=" . $params{dbfile}->id);
44
  my $dbfile = $params{dbfile};
45
  die 'no file contents' unless $params{file_path} || $params{file_contents};
46

  
47
  if ($params{dbfile}->id * 1 == 0) {
48

  
49
    # new element: need id for file
50
    $params{dbfile}->save;
51
  }
52
  my ($tofile, undef, $basename) = $self->webdav_path($params{dbfile});
53
  if ($params{file_path} && -f $params{file_path}) {
54
    copy($params{file_path}, $tofile);
55
  }
56
  elsif ($params{file_contents}) {
57
    open(OUT, "> " . $tofile);
58
    print OUT $params{file_contents};
59
    close(OUT);
60
  }
61
  return 1;
62
}
63

  
64
sub get_version_count {
65
  my ($self, %params) = @_;
66
  die "no dbfile" unless $params{dbfile};
67
  ## TODO
68
  return 1;
69
}
70

  
71
sub get_mtime {
72
  my ($self, %params) = @_;
73
  die "no dbfile" unless $params{dbfile};
74
  $main::lxdebug->message(LXDebug->DEBUG2(), "version=" .$params{version});
75
  my ($path, undef, undef) = $self->webdav_path($params{dbfile});
76
  die "no file found in backend" if !-f $path;
77
  my @st = stat($path);
78
  my $dt = DateTime->from_epoch(epoch => $st[9])->clone();
79
  $main::lxdebug->message(LXDebug->DEBUG2(), "dt=" .$dt);
80
  return $dt;
81
}
82

  
83
sub get_filepath {
84
  my ($self, %params) = @_;
85
  die "no dbfile" unless $params{dbfile};
86
  my ($path, undef, undef) = $self->webdav_path($params{dbfile});
87
  die "no file" if !-f $path;
88
  return $path;
89
}
90

  
91
sub get_content {
92
  my ($self, %params) = @_;
93
  my $path = $self->get_filepath(%params);
94
  return "" unless $path;
95
  my $contents = File::Slurp::read_file($path);
96
  return \$contents;
97
}
98

  
99
sub sync_from_backend {
100
  my ($self, %params) = @_;
101
  return unless $params{file_type};
102

  
103
  $self->sync_all_locations(%params);
104

  
105
}
106

  
107
sub enabled {
108
  return 0 unless $::instance_conf->get_doc_webdav;
109
  return 1;
110
}
111

  
112
#
113
# internals
114
#
115

  
116
my %type_to_path = (
117
  sales_quotation         => 'angebote',
118
  sales_order             => 'bestellungen',
119
  request_quotation       => 'anfragen',
120
  purchase_order          => 'lieferantenbestellungen',
121
  sales_delivery_order    => 'verkaufslieferscheine',
122
  purchase_delivery_order => 'einkaufslieferscheine',
123
  credit_note             => 'gutschriften',
124
  invoice                 => 'rechnungen',
125
  purchase_invoice        => 'einkaufsrechnungen',
126
  part                    => 'waren',
127
  service                 => 'dienstleistungen',
128
  assembly                => 'erzeugnisse',
129
  letter                  => 'briefe',
130
  general_ledger          => 'dialogbuchungen',
131
  accounts_payable        => 'kreditorenbuchungen',
132
);
133

  
134
my %type_to_model = (
135
  sales_quotation         => 'Order',
136
  sales_order             => 'Order',
137
  request_quotation       => 'Order',
138
  purchase_order          => 'Order',
139
  sales_delivery_order    => 'DeliveryOrder',
140
  purchase_delivery_order => 'DeliveryOrder',
141
  credit_note             => 'Invoice',
142
  invoice                 => 'Invoice',
143
  purchase_invoice        => 'PurchaseInvoice',
144
  part                    => 'Part',
145
  service                 => 'Part',
146
  assembly                => 'Part',
147
  letter                  => 'Letter',
148
  general_ledger          => 'GLTransaction',
149
  accounts_payable        => 'GLTransaction',
150
);
151

  
152
my %model_to_number = (
153
  Order           => 'ordnumber',
154
  DeliveryOrder   => 'ordnumber',
155
  Invoice         => 'invnumber',
156
  PurchaseInvoice => 'invnumber',
157
  Part            => 'partnumber',
158
  Letter          => 'letternumber',
159
  GLTransaction   => 'reference'
160
);
161

  
162
sub webdav_path {
163
  my ($self, $dbfile) = @_;
164

  
165
  #die "No webdav backend enabled" unless $::instance_conf->get_webdav;
166

  
167
  my $type = $type_to_path{ $dbfile->object_type };
168

  
169
  die "Unknown type" unless $type;
170

  
171
  my $number = $dbfile->backend_data;
172
  if ($number eq '') {
173
    $number = $self->_get_number_from_model($dbfile);
174
    $dbfile->backend_data($number);
175
    $dbfile->save;
176
  }
177
  $main::lxdebug->message(LXDebug->DEBUG2(), "file_name=" . $dbfile->file_name ." number=".$number);
178

  
179
  my @fileparts = split(/_/, $dbfile->file_name);
180
  my $number_ext = pop @fileparts;
181
  my ($maynumber, $ext) = split(/\./, $number_ext, 2);
182
  push @fileparts, $maynumber if $maynumber ne $number;
183

  
184
  my $basename = join('_', @fileparts);
185

  
186
  my $path = File::Spec->catdir($self->get_rootdir, "webdav", $::auth->client->{id}, $type, $number);
187
  if (!-d $path) {
188
    File::Path::make_path($path, { chmod => 0770 });
189
  }
190
  my $fname = $basename . '_' . $number . '_' . $dbfile->itime->strftime('%Y%m%d_%H%M%S');
191
  $fname .= '.' . $ext if $ext;
192

  
193
  $main::lxdebug->message(LXDebug->DEBUG2(), "webdav path=" . $path . " filename=" . $fname);
194

  
195
  return (File::Spec->catfile($path, $fname), $path, $fname);
196
}
197

  
198
sub get_rootdir {
199
  my ($self) = @_;
200

  
201
  #TODO immer noch das alte Problem:
202
  #je nachdem von woher der Aufruf kommt ist man in ./users oder .
203
  my $rootdir  = POSIX::getcwd();
204
  my $basename = basename($rootdir);
205
  my $dirname  = dirname($rootdir);
206
  $rootdir = $dirname if $basename eq 'users';
207
  return $rootdir;
208
}
209

  
210
sub _get_number_from_model {
211
  my ($self, $dbfile) = @_;
212

  
213
  my $class = 'SL::DB::' . $type_to_model{ $dbfile->object_type };
214
  eval "require $class";
215
  my $obj = $class->new(id => $dbfile->object_id)->load;
216
  die 'no object found' unless $obj;
217
  my $numberattr = $model_to_number{ $type_to_model{ $dbfile->object_type } };
218
  return $obj->$numberattr;
219
}
220

  
221
#
222
# TODO not fully imlemented and tested
223
#
224
sub sync_all_locations {
225
  my ($self, %params) = @_;
226

  
227
  my %dateparms = (dateformat => 'yyyymmdd');
228

  
229
  foreach my $type (keys %type_to_path) {
230

  
231
    my @query = (
232
      file_type => $params{file_type},
233
      object_type    => $type
234
    );
235
    my @oldfiles = @{ SL::DB::Manager::File->get_all(
236
        query => [
237
          file_type => $params{file_type},
238
          object_type    => $type
239
        ]
240
      )
241
    };
242

  
243
    my $path = File::Spec->catdir($self->get_rootdir, "webdav", $::auth->client->{id},$type_to_path{$type});
244

  
245
    if (opendir my $dir, $path) {
246
      foreach my $file (sort { lc $a cmp lc $b }
247
        map { decode("UTF-8", $_) } readdir $dir)
248
      {
249
        next if (($file eq '.') || ($file eq '..'));
250

  
251
        my $fname = $file;
252
        $fname =~ s|.*/||;
253

  
254
        my ($filename, $number, $date, $time_ext) = split(/_/, $fname);
255
        my ($time, $ext) = split(/\./, $time_ext, 2);
256

  
257
        $time = substr($time, 0, 2) . ':' . substr($time, 2, 2) . ':' . substr($time, 4, 2);
258

  
259
        #my @found = grep { $_->backend_data eq $fname } @oldfiles;
260
        #if (scalar(@found) > 0) {
261
        #  @oldfiles = grep { $_ != @found[0] } @oldfiles;
262
        #}
263
        #else {
264
          my $dbfile = SL::DB::File->new();
265
          my $class  = 'SL::DB::Manager::' . $type_to_model{$type};
266
          my $obj =
267
            $class->find_by(
268
            $model_to_number{ $type_to_model{$type} } => $number);
269
          if ($obj) {
270

  
271
            my $mime_type = File::MimeInfo::Magic::magic(File::Spec->catfile($path, $fname));
272
            if (!$mime_type) {
273
              # if filename has the suffix "pdf", but is really no pdf set mimetype for no suffix
274
              $mime_type = File::MimeInfo::Magic::mimetype($fname);
275
              $mime_type = 'application/octet-stream' if $mime_type eq 'application/pdf' || !$mime_type;
276
            }
277

  
278
            $dbfile->assign_attributes(
279
              object_id   => $obj->id,
280
              object_type => $type,
281
              source      => $params{file_type} eq 'document' ? 'created' : 'uploaded',
282
              file_type   => $params{file_type},
283
              file_name   => $filename . '_' . $number . '_' . $ext,
284
              mime_type   => $mime_type,
285
              itime       => $::locale->parse_date_to_object($date . ' ' . $time, %dateparms),
286
            );
287
            $dbfile->save;
288
          }
289
        #}
290

  
291
        closedir $dir;
292
      }
293
    }
294
  }
295
}
296

  
297
1;
298

  
299
__END__
300

  
301
=pod
302

  
303
=encoding utf8
304

  
305
=head1 NAME
306

  
307
SL::File::Backend::Filesystem  - Filesystem class for file storage backend
308

  
309
=head1 SYNOPSIS
310

  
311
See the synopsis of L<SL::File::Backend>.
312

  
313
=head1 OVERVIEW
314

  
315
This specific storage backend use a Filesystem which is only accessed by this interface.
316
This is the big difference to the Webdav backend where the files can be accessed without the control of that backend.
317
This backend use the database id of the SL::DB::File object as filename. The filesystem has up to 1000 subdirectories
318
to store the files not to flat in the filesystem.
319

  
320

  
321
=head1 METHODS
322

  
323
See methods of L<SL::File::Backend>.
324

  
325
=head1 SEE ALSO
326

  
327
L<SL::File::Backend>
328

  
329
=head1 TODO
330

  
331
The synchronization must be tested and a periodical task is needed to synchronize in some time periods.
332

  
333
=head1 AUTHOR
334

  
335
Martin Helmling E<lt>martin.helmling@opendynamic.deE<gt>
336

  
337
=cut
338

  
339

  

Auch abrufbar als: Unified diff