kivitendo/SL/Webdav.pm @ 7b1da9c3
dc6d8231 | Sven Schöling | package SL::Webdav;
|
||
use strict;
|
||||
use parent qw(Rose::Object);
|
||||
use Encode qw(decode);
|
||||
use File::Spec;
|
||||
use SL::Common;
|
||||
use SL::Webdav::File;
|
||||
use SL::Webdav::Object;
|
||||
use SL::Webdav::VersionScheme::Serial;
|
||||
use SL::Webdav::VersionScheme::Timestamp;
|
||||
use Rose::Object::MakeMethods::Generic (
|
||||
scalar => [ qw(type number) ],
|
||||
'scalar --get_set_init' => [ qw(version_scheme) ],
|
||||
);
|
||||
my %type_to_path = (
|
||||
7202756a | Bernd Bleßmann | sales_quotation => 'angebote',
|
||
4479a147 | Bernd Bleßmann | sales_order_intake => 'auftragseingaenge',
|
||
7202756a | Bernd Bleßmann | sales_order => 'bestellungen',
|
||
request_quotation => 'anfragen',
|
||||
aed1f6f0 | Bernd Bleßmann | purchase_quotation_intake => 'angebotseingaenge',
|
||
7202756a | Bernd Bleßmann | purchase_order => 'lieferantenbestellungen',
|
||
3c207d41 | Bernd Bleßmann | purchase_order_confirmation => 'lieferantenauftragsbestaetigungen',
|
||
7202756a | Bernd Bleßmann | sales_delivery_order => 'verkaufslieferscheine',
|
||
purchase_delivery_order => 'einkaufslieferscheine',
|
||||
6f28dbb7 | Sven Schöling | supplier_delivery_order => 'beistelllieferscheine',
|
||
rma_delivery_order => 'retourenlieferscheine',
|
||||
dd9a78c5 | Tamino Steinert | purchase_reclamation => 'einkaufsreklamation',
|
||
sales_reclamation => 'verkaufsreklamation',
|
||||
7202756a | Bernd Bleßmann | credit_note => 'gutschriften',
|
||
invoice => 'rechnungen',
|
||||
3f9da67b | Bernd Bleßmann | invoice_for_advance_payment => 'rechnungen',
|
||
7202756a | Bernd Bleßmann | final_invoice => 'rechnungen',
|
||
purchase_invoice => 'einkaufsrechnungen',
|
||||
part => 'waren',
|
||||
service => 'dienstleistungen',
|
||||
assembly => 'erzeugnisse',
|
||||
letter => 'briefe',
|
||||
general_ledger => 'dialogbuchungen',
|
||||
accounts_payable => 'kreditorenbuchungen',
|
||||
customer => 'kunden',
|
||||
vendor => 'lieferanten',
|
||||
dunning => 'mahnungen',
|
||||
dc6d8231 | Sven Schöling | );
|
||
sub get_all_files {
|
||||
my ($self) = @_;
|
||||
my @objects = $self->get_all_objects;
|
||||
my %files_by_name;
|
||||
for my $obj (@objects) {
|
||||
my $filename = join '.', grep $_, $obj->basename, $obj->extension;
|
||||
my $file = $files_by_name{$filename} ||= SL::Webdav::File->new(filename => $filename, webdav => $self, loaded => 1);
|
||||
$file->add_objects($obj);
|
||||
}
|
||||
return values %files_by_name;
|
||||
}
|
||||
sub get_all_objects {
|
||||
my ($self) = @_;
|
||||
my $path = $self->webdav_path;
|
||||
my @objects;
|
||||
my $base_path = $ENV{'SCRIPT_NAME'};
|
||||
$base_path =~ s|[^/]+$||;
|
||||
if (opendir my $dir, $path) {
|
||||
foreach my $file (sort { lc $a cmp lc $b } map { decode("UTF-8", $_) } readdir $dir) {
|
||||
next if (($file eq '.') || ($file eq '..'));
|
||||
my $fname = $file;
|
||||
$fname =~ s|.*/||;
|
||||
push @objects, SL::Webdav::Object->new(filename => $fname, webdav => $self);
|
||||
}
|
||||
closedir $dir;
|
||||
return @objects;
|
||||
}
|
||||
}
|
||||
sub get_all_latest {
|
||||
my ($self) = @_;
|
||||
my @files = $self->get_all_files;
|
||||
map { ($_->versions)[-1] } @files;
|
||||
}
|
||||
sub _sanitized_number {
|
||||
my $number = $_[0]->number;
|
||||
$number =~ s|[/\\]|_|g;
|
||||
$number;
|
||||
}
|
||||
sub webdav_path {
|
||||
my ($self) = @_;
|
||||
die "No client set in \$::auth" unless $::auth->client;
|
||||
die "Need number" unless $self->number;
|
||||
my $type = $type_to_path{$self->type};
|
||||
die "Unknown type" unless $type;
|
||||
my $path = File::Spec->catdir("webdav", $::auth->client->{id}, $type, $self->_sanitized_number);
|
||||
if (!-d $path) {
|
||||
Common::mkdir_with_parents($path);
|
||||
}
|
||||
return $path;
|
||||
}
|
||||
sub init_version_scheme {
|
||||
SL::Webdav::VersionScheme::Timestamp->new;
|
||||
}
|
||||
1;
|
||||
__END__
|
||||
=encoding utf-8
|
||||
=head1 NAME
|
||||
SL::Webdav - Webdav manipulation
|
||||
=head1 SYNOPSIS
|
||||
# get list of all documents for this record
|
||||
use SL::Webdav;
|
||||
my $webdav = SL::Webdav->new(
|
||||
type => 'part',
|
||||
number => $number,
|
||||
);
|
||||
# gives you SL::Webdav::File instances
|
||||
my $webdav_files = $webdav->get_all_files;
|
||||
# gives you the objects instead
|
||||
my $webdav_objects = $webdav->get_all_objects;
|
||||
# gives you only the latest objects
|
||||
my $webdav_objects = $webdav->get_all_latest;
|
||||
# physical path to this dir
|
||||
my $path = $webdav->webdav_path;
|
||||
=head1 DESCRIPTION
|
||||
This module is a wrapper around the webdav storage mechanism with some simple
|
||||
document management functionality.
|
||||
This is not a replacement for real document management, mostly because the
|
||||
854eeca8 | Geoffrey Richardson | underlying webdav storage is not fully under our control. It's common practice
|
||
dc6d8231 | Sven Schöling | to allow people direct samba access to the webdav, so all versioning
|
||
854eeca8 | Geoffrey Richardson | information needs to be encoded into the filename of a file, and nonsensical
|
||
dc6d8231 | Sven Schöling | filenames must not break assumptions.
|
||
This module is intended to be used if you need to scan the folder for
|
||||
854eeca8 | Geoffrey Richardson | previously saved files and need to build a list in order to display it.
|
||
dc6d8231 | Sven Schöling | |||
If you need to manipulate the versions of a file, see L<SL::Webdav::File>
|
||||
If you need to access a file directly for download or metadata, see L<SL::Webdav::Object>
|
||||
=head1 FUNCTIONS
|
||||
=over 4
|
||||
=item C<get_all_objects>
|
||||
Returns all L<SL::Webdav::Objects> found.
|
||||
=item C<get_all_files>
|
||||
Returns all objects sorted into L<SL::Webdav::File>s.
|
||||
=item C<get_all_latest>
|
||||
Returns only the latest object of each L<SL::Webdav::File> found.
|
||||
=item C<webdav_path>
|
||||
Returns the physical path to this webdav object.
|
||||
=back
|
||||
=head1 VERSIONING SCHEME
|
||||
854eeca8 | Geoffrey Richardson | You may register a versioning scheme object to handle versioning. It is
|
||
dc6d8231 | Sven Schöling | expected to implement the following methods:
|
||
=over 4
|
||||
=item C<separator>
|
||||
854eeca8 | Geoffrey Richardson | Must return a string that will be used to separate the basename and version part of
|
||
filenames when generating and parsing.
|
||||
dc6d8231 | Sven Schöling | |||
=item C<extract_regexp>
|
||||
Must return a regexp that will match a versioning string at the end of a
|
||||
filename after the extension has been stripped off. It will be surrounded by
|
||||
captures.
|
||||
=item C<cmp>
|
||||
Must return a comparison function that will be invoked with two
|
||||
L<SL::Webdav::Object> instances.
|
||||
=item C<first_version>
|
||||
Must return a string representing the version of the first of a series of objects.
|
||||
May return undef.
|
||||
=item C<next_version>
|
||||
Will be called with the latest L<SL::Webdav::Object> and must return a new version string.
|
||||
=item C<keep_last_version>
|
||||
Will be called with the latest L<SL::Webdav::Object>. Truish return value will
|
||||
cause the latest object to be overwritten instead of creating a new version.
|
||||
=back
|
||||
=head1 BUGS AND CAVEATS
|
||||
=over 4
|
||||
=item *
|
||||
File operations are inconsistently L<File::Spec>ed.
|
||||
=back
|
||||
=head1 SEE ALSO
|
||||
L<SL::Webdav::File>, L<SL::Webdav::Object>
|
||||
=head1 AUTHOR
|
||||
Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>
|
||||
=cut
|