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   gl_transaction          => 'dialogbuchungen',
 
 132   accounts_payable        => 'kreditorenbuchungen',
 
 133   shop_image              => 'shopbilder',
 
 134   customer                => 'kunden',
 
 135   vendor                  => 'lieferanten',
 
 138 my %type_to_model = (
 
 139   sales_quotation         => 'Order',
 
 140   sales_order             => 'Order',
 
 141   request_quotation       => 'Order',
 
 142   purchase_order          => 'Order',
 
 143   sales_delivery_order    => 'DeliveryOrder',
 
 144   purchase_delivery_order => 'DeliveryOrder',
 
 145   credit_note             => 'Invoice',
 
 146   invoice                 => 'Invoice',
 
 147   purchase_invoice        => 'PurchaseInvoice',
 
 152   general_ledger          => 'GLTransaction',
 
 153   gl_transaction          => 'GLTransaction',
 
 154   accounts_payable        => 'GLTransaction',
 
 155   shop_image              => 'Part',
 
 156   customer                => 'Customer',
 
 160 my %model_to_number = (
 
 161   Order           => 'ordnumber',
 
 162   DeliveryOrder   => 'ordnumber',
 
 163   Invoice         => 'invnumber',
 
 164   PurchaseInvoice => 'invnumber',
 
 165   Part            => 'partnumber',
 
 166   Letter          => 'letternumber',
 
 167   GLTransaction   => 'reference',
 
 168   ShopImage       => 'partnumber',
 
 169   Customer        => 'customernumber',
 
 170   Vendor          => 'vendornumber',
 
 174   my ($self, $dbfile) = @_;
 
 176   #die "No webdav backend enabled" unless $::instance_conf->get_webdav;
 
 178   my $type = $type_to_path{ $dbfile->object_type };
 
 180   die "Unknown type" unless $type;
 
 182   my $number = $dbfile->backend_data;
 
 184     $number = $self->_get_number_from_model($dbfile);
 
 185     $dbfile->backend_data($number);
 
 188   $main::lxdebug->message(LXDebug->DEBUG2(), "file_name=" . $dbfile->file_name ." number=".$number);
 
 190   my @fileparts = split(/_/, $dbfile->file_name);
 
 191   my $number_ext = pop @fileparts;
 
 192   my ($maynumber, $ext) = split(/\./, $number_ext, 2);
 
 193   push @fileparts, $maynumber if $maynumber ne $number;
 
 195   my $basename = join('_', @fileparts);
 
 197   my $path = File::Spec->catdir($self->get_rootdir, "webdav", $::auth->client->{id}, $type, $number);
 
 199     File::Path::make_path($path, { chmod => 0770 });
 
 201   my $fname = $basename . '_' . $number . '_' . $dbfile->itime->strftime('%Y%m%d_%H%M%S');
 
 202   $fname .= '.' . $ext if $ext;
 
 204   $main::lxdebug->message(LXDebug->DEBUG2(), "webdav path=" . $path . " filename=" . $fname);
 
 206   return (File::Spec->catfile($path, $fname), $path, $fname);
 
 212   #TODO immer noch das alte Problem:
 
 213   #je nachdem von woher der Aufruf kommt ist man in ./users oder .
 
 214   my $rootdir  = POSIX::getcwd();
 
 215   my $basename = basename($rootdir);
 
 216   my $dirname  = dirname($rootdir);
 
 217   $rootdir = $dirname if $basename eq 'users';
 
 221 sub _get_number_from_model {
 
 222   my ($self, $dbfile) = @_;
 
 224   my $class = 'SL::DB::' . $type_to_model{ $dbfile->object_type };
 
 225   eval "require $class";
 
 226   my $obj = $class->new(id => $dbfile->object_id)->load;
 
 227   die 'no object found' unless $obj;
 
 228   my $numberattr = $model_to_number{ $type_to_model{ $dbfile->object_type } };
 
 229   return $obj->$numberattr;
 
 233 # TODO not fully imlemented and tested
 
 235 sub sync_all_locations {
 
 236   my ($self, %params) = @_;
 
 238   my %dateparms = (dateformat => 'yyyymmdd');
 
 240   foreach my $type (keys %type_to_path) {
 
 243       file_type => $params{file_type},
 
 246     my @oldfiles = @{ SL::DB::Manager::File->get_all(
 
 248           file_type => $params{file_type},
 
 254     my $path = File::Spec->catdir($self->get_rootdir, "webdav", $::auth->client->{id},$type_to_path{$type});
 
 256     if (opendir my $dir, $path) {
 
 257       foreach my $file (sort { lc $a cmp lc $b }
 
 258         map { decode("UTF-8", $_) } readdir $dir)
 
 260         next if (($file eq '.') || ($file eq '..'));
 
 265         my ($filename, $number, $date, $time_ext) = split(/_/, $fname);
 
 266         my ($time, $ext) = split(/\./, $time_ext, 2);
 
 268         $time = substr($time, 0, 2) . ':' . substr($time, 2, 2) . ':' . substr($time, 4, 2);
 
 270         #my @found = grep { $_->backend_data eq $fname } @oldfiles;
 
 271         #if (scalar(@found) > 0) {
 
 272         #  @oldfiles = grep { $_ != @found[0] } @oldfiles;
 
 275           my $dbfile = SL::DB::File->new();
 
 276           my $class  = 'SL::DB::Manager::' . $type_to_model{$type};
 
 279             $model_to_number{ $type_to_model{$type} } => $number);
 
 282             my $mime_type = File::MimeInfo::Magic::magic(File::Spec->catfile($path, $fname));
 
 284               # if filename has the suffix "pdf", but is really no pdf set mimetype for no suffix
 
 285               $mime_type = File::MimeInfo::Magic::mimetype($fname);
 
 286               $mime_type = 'application/octet-stream' if $mime_type eq 'application/pdf' || !$mime_type;
 
 289             $dbfile->assign_attributes(
 
 290               object_id   => $obj->id,
 
 291               object_type => $type,
 
 292               source      => $params{file_type} eq 'document' ? 'created' : 'uploaded',
 
 293               file_type   => $params{file_type},
 
 294               file_name   => $filename . '_' . $number . '_' . $ext,
 
 295               mime_type   => $mime_type,
 
 296               itime       => $::locale->parse_date_to_object($date . ' ' . $time, %dateparms),
 
 318 SL::File::Backend::Filesystem  - Filesystem class for file storage backend
 
 322 See the synopsis of L<SL::File::Backend>.
 
 326 This specific storage backend use a Filesystem which is only accessed by this interface.
 
 327 This is the big difference to the Webdav backend where the files can be accessed without the control of that backend.
 
 328 This backend use the database id of the SL::DB::File object as filename. The filesystem has up to 1000 subdirectories
 
 329 to store the files not to flat in the filesystem.
 
 334 See methods of L<SL::File::Backend>.
 
 342 The synchronization must be tested and a periodical task is needed to synchronize in some time periods.
 
 346 Martin Helmling E<lt>martin.helmling@opendynamic.deE<gt>