[Catalyst] File-browser functionality

Jonathan Rockway jon at jrock.us
Fri Feb 29 21:53:34 GMT 2008


* On Fri, Feb 29 2008, Alessio Bragadini wrote:
> On 29 Feb 2008, at 12:13, Peter Sørensen wrote:
>
>> I'm using catalyst and TT to develop a system, where
>> it is possible to search in system logfiles based
>> on predefined regex.
>>
>> I need a way to BROWSE on the server filesystem.
>>
>> I can use the directory plugin in TT but before
>> trying this I would ask if any other solutions
>> are around.
>
> In the Catalyst book written by Jonathan Rockway, an example
> implements a new Filesystem Model to read and write blog posts as
> files on disk. This is IMO similar in concept to the thing you are
> trying to do. Jonathan takes the example further with the Angerwhale
> module available from CPAN.
>
> Since you need to "search" in files, another angle would be to treat
> the log files as tables using some kind of package based on
> DBD::File. Once that's in place, the rest will follow as a normal
> Catalyst application with a DBI-based Model.

I think the code will end up like what's below.  You can probably get
away with using Path::Class objects directly, actually...  Just make
sure you enforce permissions in your model, passing some privileges
model object in from the controller if necessary.  In that case, make
sure to use Catalyst::Model::Factory and automate passing it in.

Backend:

  package YourApp::File;
  has 'path' => (is => 'ro', isa => File, required => 1);

  package YourApp::Directory;
  has 'path' => (is => 'ro', isa => Dir, required => 1);

  sub files {
      opendir $dh, $self->path;
      pushd $self->path; # File::pushd
      my @results;
      while(my $filename = readdir $dh){
         next if $filename =~ /^..?$/; # skip .. and .
         given($filename){
             when(-f) { YourApp::File->new(path => $filename) }
             when(-d) { YourApp::Directory->new(path => $filename) }
         }
      }
  }

  sub subdir {
     my $dir = shift;
     __PACKAGE__->new( path => $self->path . "/$dir" ); # or use Path::Class
  }

Model:

  package YourApp::Model::SomeDirectory;
  use base 'Catalyst::Model::Adaptor';
  
  __PACAKGE__->config( class => 'YourApp::Directory' );

Config:

  ---
  Model::SomeDirectory:
    args:
      path: "/var/myapp"

Controller:

  package YourApp::Controller::Directory;
  sub show :Path {
     my ($self, $c, @path_parts) = @_;
     my $dir = $c->model('SomeDirectory');
     $dir = $dir->subdir($_) for @path_parts;

     $c->stash->{directory} = $dir;
     $c->stash->{template} = 'list_directory.tt';
  }

Template:

  <ul>
  [% FOREACH file IN dir.files %]
  [% IF file.isa("YourApp::Directory") %]
    <li><a href="...">[% file.name %]</a></li>
   [% ELSE %]
    <li>[% file.name %]</li>
   [% END %]
  [% END %]
  </ul>

Regards,
Jonathan Rockway



More information about the Catalyst mailing list