Yukki

 view release on metacpan or  search on metacpan

lib/Yukki/Model/File.pm  view on Meta::CPAN


    my %args;
    if (@_ == 1) { %args = %{ $_[0] }; }
    else         { %args = @_; }

    if ($args{full_path}) {
        my $full_path = delete $args{full_path};

        my ($path, $filetype) = $full_path =~ m{^(.*)(?:\.(\w+))?$};

        $args{path}     = $path;
        $args{filetype} = $filetype;
    }

    return \%args;
}


sub full_path {
    my $self = shift;

    my $full_path;
    given ($self->filetype) {
        when (defined) { $full_path = join '.', $self->path, $self->filetype }
        default        { $full_path = $self->path }
    }

    return $full_path;
}


sub file_name {
    my $self = shift;
    my $full_path = $self->full_path;
    my ($file_name) = $full_path =~ m{([^/]+)$};
    return $file_name;
}


sub file_id {
    my $self = shift;
    return sha1_hex($self->file_name);
}


sub object_id {
    my $self = shift;
    return $self->find_path($self->full_path);
}


sub title {
    my $self = shift;

    if ($self->filetype eq 'yukki') {
        LINE: for my $line ($self->fetch) {
            if ($line =~ /^#\s*(.*)$/) {
                return $1;
            }
            elsif ($line =~ /:/) {
                my ($name, $value) = split m{\s*:\s*}, $line, 2;
                return $value if lc($name) eq 'title';
            }
            else {
                last LINE;
            }
        }
    }

    my $title = $self->file_name;
    $title =~ s/\.(\w+)$//g;
    return $title;
}


sub file_size {
    my $self = shift;
    return $self->fetch_size($self->full_path);
}


sub formatted_file_size {
    my $self = shift;
    return format_bytes($self->file_size);
}


sub media_type {
    my $self = shift;
    return guess_media_type($self->full_path);
}


sub store {
    my ($self, $params) = @_;
    my $path = $self->full_path;

    my (@parts) = split m{/}, $path;
    my $blob_name = $parts[-1];

    my $object_id;
    if ($params->{content}) {
        $object_id = $self->make_blob($blob_name, $params->{content});
    }
    elsif ($params->{filename}) {
        $object_id = $self->make_blob_from_file($blob_name, $params->{filename});
    }
    http_throw("unable to create blob for $path") unless $object_id;

    my $old_tree_id = $self->find_root;
    http_throw("unable to locate original tree ID for ".$self->branch)
        unless $old_tree_id;

    my $new_tree_id = $self->make_tree($old_tree_id, \@parts, $object_id);
    http_throw("unable to create the new tree containing $path\n")
        unless $new_tree_id;

    my $commit_id = $self->commit_tree($old_tree_id, $new_tree_id, $params->{comment});
    http_throw("unable to commit the new tree containing $path\n")
        unless $commit_id;

    $self->update_root($old_tree_id, $commit_id);
}


sub rename {
    my ($self, $params) = @_;
    my $old_path = $self->full_path;

    my (@new_parts) = split m{/}, $params->{full_path};
    my (@old_parts) = split m{/}, $old_path;
    my $blob_name = $old_parts[-1];

    my $object_id = $self->object_id;

    my $old_tree_id = $self->find_root;
    http_throw("unable to locate original tree ID for ".$self->branch)
        unless $old_tree_id;

    my $new_tree_id = $self->make_tree(
        $old_tree_id, \@old_parts, \@new_parts, $object_id);
    http_throw("unable to create the new tree renaming $old_path to $params->{full_path}\n")
        unless $new_tree_id;

    my $commit_id = $self->commit_tree($old_tree_id, $new_tree_id, $params->{comment});
    http_throw("unable to commit the new tree renaming $old_path to $params->{full_path}\n")
        unless $commit_id;

    $self->update_root($old_tree_id, $commit_id);

    return Yukki::Model::File->new(
        app        => $self->app,
        repository => $self->repository,
        full_path  => $params->{full_path},
    );
}


sub remove {
    my ($self, $params) = @_;
    my $old_path = $self->full_path;

    my (@old_parts) = split m{/}, $old_path;

    my $old_tree_id = $self->find_root;
    http_throw("unable to locate original tree ID for ".$self->branch)
        unless $old_tree_id;

    my $new_tree_id = $self->make_tree($old_tree_id, \@old_parts);
    http_throw("unable to create the new tree removing $old_path\n")
        unless $new_tree_id;

    my $commit_id = $self->commit_tree($old_tree_id, $new_tree_id, $params->{comment});
    http_throw("unable to commit the new tree removing $old_path\n")
        unless $commit_id;

    $self->update_root($old_tree_id, $commit_id);
}


sub exists {
    my $self = shift;

    my $path = $self->full_path;
    return $self->find_path($path);
}


sub fetch {
    my $self = shift;

    my $path = $self->full_path;
    my $object_id = $self->find_path($path);

    return unless defined $object_id;

    return $self->show($object_id);
}


sub has_format {
    my ($self, $media_type) = @_;
    $media_type //= $self->media_type;

    my @formatters = $self->app->formatter_plugins;
    for my $formatter (@formatters) {
        return 1 if $formatter->has_format($media_type);
    }

    return '';
}


sub fetch_formatted {
    my ($self, $ctx, $position) = @_;
    $position //= 0;

    my $media_type = $self->media_type;

    my $formatter;
    for my $plugin ($self->app->formatter_plugins) {
        return $plugin->format({
            context    => $ctx,
            file       => $self,
            position   => $position,
        }) if $plugin->has_format($media_type);
    }

    return $self->fetch;
}


sub history {
    my $self = shift;
    return $self->log($self->full_path);
}


sub diff {
    my ($self, $object_id_1, $object_id_2) = @_;
    return $self->diff_blobs($self->full_path, $object_id_1, $object_id_2);
}


sub file_preview {
    my ($self, %params) = @_;

    Class::Load::load_class('Yukki::Model::FilePreview');
    return Yukki::Model::FilePreview->new(
        %params,
        app        => $self->app,
        repository => $self->repository,
        path       => $self->path,
    );
}


sub list_files {
    my ($self) = @_;
    return $self->repository->list_files($self->path);
}


sub parent {
    my $self = shift;

    my @parts = split m{/}, $self->path;
    return if @parts == 1;

    pop @parts;
    return Yukki::Model::File->new(
        app        => $self->app,
        repository => $self->repository,
        path       => join('/', @parts),
    );
}

1;

__END__

=pod

=head1 NAME

Yukki::Model::File - the model for loading and saving files in the wiki

=head1 VERSION

version 0.140290

=head1 SYNOPSIS

  my $repository = $app->model('Repository', { repository => 'main' });
  my $file = $repository->file({
      path     => 'foobar',
      filetype => 'yukki',
  });

=head1 DESCRIPTION

Tools for fetching files from the git repository and storing them there.

=head1 EXTENDS

L<Yukki::Model>

=head1 ATTRIBUTES

=head2 path

This is the path to the file in the repository, but without the file suffix.

=head2 filetype

The suffix of the file. Defaults to "yukki".

=head2 repository

This is the the L<Yukki::Model::Repository> the file will be fetched from or
stored into.

=head1 METHODS

=head2 BUILDARGS

Allows C<full_path> to be given instead of C<path> and C<filetype>.



( run in 1.136 second using v1.01-cache-2.11-cpan-71847e10f99 )