1 package SL::File::Backend::Webdav;
 
   5 use parent qw(SL::File::Backend);
 
  12 use File::Path qw(make_path);
 
  13 use File::MimeInfo::Magic;
 
  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});
 
  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);
 
  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};
 
  47   if ($params{dbfile}->id * 1 == 0) {
 
  49     # new element: need id for file
 
  50     $params{dbfile}->save;
 
  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);
 
  56   elsif ($params{file_contents}) {
 
  57     open(OUT, "> " . $tofile);
 
  58     print OUT $params{file_contents};
 
  64 sub get_version_count {
 
  65   my ($self, %params) = @_;
 
  66   die "no dbfile" unless $params{dbfile};
 
  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;
 
  78   my $dt = DateTime->from_epoch(epoch => $st[9])->clone();
 
  79   $main::lxdebug->message(LXDebug->DEBUG2(), "dt=" .$dt);
 
  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;
 
  92   my ($self, %params) = @_;
 
  93   my $path = $self->get_filepath(%params);
 
  94   return "" unless $path;
 
  95   my $contents = File::Slurp::read_file($path);
 
  99 sub sync_from_backend {
 
 100   my ($self, %params) = @_;
 
 101   return unless $params{file_type};
 
 103   $self->sync_all_locations(%params);
 
 108   return 0 unless $::instance_conf->get_doc_webdav;
 
 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',
 
 127   service                 => 'dienstleistungen',
 
 128   assembly                => 'erzeugnisse',
 
 130   general_ledger          => 'dialogbuchungen',
 
 131   accounts_payable        => 'kreditorenbuchungen',
 
 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',
 
 148   general_ledger          => 'GLTransaction',
 
 149   accounts_payable        => 'GLTransaction',
 
 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'
 
 163   my ($self, $dbfile) = @_;
 
 165   #die "No webdav backend enabled" unless $::instance_conf->get_webdav;
 
 167   my $type = $type_to_path{ $dbfile->object_type };
 
 169   die "Unknown type" unless $type;
 
 171   my $number = $dbfile->backend_data;
 
 173     $number = $self->_get_number_from_model($dbfile);
 
 174     $dbfile->backend_data($number);
 
 177   $main::lxdebug->message(LXDebug->DEBUG2(), "file_name=" . $dbfile->file_name ." number=".$number);
 
 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;
 
 184   my $basename = join('_', @fileparts);
 
 186   my $path = File::Spec->catdir($self->get_rootdir, "webdav", $::auth->client->{id}, $type, $number);
 
 188     File::Path::make_path($path, { chmod => 0770 });
 
 190   my $fname = $basename . '_' . $number . '_' . $dbfile->itime->strftime('%Y%m%d_%H%M%S');
 
 191   $fname .= '.' . $ext if $ext;
 
 193   $main::lxdebug->message(LXDebug->DEBUG2(), "webdav path=" . $path . " filename=" . $fname);
 
 195   return (File::Spec->catfile($path, $fname), $path, $fname);
 
 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';
 
 210 sub _get_number_from_model {
 
 211   my ($self, $dbfile) = @_;
 
 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;
 
 222 # TODO not fully imlemented and tested
 
 224 sub sync_all_locations {
 
 225   my ($self, %params) = @_;
 
 227   my %dateparms = (dateformat => 'yyyymmdd');
 
 229   foreach my $type (keys %type_to_path) {
 
 232       file_type => $params{file_type},
 
 235     my @oldfiles = @{ SL::DB::Manager::File->get_all(
 
 237           file_type => $params{file_type},
 
 243     my $path = File::Spec->catdir($self->get_rootdir, "webdav", $::auth->client->{id},$type_to_path{$type});
 
 245     if (opendir my $dir, $path) {
 
 246       foreach my $file (sort { lc $a cmp lc $b }
 
 247         map { decode("UTF-8", $_) } readdir $dir)
 
 249         next if (($file eq '.') || ($file eq '..'));
 
 254         my ($filename, $number, $date, $time_ext) = split(/_/, $fname);
 
 255         my ($time, $ext) = split(/\./, $time_ext, 2);
 
 257         $time = substr($time, 0, 2) . ':' . substr($time, 2, 2) . ':' . substr($time, 4, 2);
 
 259         #my @found = grep { $_->backend_data eq $fname } @oldfiles;
 
 260         #if (scalar(@found) > 0) {
 
 261         #  @oldfiles = grep { $_ != @found[0] } @oldfiles;
 
 264           my $dbfile = SL::DB::File->new();
 
 265           my $class  = 'SL::DB::Manager::' . $type_to_model{$type};
 
 268             $model_to_number{ $type_to_model{$type} } => $number);
 
 271             my $mime_type = File::MimeInfo::Magic::magic(File::Spec->catfile($path, $fname));
 
 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;
 
 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),
 
 307 SL::File::Backend::Filesystem  - Filesystem class for file storage backend
 
 311 See the synopsis of L<SL::File::Backend>.
 
 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.
 
 323 See methods of L<SL::File::Backend>.
 
 331 The synchronization must be tested and a periodical task is needed to synchronize in some time periods.
 
 335 Martin Helmling E<lt>martin.helmling@opendynamic.deE<gt>