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',
 
 136 my %type_to_model = (
 
 137   sales_quotation         => 'Order',
 
 138   sales_order             => 'Order',
 
 139   request_quotation       => 'Order',
 
 140   purchase_order          => 'Order',
 
 141   sales_delivery_order    => 'DeliveryOrder',
 
 142   purchase_delivery_order => 'DeliveryOrder',
 
 143   credit_note             => 'Invoice',
 
 144   invoice                 => 'Invoice',
 
 145   purchase_invoice        => 'PurchaseInvoice',
 
 150   general_ledger          => 'GLTransaction',
 
 151   gl_transaction          => 'GLTransaction',
 
 152   accounts_payable        => 'GLTransaction',
 
 153   shop_image              => 'Part',
 
 156 my %model_to_number = (
 
 157   Order           => 'ordnumber',
 
 158   DeliveryOrder   => 'ordnumber',
 
 159   Invoice         => 'invnumber',
 
 160   PurchaseInvoice => 'invnumber',
 
 161   Part            => 'partnumber',
 
 162   Letter          => 'letternumber',
 
 163   GLTransaction   => 'reference',
 
 164   ShopImage       => 'partnumber',
 
 168   my ($self, $dbfile) = @_;
 
 170   #die "No webdav backend enabled" unless $::instance_conf->get_webdav;
 
 172   my $type = $type_to_path{ $dbfile->object_type };
 
 174   die "Unknown type" unless $type;
 
 176   my $number = $dbfile->backend_data;
 
 178     $number = $self->_get_number_from_model($dbfile);
 
 179     $dbfile->backend_data($number);
 
 182   $main::lxdebug->message(LXDebug->DEBUG2(), "file_name=" . $dbfile->file_name ." number=".$number);
 
 184   my @fileparts = split(/_/, $dbfile->file_name);
 
 185   my $number_ext = pop @fileparts;
 
 186   my ($maynumber, $ext) = split(/\./, $number_ext, 2);
 
 187   push @fileparts, $maynumber if $maynumber ne $number;
 
 189   my $basename = join('_', @fileparts);
 
 191   my $path = File::Spec->catdir($self->get_rootdir, "webdav", $::auth->client->{id}, $type, $number);
 
 193     File::Path::make_path($path, { chmod => 0770 });
 
 195   my $fname = $basename . '_' . $number . '_' . $dbfile->itime->strftime('%Y%m%d_%H%M%S');
 
 196   $fname .= '.' . $ext if $ext;
 
 198   $main::lxdebug->message(LXDebug->DEBUG2(), "webdav path=" . $path . " filename=" . $fname);
 
 200   return (File::Spec->catfile($path, $fname), $path, $fname);
 
 206   #TODO immer noch das alte Problem:
 
 207   #je nachdem von woher der Aufruf kommt ist man in ./users oder .
 
 208   my $rootdir  = POSIX::getcwd();
 
 209   my $basename = basename($rootdir);
 
 210   my $dirname  = dirname($rootdir);
 
 211   $rootdir = $dirname if $basename eq 'users';
 
 215 sub _get_number_from_model {
 
 216   my ($self, $dbfile) = @_;
 
 218   my $class = 'SL::DB::' . $type_to_model{ $dbfile->object_type };
 
 219   eval "require $class";
 
 220   my $obj = $class->new(id => $dbfile->object_id)->load;
 
 221   die 'no object found' unless $obj;
 
 222   my $numberattr = $model_to_number{ $type_to_model{ $dbfile->object_type } };
 
 223   return $obj->$numberattr;
 
 227 # TODO not fully imlemented and tested
 
 229 sub sync_all_locations {
 
 230   my ($self, %params) = @_;
 
 232   my %dateparms = (dateformat => 'yyyymmdd');
 
 234   foreach my $type (keys %type_to_path) {
 
 237       file_type => $params{file_type},
 
 240     my @oldfiles = @{ SL::DB::Manager::File->get_all(
 
 242           file_type => $params{file_type},
 
 248     my $path = File::Spec->catdir($self->get_rootdir, "webdav", $::auth->client->{id},$type_to_path{$type});
 
 250     if (opendir my $dir, $path) {
 
 251       foreach my $file (sort { lc $a cmp lc $b }
 
 252         map { decode("UTF-8", $_) } readdir $dir)
 
 254         next if (($file eq '.') || ($file eq '..'));
 
 259         my ($filename, $number, $date, $time_ext) = split(/_/, $fname);
 
 260         my ($time, $ext) = split(/\./, $time_ext, 2);
 
 262         $time = substr($time, 0, 2) . ':' . substr($time, 2, 2) . ':' . substr($time, 4, 2);
 
 264         #my @found = grep { $_->backend_data eq $fname } @oldfiles;
 
 265         #if (scalar(@found) > 0) {
 
 266         #  @oldfiles = grep { $_ != @found[0] } @oldfiles;
 
 269           my $dbfile = SL::DB::File->new();
 
 270           my $class  = 'SL::DB::Manager::' . $type_to_model{$type};
 
 273             $model_to_number{ $type_to_model{$type} } => $number);
 
 276             my $mime_type = File::MimeInfo::Magic::magic(File::Spec->catfile($path, $fname));
 
 278               # if filename has the suffix "pdf", but is really no pdf set mimetype for no suffix
 
 279               $mime_type = File::MimeInfo::Magic::mimetype($fname);
 
 280               $mime_type = 'application/octet-stream' if $mime_type eq 'application/pdf' || !$mime_type;
 
 283             $dbfile->assign_attributes(
 
 284               object_id   => $obj->id,
 
 285               object_type => $type,
 
 286               source      => $params{file_type} eq 'document' ? 'created' : 'uploaded',
 
 287               file_type   => $params{file_type},
 
 288               file_name   => $filename . '_' . $number . '_' . $ext,
 
 289               mime_type   => $mime_type,
 
 290               itime       => $::locale->parse_date_to_object($date . ' ' . $time, %dateparms),
 
 312 SL::File::Backend::Filesystem  - Filesystem class for file storage backend
 
 316 See the synopsis of L<SL::File::Backend>.
 
 320 This specific storage backend use a Filesystem which is only accessed by this interface.
 
 321 This is the big difference to the Webdav backend where the files can be accessed without the control of that backend.
 
 322 This backend use the database id of the SL::DB::File object as filename. The filesystem has up to 1000 subdirectories
 
 323 to store the files not to flat in the filesystem.
 
 328 See methods of L<SL::File::Backend>.
 
 336 The synchronization must be tested and a periodical task is needed to synchronize in some time periods.
 
 340 Martin Helmling E<lt>martin.helmling@opendynamic.deE<gt>