Projekt

Allgemein

Profil

Herunterladen (5,56 KB) Statistiken
| Zweig: | Markierung: | Revision:
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 = (
sales_quotation => 'angebote',
sales_order => 'bestellungen',
request_quotation => 'anfragen',
purchase_order => 'lieferantenbestellungen',
sales_delivery_order => 'verkaufslieferscheine',
purchase_delivery_order => 'einkaufslieferscheine',
credit_note => 'gutschriften',
invoice => 'rechnungen',
purchase_invoice => 'einkaufsrechnungen',
part => 'waren',
service => 'dienstleistungen',
assembly => 'erzeugnisse',
e80effa2 Moritz Bunkus
letter => 'briefe',
b166ba3b Jan Büren
general_ledger => 'dialogbuchungen',
9d0aef99 Jan Büren
accounts_payable => 'kreditorenbuchungen',
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