|  | package SL::Webdav::File;
 | 
  
    |  | 
 | 
  
    |  | use strict;
 | 
  
    |  | use parent qw(Rose::Object);
 | 
  
    |  | 
 | 
  
    |  | use File::Spec;
 | 
  
    |  | use File::Copy ();
 | 
  
    |  | use Carp;
 | 
  
    |  | 
 | 
  
    |  | use Rose::Object::MakeMethods::Generic (
 | 
  
    |  |   scalar => [ qw(webdav filename loaded) ],
 | 
  
    |  |   array  => [
 | 
  
    |  |     qw(objects),
 | 
  
    |  |     add_objects => { interface => 'push', hash_key => 'objects' },
 | 
  
    |  |   ],
 | 
  
    |  | );
 | 
  
    |  | 
 | 
  
    |  | sub versions {
 | 
  
    |  |   $_[0]->load unless $_[0]->loaded;
 | 
  
    |  |   my $cmp = $_[0]->webdav->version_scheme->cmp;
 | 
  
    |  |   sort { $cmp->($a, $b) } $_[0]->objects;
 | 
  
    |  | }
 | 
  
    |  | 
 | 
  
    |  | sub latest_version {
 | 
  
    |  |   ($_[0]->versions)[-1]
 | 
  
    |  | }
 | 
  
    |  | 
 | 
  
    |  | sub load {
 | 
  
    |  |   my ($self) = @_;
 | 
  
    |  |   my @objects = $self->webdav->get_all_objects;
 | 
  
    |  |   my $ref = SL::Webdav::Object->new(filename => $self->filename, webdav => $self->webdav);
 | 
  
    |  |   my ($ref_basename, undef, $ref_extension) = $ref->parse_filename;
 | 
  
    |  | 
 | 
  
    |  |   $self->objects(grep { $_->basename eq $ref_basename && $_->extension eq $ref_extension } @objects);
 | 
  
    |  |   $self->loaded(1);
 | 
  
    |  | }
 | 
  
    |  | 
 | 
  
    |  | sub store {
 | 
  
    |  |   my ($self, %params) = @_;
 | 
  
    |  | 
 | 
  
    |  |   croak 'Invalid call. Only data or file can be set' if ($params{data} && $params{file});
 | 
  
    |  | 
 | 
  
    |  |   $self->load unless $self->loaded;
 | 
  
    |  | 
 | 
  
    |  |   my $last = $self->latest_version;
 | 
  
    |  |   my $object;
 | 
  
    |  | 
 | 
  
    |  |   if (!$last) {
 | 
  
    |  |     my ($basename, undef, $extension) = SL::Webdav::Object->new(filename => $self->filename, webdav => $self->webdav)->parse_filename;
 | 
  
    |  |     my $new_version  = $self->webdav->version_scheme->first_version;
 | 
  
    |  |     my $sep          = $self->webdav->version_scheme->separator;
 | 
  
    |  |     my $new_filename = $basename . $sep . $new_version . "." . $extension;
 | 
  
    |  |     $object = SL::Webdav::Object->new(filename => $new_filename, webdav => $self->webdav);
 | 
  
    |  | 
 | 
  
    |  |     $self->add_objects($object);
 | 
  
    |  |   } else {
 | 
  
    |  |     if (!$self->webdav->version_scheme->keep_last_version($last)) {
 | 
  
    |  |       $params{new_version} = 1;
 | 
  
    |  |     }
 | 
  
    |  | 
 | 
  
    |  |     # Do not create a new version of the document if file size of last version is the same.
 | 
  
    |  |     if ($params{new_version}) {
 | 
  
    |  |       my $last_file_size = $last->size;
 | 
  
    |  |       my $new_file_size;
 | 
  
    |  |       if ($params{file}) {
 | 
  
    |  |         croak 'No valid file' unless -f $params{file};
 | 
  
    |  |         $new_file_size  = (stat($params{file}))[7];
 | 
  
    |  |       } else {
 | 
  
    |  |         $new_file_size  = length(${ $params{data} });
 | 
  
    |  |       }
 | 
  
    |  |       $params{new_version} = 0 if $last_file_size == $new_file_size;
 | 
  
    |  |     }
 | 
  
    |  | 
 | 
  
    |  |     if ($params{new_version}) {
 | 
  
    |  |       my $new_version  = $self->webdav->version_scheme->next_version($last);
 | 
  
    |  |       my $sep          = $self->webdav->version_scheme->separator;
 | 
  
    |  |       my $new_filename = $last->basename . $sep . $new_version . "." . $last->extension;
 | 
  
    |  |       $object = SL::Webdav::Object->new(filename => $new_filename, webdav => $self->webdav);
 | 
  
    |  | 
 | 
  
    |  |       $self->add_objects($object);
 | 
  
    |  |     } else {
 | 
  
    |  |       $object = $last;
 | 
  
    |  |     }
 | 
  
    |  |   }
 | 
  
    |  | 
 | 
  
    |  |   if ($params{file}) {
 | 
  
    |  |     croak 'No valid file' unless -f $params{file};
 | 
  
    |  |     File::Copy::copy($params{file}, $object->full_filedescriptor) or croak "Copy failed from $params{file} to @{[ $object->filename ]}: $!";
 | 
  
    |  |   } else {
 | 
  
    |  | 
 | 
  
    |  |     open my $fh, '>:raw', $object->full_filedescriptor or die "could not open " . $object->filename . ": $!";
 | 
  
    |  | 
 | 
  
    |  |     $fh->print(${ $params{data} });
 | 
  
    |  | 
 | 
  
    |  |     close $fh;
 | 
  
    |  |   }
 | 
  
    |  | 
 | 
  
    |  | 
 | 
  
    |  |   return $object;
 | 
  
    |  | }
 | 
  
    |  | 
 | 
  
    |  | 1;
 | 
  
    |  | 
 | 
  
    |  | __END__
 | 
  
    |  | 
 | 
  
    |  | =encoding utf-8
 | 
  
    |  | 
 | 
  
    |  | =head1 NAME
 | 
  
    |  | 
 | 
  
    |  | SL::Webdav::File - Webdav file manipulation
 | 
  
    |  | 
 | 
  
    |  | =head1 SYNOPSIS
 | 
  
    |  | 
 | 
  
    |  |   use SL::Webdav::File;
 | 
  
    |  | 
 | 
  
    |  |   my $webdav_file = SL::Webdav::File->new(
 | 
  
    |  |     webdav   => $webdav,  # SL::Webdav instance
 | 
  
    |  |     filename => 'technical_drawing_AB28375.pdf',
 | 
  
    |  |   );
 | 
  
    |  | 
 | 
  
    |  |   # get existing versioned files
 | 
  
    |  |   my @webdav_objects = $webdav_file->versions;
 | 
  
    |  | 
 | 
  
    |  |   # store new version
 | 
  
    |  |   my $data = SL::Helper::CreatePDF->create_pdf(...);
 | 
  
    |  |   my $webdav_object = $webdav_file->store(data => \$data);
 | 
  
    |  | 
 | 
  
    |  |   # use file instead of data
 | 
  
    |  |   my $webdav_object = $webdav_file->store(file => $path_to_file);
 | 
  
    |  | 
 | 
  
    |  |   # force new version
 | 
  
    |  |   my $webdav_object = $webdav_file->store(data => \$data, new_version => 1);
 | 
  
    |  | 
 | 
  
    |  | =head1 DESCRIPTION
 | 
  
    |  | 
 | 
  
    |  | A file in this context is the collection of all versions of a single file saved
 | 
  
    |  | into the webdav. This module provides methods to access and manipulate these
 | 
  
    |  | objects.
 | 
  
    |  | 
 | 
  
    |  | =head1 FUNCTIONS
 | 
  
    |  | 
 | 
  
    |  | =over 4
 | 
  
    |  | 
 | 
  
    |  | =item C<versions>
 | 
  
    |  | 
 | 
  
    |  | Will return all L<SL::Webdav::Object>s found in this file, sorted by version
 | 
  
    |  | according to the version scheme used.
 | 
  
    |  | 
 | 
  
    |  | =item C<latest_version>
 | 
  
    |  | 
 | 
  
    |  | Returns only the latest version object.
 | 
  
    |  | 
 | 
  
    |  | =item C<load>
 | 
  
    |  | 
 | 
  
    |  | Loads objects from disk.
 | 
  
    |  | 
 | 
  
    |  | =item C<store PARAMS>
 | 
  
    |  | 
 | 
  
    |  | Store a new version on disk. If C<data> is present, it is expected to contain a
 | 
  
    |  | reference to the data to be written in raw encoding.
 | 
  
    |  | 
 | 
  
    |  | If C<file> is a valid filename then it will be copied.
 | 
  
    |  | 
 | 
  
    |  | C<file> and C<data> are exclusive.
 | 
  
    |  | 
 | 
  
    |  | If param C<new_version> is set, force a new version, even if the versioning
 | 
  
    |  | scheme would keep the old one.
 | 
  
    |  | 
 | 
  
    |  | No new version is stored if the file or data size is euqal to the size of
 | 
  
    |  | the last stored version.
 | 
  
    |  | 
 | 
  
    |  | =back
 | 
  
    |  | 
 | 
  
    |  | =head1 SEE ALSO
 | 
  
    |  | 
 | 
  
    |  | L<SL::Webdav>, L<SL::Webdav::Object>
 | 
  
    |  | 
 | 
  
    |  | =head1 BUGS
 | 
  
    |  | 
 | 
  
    |  | None yet :)
 | 
  
    |  | 
 | 
  
    |  | =head1 AUTHOR
 | 
  
    |  | 
 | 
  
    |  | Sven Schöling E<lt>s.schoeling@linet-services.deE<gt>
 | 
  
    |  | 
 | 
  
    |  | =cut
 |