BusyBird
view release on metacpan or search on metacpan
lib/BusyBird/Main/PSGI.pm view on Meta::CPAN
package BusyBird::Main::PSGI;
use v5.8.0;
use strict;
use warnings;
use BusyBird::Util qw(set_param future_of);
use BusyBird::Main::PSGI::View;
use Router::Simple;
use Plack::Request;
use Plack::Builder ();
use Plack::App::File;
use Try::Tiny;
use JSON qw(decode_json);
use Scalar::Util qw(looks_like_number);
use List::Util qw(min);
use Carp;
use Exporter 5.57 qw(import);
use URI::Escape qw(uri_unescape);
use Encode qw(decode_utf8);
use Future::Q;
use POSIX qw(ceil);
our @EXPORT_OK = qw(create_psgi_app);
sub create_psgi_app {
my ($main_obj) = @_;
my $self = __PACKAGE__->_new(main_obj => $main_obj);
return $self->_to_app;
}
sub _new {
my ($class, %params) = @_;
my $self = bless {
router => Router::Simple->new,
view => undef, ## lazy build
}, $class;
$self->set_param(\%params, "main_obj", undef, 1);
$self->_build_routes();
return $self;
}
sub _to_app {
my $self = shift;
my $sharedir = $self->{main_obj}->get_config("sharedir_path");
$sharedir =~ s{/+$}{};
return Plack::Builder::builder {
Plack::Builder::enable 'ContentLength';
Plack::Builder::mount '/static' => Plack::App::File->new(
root => File::Spec->catdir($sharedir, 'www', 'static')
)->to_app;
Plack::Builder::mount '/' => $self->_my_app;
};
}
sub _my_app {
my ($self) = @_;
return sub {
my ($env) = @_;
$self->{view} ||= BusyBird::Main::PSGI::View->new(main_obj => $self->{main_obj}, script_name => $env->{SCRIPT_NAME});
if(my $dest = $self->{router}->match($env)) {
my $req = Plack::Request->new($env);
my $code = $dest->{code};
my $method = $dest->{method};
return defined($code) ? $code->($self, $req, $dest) : $self->$method($req, $dest);
}else {
return $self->{view}->response_notfound();
}
};
}
sub _build_routes {
( run in 1.799 second using v1.01-cache-2.11-cpan-39bf76dae61 )