Revision bef56e29
Von Tamino Steinert vor 8 Monaten hinzugefügt
SL/File.pm | ||
---|---|---|
72 | 72 |
@fileobjs = $self->get_all(%params); |
73 | 73 |
} |
74 | 74 |
foreach my $fileobj (@fileobjs) { |
75 |
$main::lxdebug->message(LXDebug->DEBUG2(), "obj=" . $fileobj . " id=" . $fileobj->id." versions=".$fileobj->version_count);
|
|
76 |
my $maxversion = $fileobj->version_count;
|
|
77 |
$fileobj->version($maxversion);
|
|
75 |
my @file_versions = reverse @{$fileobj->loaded_db_file->file_versions_sorted};
|
|
76 |
my $latest_file_version = shift @file_versions;
|
|
77 |
$fileobj->version($latest_file_version->version);
|
|
78 | 78 |
push @versionobjs, $fileobj; |
79 |
if ($maxversion > 1) { |
|
80 |
for my $version (2..$maxversion) { |
|
81 |
$main::lxdebug->message(LXDebug->DEBUG2(), "clone for version=".($maxversion-$version+1)); |
|
82 |
eval { |
|
83 |
my $clone = $fileobj->clone; |
|
84 |
$clone->version($maxversion-$version+1); |
|
85 |
$clone->newest(0); |
|
86 |
$main::lxdebug->message(LXDebug->DEBUG2(), "clone version=".$clone->version." mtime=". $clone->mtime); |
|
87 |
push @versionobjs, $clone; |
|
88 |
1; |
|
89 |
} or do {$::lxdebug->message(LXDebug::WARN(), "clone for version=".($maxversion-$version+1) . "failed: " . $@)}; |
|
90 |
} |
|
79 |
foreach my $file_version (@file_versions) { |
|
80 |
my $clone = $fileobj->clone; |
|
81 |
$clone->version($file_version->version); |
|
82 |
$clone->newest(0); |
|
83 |
push @versionobjs, $clone; |
|
91 | 84 |
} |
92 | 85 |
} |
93 | 86 |
return @versionobjs; |
SL/File/Backend/Filesystem.pm | ||
---|---|---|
6 | 6 |
use SL::DB::File; |
7 | 7 |
use SL::DB::FileVersion; |
8 | 8 |
|
9 |
use Carp; |
|
10 |
use List::Util qw(first); |
|
11 |
|
|
9 | 12 |
use File::Copy; |
10 | 13 |
use File::Slurp; |
11 | 14 |
use File::stat; |
... | ... | |
19 | 22 |
sub delete { |
20 | 23 |
my ($self, %params) = @_; |
21 | 24 |
die "no dbfile in backend delete" unless $params{dbfile}; |
22 |
my $last_version = $params{dbfile}->backend_data; |
|
23 |
my $first_version = 1; |
|
24 |
$last_version = 0 if $params{last}; |
|
25 |
$last_version = $params{dbfile}->backend_data-1 if $params{all_but_notlast}; |
|
26 |
$last_version = $params{version} if $params{version}; |
|
27 |
$first_version = $params{version} if $params{version}; |
|
28 |
|
|
29 |
if ($last_version > 0 ) { |
|
30 |
for my $version ( $first_version..$last_version) { |
|
31 |
my $file_path = $self->_filesystem_path($params{dbfile},$version); |
|
32 |
unlink($file_path); |
|
33 |
} |
|
34 |
if ($params{version}) { |
|
35 |
for my $version ( $last_version+1 .. $params{dbfile}->backend_data) { |
|
36 |
my $from = $self->_filesystem_path($params{dbfile},$version); |
|
37 |
my $to = $self->_filesystem_path($params{dbfile},$version - 1); |
|
38 |
die "file not exists in backend delete" unless -f $from; |
|
39 |
rename($from,$to); |
|
40 |
} |
|
41 |
$params{dbfile}->backend_data($params{dbfile}->backend_data-1); |
|
42 |
} |
|
43 |
elsif ($params{all_but_notlast}) { |
|
44 |
my $from = $self->_filesystem_path($params{dbfile},$params{dbfile}->backend_data); |
|
45 |
my $to = $self->_filesystem_path($params{dbfile},1); |
|
46 |
die "file not exists in backend delete" unless -f $from; |
|
47 |
rename($from,$to); |
|
48 |
$params{dbfile}->backend_data(1); |
|
49 |
} else { |
|
50 |
$params{dbfile}->backend_data(0); |
|
51 |
} |
|
52 |
unless ($params{dbfile}->backend_data) { |
|
53 |
my $dir_path = $self->_filesystem_path($params{dbfile}); |
|
54 |
rmdir($dir_path); |
|
55 |
} |
|
25 |
my @versions = @{$params{dbfile}->file_versions_sorted}; |
|
26 |
|
|
27 |
my @versions_to_delete; |
|
28 |
if ($params{last}) { |
|
29 |
my $last = pop @versions; |
|
30 |
@versions_to_delete = ($last); |
|
31 |
} elsif ($params{all_but_notlast}) { |
|
32 |
pop @versions; # remove last |
|
33 |
@versions_to_delete = @versions; |
|
34 |
} elsif ($params{version}) { |
|
35 |
my $version = first {$_->version == $params{version}} @versions |
|
36 |
or confess "Version not found."; |
|
37 |
@versions_to_delete = ($version); |
|
56 | 38 |
} else { |
57 |
my $file_path = $self->_filesystem_path($params{dbfile},$params{dbfile}->backend_data); |
|
58 |
die "file not exists in backend delete" unless -f $file_path; |
|
59 |
unlink($file_path); |
|
60 |
$params{dbfile}->backend_data($params{dbfile}->backend_data-1); |
|
39 |
@versions_to_delete = @versions; |
|
61 | 40 |
} |
62 |
return 1; |
|
63 |
} |
|
64 | 41 |
|
65 |
sub rename { |
|
42 |
foreach my $version (@versions_to_delete) { |
|
43 |
unlink($version->get_system_location()); |
|
44 |
$version->delete; |
|
45 |
} |
|
46 |
|
|
47 |
return 1; |
|
66 | 48 |
} |
67 | 49 |
|
68 | 50 |
sub save { |
... | ... | |
81 | 63 |
return 1 if $last_file_size == $new_file_size; |
82 | 64 |
} |
83 | 65 |
|
84 |
$dbfile->backend_data(0) unless $dbfile->backend_data; |
|
85 |
$dbfile->backend_data($dbfile->backend_data*1+1); |
|
86 |
$dbfile->save->load; |
|
66 |
my @versions = @{$dbfile->file_versions_sorted}; |
|
67 |
my $new_version_number = scalar @versions ? $versions[-1]->version + 1 : 1; |
|
87 | 68 |
|
88 |
my $tofile = $self->_filesystem_path($dbfile); |
|
69 |
my $tofile = $self->_filesystem_path($dbfile, $new_version_number);
|
|
89 | 70 |
if ($params{file_path} && -f $params{file_path}) { |
90 | 71 |
File::Copy::copy($params{file_path}, $tofile); |
91 | 72 |
} elsif ($params{file_contents}) { |
... | ... | |
100 | 81 |
$rel_file =~ s/$doc_path//; |
101 | 82 |
my $fv = SL::DB::FileVersion->new( |
102 | 83 |
file_id => $dbfile->id, |
103 |
version => $dbfile->backend_data,
|
|
84 |
version => $new_version_number,
|
|
104 | 85 |
file_location => $rel_file, |
105 | 86 |
doc_path => $doc_path, |
106 | 87 |
backend => 'Filesystem', |
... | ... | |
116 | 97 |
sub get_version_count { |
117 | 98 |
my ($self, %params) = @_; |
118 | 99 |
die "no dbfile" unless $params{dbfile}; |
119 |
return $params{dbfile}->backend_data//0 * 1; |
|
100 |
my $file_id = $params{dbfile}->id; |
|
101 |
return 0 unless defined $file_id; |
|
102 |
return SL::DB::Manager::FileVersion->get_all_count(where => [file_id => $file_id]); |
|
120 | 103 |
} |
121 | 104 |
|
122 | 105 |
sub get_mtime { |
123 | 106 |
my ($self, %params) = @_; |
124 |
die "no dbfile" unless $params{dbfile}; |
|
125 |
die "unknown version" if $params{version} && |
|
126 |
($params{version} < 0 || $params{version} > $params{dbfile}->backend_data); |
|
127 |
my $path = $self->_filesystem_path($params{dbfile}, $params{version}); |
|
128 |
|
|
129 |
die "No file found at $path. Expected: $params{dbfile}{file_name}, file.id: $params{dbfile}{id}" if !-f $path; |
|
107 |
my $path = $self->get_filepath(%params); |
|
130 | 108 |
|
131 | 109 |
my $dt = DateTime->from_epoch(epoch => stat($path)->mtime, time_zone => $::locale->get_local_time_zone()->name, locale => $::lx_office_conf{system}->{language})->clone(); |
132 | 110 |
return $dt; |
... | ... | |
158 | 136 |
} |
159 | 137 |
|
160 | 138 |
sub sync_from_backend { |
161 |
my ($self, %params) = @_; |
|
162 |
my @query = (file_type => $params{file_type}); |
|
163 |
push @query, (file_name => $params{file_name}) if $params{file_name}; |
|
164 |
push @query, (mime_type => $params{mime_type}) if $params{mime_type}; |
|
165 |
push @query, (source => $params{source}) if $params{source}; |
|
166 |
|
|
167 |
my $sortby = $params{sort_by} || 'itime DESC,file_name ASC'; |
|
168 |
|
|
169 |
my @files = @{ SL::DB::Manager::File->get_all(query => [@query], sort_by => $sortby) }; |
|
170 |
for (@files) { |
|
171 |
$main::lxdebug->message(LXDebug->DEBUG2(), "file id=" . $_->id." version=".$_->backend_data); |
|
172 |
my $newversion = $_->backend_data; |
|
173 |
for my $version ( reverse 1 .. $_->backend_data ) { |
|
174 |
my $path = $self->_filesystem_path($_, $version); |
|
175 |
$main::lxdebug->message(LXDebug->DEBUG2(), "path=".$path." exists=".( -f $path?1:0)); |
|
176 |
last if -f $path; |
|
177 |
$newversion = $version - 1; |
|
178 |
} |
|
179 |
$main::lxdebug->message(LXDebug->DEBUG2(), "newversion=".$newversion." version=".$_->backend_data); |
|
180 |
if ( $newversion < $_->backend_data ) { |
|
181 |
$_->backend_data($newversion); |
|
182 |
$_->save if $newversion > 0; |
|
183 |
$_->delete if $newversion <= 0; |
|
184 |
} |
|
185 |
} |
|
186 |
|
|
139 |
die "Not implemented"; |
|
187 | 140 |
} |
188 | 141 |
|
189 | 142 |
# |
... | ... | |
196 | 149 |
die "No files backend enabled" unless $::instance_conf->get_doc_files || $::lx_office_conf{paths}->{document_path}; |
197 | 150 |
|
198 | 151 |
# use filesystem with depth 3 |
199 |
$version = $dbfile->backend_data if !$version || $version < 1 || $version > $dbfile->backend_data; |
|
152 |
$version ||= $dbfile->file_versions_sorted->[-1]->version; |
|
153 |
confess "Version is required." unless $version; |
|
200 | 154 |
my $iddir = sprintf("%04d", $dbfile->id % 1000); |
201 | 155 |
my $path = File::Spec->catdir($::lx_office_conf{paths}->{document_path}, $::auth->client->{id}, $iddir, $dbfile->id); |
202 | 156 |
if (!-d $path) { |
203 | 157 |
File::Path::make_path($path, { chmod => 0770 }); |
204 | 158 |
} |
205 |
return $path if !$version; |
|
206 | 159 |
return File::Spec->catdir($path, $dbfile->id . '_' . $version); |
207 | 160 |
} |
208 | 161 |
|
locale/de/all | ||
---|---|---|
868 | 868 |
'Could not spawn ghostscript.' => 'Die Anwendung "ghostscript" konnte nicht gestartet werden.', |
869 | 869 |
'Could not spawn the printer command.' => 'Die Druckanwendung konnte nicht gestartet werden.', |
870 | 870 |
'Could not update prices!' => 'Preise konnten nicht aktualisiert werden!', |
871 |
'Count' => 'Anzahl', |
|
871 | 872 |
'Country' => 'Land', |
872 | 873 |
'Country (Shipping)' => 'Land (Lieferung)', |
873 | 874 |
'Create' => 'Anlegen', |
locale/en/all | ||
---|---|---|
868 | 868 |
'Could not spawn ghostscript.' => '', |
869 | 869 |
'Could not spawn the printer command.' => '', |
870 | 870 |
'Could not update prices!' => '', |
871 |
'Count' => '', |
|
871 | 872 |
'Country' => '', |
872 | 873 |
'Country (Shipping)' => '', |
873 | 874 |
'Create' => '', |
sql/Pg-upgrade2/add_file_version.pl | ||
---|---|---|
15 | 15 |
|
16 | 16 |
use parent qw(SL::DBUpgrade2::Base); |
17 | 17 |
|
18 |
sub get_all_versions { |
|
19 |
my ($fileobj) = @_; |
|
20 |
|
|
21 |
my @versionobjs; |
|
22 |
|
|
23 |
my $maxversion = $fileobj->version_count; |
|
24 |
$fileobj->version($maxversion); |
|
25 |
push @versionobjs, $fileobj; |
|
26 |
if ($maxversion > 1) { |
|
27 |
for my $version (2..$maxversion) { |
|
28 |
my $clone = $fileobj->clone; |
|
29 |
$clone->version($maxversion-$version+1); |
|
30 |
$clone->newest(0); |
|
31 |
push @versionobjs, $clone; |
|
32 |
} |
|
33 |
} |
|
34 |
} |
|
35 |
|
|
18 | 36 |
sub run { |
19 | 37 |
my ($self) = @_; |
20 | 38 |
|
... | ... | |
35 | 53 |
die "Unknown backend '$backend' for file with ID '$file_id'."; |
36 | 54 |
} |
37 | 55 |
|
38 |
my @versions = SL::File->get_all_versions(dbfile => $dbfile);
|
|
56 |
my @versions = get_all_versions($dbfile);
|
|
39 | 57 |
foreach my $version (@versions) { |
40 | 58 |
my $tofile; |
41 | 59 |
eval { |
... | ... | |
53 | 71 |
|
54 | 72 |
my $fv = SL::DB::FileVersion->new( |
55 | 73 |
file_id => $dbfile->id, |
56 |
version => $version->version, |
|
74 |
version => $version->version || 1,
|
|
57 | 75 |
file_location => $rel_file, |
58 | 76 |
doc_path => $doc_path, |
59 | 77 |
backend => $dbfile->backend, |
templates/design40_webpages/file/list.html | ||
---|---|---|
32 | 32 |
</th> |
33 | 33 |
<th>[% source.chkall_title %]</th> |
34 | 34 |
[% END %] |
35 |
<th>[% LxERP.t8('Version') %]</th> |
|
35 |
<th>[% LxERP.t8('Version') _ ' (' _ LxERP.t8('Count') _ ')' %]</th>
|
|
36 | 36 |
<th>[% LxERP.t8('Date') %]</th> |
37 | 37 |
<th>[% source.file_title %]</th> |
38 | 38 |
[% IF file_type == 'image' %] |
... | ... | |
59 | 59 |
[% END %] |
60 | 60 |
<td class="right[%- IF file.version_count > 1 && !is_other_version %] cursor-pointer" onclick="kivi.File.toggle_versions('[% file.id %]')"[%- ELSE -%]"[%- END %]>[%#"%] |
61 | 61 |
[%- IF file.version_count > 1 && !is_other_version %]<span id="[% 'version_toggle_' _ file.id %]">⏷ </span>[% END %] |
62 |
[% file.version _ '/' _ file.version_count %]
|
|
62 |
[% file.version _ ' (' _ file.version_count _ ')' %]
|
|
63 | 63 |
[% L.hidden_tag("version[]", file.version) %] |
64 | 64 |
</td> |
65 | 65 |
<td>[% file.mtime_as_timestamp_s %]</td> |
templates/webpages/file/list.html | ||
---|---|---|
29 | 29 |
<th class="listheading" width="3%">[% L.checkbox_tag(checkname _ '_checkall') %]</th> |
30 | 30 |
<th class="listheading" width="7%">[% source.chkall_title %]</th> |
31 | 31 |
[%- END %] |
32 |
<th class="listheading" width="2%"><b>[% LxERP.t8('Version') %]</b></th> |
|
32 |
<th class="listheading" width="2%"><b>[% LxERP.t8('Version') _ ' (' _ LxERP.t8('Count') _ ')' %]</b></th>
|
|
33 | 33 |
<th class="listheading" width="15%"><b>[% LxERP.t8('Date') %]</b></th> |
34 | 34 |
<th class="listheading" width="20%"><b>[% source.file_title %]</b></th> |
35 | 35 |
[%- IF file_type == 'image' %] |
... | ... | |
60 | 60 |
[%- END %] |
61 | 61 |
<td align="right" [%- IF file.version_count > 1 && !is_other_version %] class="cursor-pointer" onclick="kivi.File.toggle_versions('[% file.id %]')"[%- END %]> |
62 | 62 |
[%- IF file.version_count > 1 && !is_other_version %]<span id="[% 'version_toggle_' _ file.id %]">⏷ </span>[% END %] |
63 |
[% file.version _ '/' _ file.version_count %]
|
|
63 |
[% file.version _ ' (' _ file.version_count _ ')' %]
|
|
64 | 64 |
[% L.hidden_tag("version[]", file.version) %] |
65 | 65 |
</td> |
66 | 66 |
<td>[% file.mtime_as_timestamp_s %]</td> |
Auch abrufbar als: Unified diff
SL::File: Versionsnummber über file_version bestimmen