X-Git-Url: http://wagnertech.de/gitweb/gitweb.cgi/mfinanz.git/blobdiff_plain/8c7f25bcd4da160b26527fa23a2e598476dc052d..eeb5375ee7727c956cc357cc8f90b19d1bfe80b9:/SL/File/Backend/Filesystem.pm diff --git a/SL/File/Backend/Filesystem.pm b/SL/File/Backend/Filesystem.pm index a706c3820..d2ff9d3ed 100644 --- a/SL/File/Backend/Filesystem.pm +++ b/SL/File/Backend/Filesystem.pm @@ -4,9 +4,16 @@ use strict; use parent qw(SL::File::Backend); use SL::DB::File; +use SL::DB::FileVersion; + +use Carp; +use List::Util qw(first); + use File::Copy; use File::Slurp; +use File::stat; use File::Path qw(make_path); +use UUID::Tiny ':std'; # # public methods @@ -14,38 +21,32 @@ use File::Path qw(make_path); sub delete { my ($self, %params) = @_; - $main::lxdebug->message(LXDebug->DEBUG2(), "del in backend " . $self . " file " . $params{dbfile}); - $main::lxdebug->message(LXDebug->DEBUG2(), "file id=" . ($params{dbfile}->id * 1)); - die "no dbfile" unless $params{dbfile}; - my $backend_data = $params{dbfile}->backend_data; - $backend_data = 0 if $params{last}; - $backend_data = $params{dbfile}->backend_data-1 if $params{all_but_notlast}; - - if ($backend_data > 0 ) { - $main::lxdebug->message(LXDebug->DEBUG2(), "backend_data=" .$backend_data); - for my $version ( 1..$backend_data) { - my $file_path = $self->_filesystem_path($params{dbfile},$version); - $main::lxdebug->message(LXDebug->DEBUG2(), "unlink " .$file_path); - unlink($file_path); - } - if ($params{all_but_notlast}) { - my $from = $self->_filesystem_path($params{dbfile},$params{dbfile}->backend_data); - my $to = $self->_filesystem_path($params{dbfile},$params{dbfile}->backend_data); - die "file not exists" unless -f $from; - rename($from,$to); - $params{dbfile}->backend_data(1); + die "no dbfile in backend delete" unless $params{dbfile}; + + my @versions_to_delete; + if ($params{file_version}) { + croak "file_version has to be of type SL::DB::FileVersion" + unless ref $params{file_version} eq 'SL::DB::FileVersion'; + @versions_to_delete = ($params{file_version}); + } else { + my @versions = @{$params{dbfile}->file_versions_sorted}; + if ($params{last}) { + my $last = pop @versions; + @versions_to_delete = ($last); + } elsif ($params{all_but_notlast}) { + pop @versions; # remove last + @versions_to_delete = @versions; } else { - $params{dbfile}->backend_data(0); - my $dir_path = $self->_filesystem_path($params{dbfile}); - rmdir($dir_path); - $main::lxdebug->message(LXDebug->DEBUG2(), "unlink " .$dir_path); + @versions_to_delete = @versions; } - } else { - my $file_path = $self->_filesystem_path($params{dbfile},$params{dbfile}->backend_data); - die "file not exists" unless -f $file_path; - unlink($file_path); - $params{dbfile}->backend_data($params{dbfile}->backend_data-1); } + + foreach my $version (@versions_to_delete) { + unlink($version->get_system_location()); + $version->delete; + } + + return 1; } sub rename { @@ -53,45 +54,64 @@ sub rename { sub save { my ($self, %params) = @_; - die 'dbfile not exists' unless $params{dbfile}; - $main::lxdebug->message(LXDebug->DEBUG2(), "in backend " . $self . " file " . $params{dbfile}); - $main::lxdebug->message(LXDebug->DEBUG2(), "file id=" . $params{dbfile}->id . " path=" . $params{file_path}); - my $dbfile = $params{dbfile}; - die 'no file contents' unless $params{file_path} || $params{file_contents}; - $dbfile->backend_data(0) unless $dbfile->backend_data; - $dbfile->backend_data($dbfile->backend_data*1+1); - $dbfile->save->load; - - my $tofile = $self->_filesystem_path($dbfile); - $main::lxdebug->message(LXDebug->DEBUG2(), "topath=" . $tofile . " from=" . $params{file_path}); + + die 'dbfile not exists' unless ref $params{dbfile} eq 'SL::DB::File'; + die 'no file contents' unless $params{file_path} || $params{file_contents}; + + my $dbfile = delete $params{dbfile}; + + # Do not save and do not create a new version of the document if file size of last version is the same. + if ($dbfile->source eq 'created' && $self->get_version_count(dbfile => $dbfile)) { + my $new_file_size = $params{file_path} ? stat($params{file_path})->size : length($params{file_contents}); + my $last_file_size = stat($self->_filesystem_path($dbfile))->size; + + return 1 if $last_file_size == $new_file_size; + } + + my @versions = @{$dbfile->file_versions_sorted}; + my $new_version_number = scalar @versions ? $versions[-1]->version + 1 : 1; + + my $tofile = $self->_filesystem_path($dbfile, $new_version_number); if ($params{file_path} && -f $params{file_path}) { File::Copy::copy($params{file_path}, $tofile); - } - elsif ($params{file_contents}) { + } elsif ($params{file_contents}) { open(OUT, "> " . $tofile); print OUT $params{file_contents}; close(OUT); } + + # save file version + my $doc_path = $::lx_office_conf{paths}->{document_path}; + my $rel_file = $tofile; + $rel_file =~ s/$doc_path//; + my $fv = SL::DB::FileVersion->new( + file_id => $dbfile->id, + version => $new_version_number, + file_location => $rel_file, + doc_path => $doc_path, + backend => 'Filesystem', + guid => create_uuid_as_string(UUID_V4), + )->save; + + if ($params{mtime}) { + utime($params{mtime}, $params{mtime}, $tofile); + } return 1; } sub get_version_count { my ($self, %params) = @_; die "no dbfile" unless $params{dbfile}; - return $params{dbfile}->backend_data * 1; + my $file_id = $params{dbfile}->id; + return 0 unless defined $file_id; + return SL::DB::Manager::FileVersion->get_all_count(where => [file_id => $file_id]); } sub get_mtime { my ($self, %params) = @_; - die "no dbfile" unless $params{dbfile}; - $main::lxdebug->message(LXDebug->DEBUG2(), "version=" .$params{version}); - die "unknown version" if $params{version} && - ($params{version} < 0 || $params{version} > $params{dbfile}->backend_data) ; - my $path = $self->_filesystem_path($params{dbfile},$params{version}); - die "no file found in backend" if !-f $path; - my @st = stat($path); - my $dt = DateTime->from_epoch(epoch => $st[9])->clone(); - $main::lxdebug->message(LXDebug->DEBUG2(), "dt=" .$dt); + my $path = $self->get_filepath(%params); + + my $dt = DateTime->from_epoch(epoch => stat($path)->mtime, time_zone => $::locale->get_local_time_zone()->name, locale => $::lx_office_conf{system}->{language})->clone(); return $dt; } @@ -99,7 +119,9 @@ sub get_filepath { my ($self, %params) = @_; die "no dbfile" unless $params{dbfile}; my $path = $self->_filesystem_path($params{dbfile},$params{version}); - die "no file" if !-f $path; + + die "No file found at $path. Expected: $params{dbfile}{file_name}, file.id: $params{dbfile}{id}" if !-f $path; + return $path; } @@ -112,12 +134,15 @@ sub get_content { } sub enabled { - return 0 unless $::instance_conf->get_doc_files || $::instance_conf->get_doc_files_rootpath; - $main::lxdebug->message(LXDebug->DEBUG2(), "root path=" . $::instance_conf->get_doc_files_rootpath . " isdir=" .( -d $::instance_conf->get_doc_files_rootpath?"YES":"NO")); - return 0 unless -d $::instance_conf->get_doc_files_rootpath; + return 0 unless $::instance_conf->get_doc_files; + return 0 unless $::lx_office_conf{paths}->{document_path}; + return 0 unless -d $::lx_office_conf{paths}->{document_path}; return 1; } +sub sync_from_backend { + die "Not implemented"; +} # # internals @@ -126,17 +151,22 @@ sub enabled { sub _filesystem_path { my ($self, $dbfile, $version) = @_; - die "No files backend enabled" unless $::instance_conf->get_doc_files || $::instance_conf->get_doc_files_rootpath; + die "No files backend enabled" unless $::instance_conf->get_doc_files || $::lx_office_conf{paths}->{document_path}; + + unless ($version) { + my $file_version = SL::DB::Manager::FileVersion->get_first( + where => [file_id => $dbfile->id], + sort_by => 'version DESC' + ) or die "Could not find a file version for file with id " . $dbfile->id; + $version = $file_version->version; + } # use filesystem with depth 3 - $version = $dbfile->backend_data if !$version || $version < 1 || $version > $dbfile->backend_data; my $iddir = sprintf("%04d", $dbfile->id % 1000); - my $path = File::Spec->catdir($::instance_conf->get_doc_files_rootpath, $iddir, $dbfile->id); - $main::lxdebug->message(LXDebug->DEBUG2(), "file path=" .$path." id=" .$dbfile->id." version=".$version." basename=".$dbfile->id . '_' . $version); + my $path = File::Spec->catdir($::lx_office_conf{paths}->{document_path}, $::auth->client->{id}, $iddir, $dbfile->id); if (!-d $path) { File::Path::make_path($path, { chmod => 0770 }); } - return $path if !$version; return File::Spec->catdir($path, $dbfile->id . '_' . $version); } @@ -181,5 +211,3 @@ L Martin Helmling Emartin.helmling@opendynamic.deE =cut - -