Dezi

 view release on metacpan or  search on metacpan

lib/Dezi/Config.pm  view on Meta::CPAN

);
has 'server_class' =>
    ( is => 'rw', isa => Str, default => sub {'Dezi::Server'} );
has 'ui_class'    => ( is => 'rw', isa => Maybe [Str] );
has 'admin_class' => ( is => 'rw', isa => Maybe [Str] );
has 'debug' =>
    ( is => 'rw', isa => Bool, default => sub { $ENV{DEZI_DEBUG} || 0 } );
has 'base_uri' => ( is => 'rw', isa => Str, default => sub {''} );
has 'search_server' => (
    is      => 'rw',
    isa     => InstanceOf ['Search::OpenSearch::Server::Plack'],
    lazy    => 1,
    builder => 'init_search_server',
);
has 'index_server' => (
    is      => 'rw',
    isa     => InstanceOf ['Search::OpenSearch::Server::Plack'],
    lazy    => 1,
    builder => 'init_index_server',
);
has 'authenticator' => ( is => 'rw', isa => Maybe [CodeRef] );
has 'server_config' => ( is => 'rw', isa => HashRef );

our $VERSION = '0.004003';

sub init_ui {
    my $self = shift;
    if ( $self->ui_class ) {
        Class::Load::load_class $self->ui_class;
        return $self->ui_class->new(
            search_path => $self->search_path,
            base_uri    => $self->base_uri
        );
    }
    return undef;
}

sub init_admin {
    my $self = shift;
    if ( $self->admin_class ) {
        Class::Load::load_class $self->admin_class;
        return $self->admin_class->app(
            user_config => $self->server_config,
            searcher    => $self->search_server,
            base_uri    => $self->base_uri,
        );
    }
    return undef;
}

sub BUILDARGS {
    my $class = shift;
    my %args;
    if ( @_ == 1 and ref( $_[0] ) eq 'HASH' ) {
        %args = %{ $_[0] };
    }
    else {
        %args = @_;
    }

    # save credentials in a closure but not plain in args
    my $username      = delete $args{username};
    my $password      = delete $args{password};
    my $authenticator = ( defined $username and defined $password )
        ? sub {
        my ( $u, $p ) = @_;
        return $u eq $username && $p eq $password;
        }
        : undef;
    $args{authenticator} ||= $authenticator;

    # save anything we do not have an explicit method for
    # in the server_config stash
    $args{server_config} ||= {};
    for my $arg ( keys %args ) {
        if ( !$class->can($arg) ) {
            $args{server_config}->{$arg} = delete $args{$arg};
        }
        elsif ( $arg eq 'admin' and ref( $args{$arg} ) eq 'HASH' ) {

            # special case. compatability with Dezi::Admin::Config.
            $args{server_config}->{$arg} = delete $args{$arg};
        }
    }

    # make sure all paths are /-prefixed
    for my $p (
        qw( search_path index_path commit_path rollback_path ui_path admin_path )
        )
    {
        if ( exists $args{$p} ) {
            $args{$p} = "/$args{$p}" unless $args{$p} =~ m!^(/|https?:)!;
        }
    }
    return \%args;
}

sub BUILD {
    my $self          = shift;
    my $server_class  = $self->server_class;
    my $search_path   = $self->search_path;
    my $index_path    = $self->index_path;
    my $commit_path   = $self->commit_path;
    my $rollback_path = $self->rollback_path;
    my $ui_path       = $self->ui_path;
    my $admin_path    = $self->admin_path;
    my $base_uri      = $self->base_uri;

    Class::Load::load_class $server_class;
    my $search_server = $server_class->new(
        %{ $self->server_config },
        engine_config => $self->apply_default_engine_config(
            { %{ $self->server_config }, search_path => $search_path }
        ),
        http_allow => [qw( GET )],
    );
    my $index_server = $server_class->new(
        %{ $self->server_config },
        engine_config => $self->apply_default_engine_config(
            { %{ $self->server_config }, search_path => $search_path }
        ),

lib/Dezi/Config.pm  view on Meta::CPAN

    return $self;
}

sub apply_default_engine_config {
    my ( $self, $args ) = @_;
    my $engine_config = $args->{engine_config} || {};
    $engine_config->{type}  ||= 'Lucy';
    $engine_config->{index} ||= ['dezi.index'];
    my $search_path = delete $args->{search_path};
    $engine_config->{link} ||= $search_path;
    $engine_config->{default_response_format} ||= 'JSON';
    $engine_config->{debug} = $args->{debug} || $self->debug;
    return $engine_config;
}

sub as_hash {
    my $self = shift;
    return %$self;
}

1;

__END__

=pod

=head1 NAME

Dezi::Config - Dezi server configuration

=head1 SYNOPSIS

 use Dezi::Config;
 use CHI;         # optional, see cache below
 use Dezi::UI;    # optional, see ui_class and ui below
 use Dezi::Admin; # optional, see admin_class and admin below
 use Dezi::Stats; # optional, see stats_logger below

 my $dezi_config = Dezi::Config->new({
 
    search_path     => '/search',
    index_path      => '/index',
    commit_path     => '/commit',
    rollback_path   => '/rollback',
    ui_path         => '/ui',
    ui_class        => 'Dezi::UI',
    # or
    # ui              => Dezi::UI->new()
   
    admin_path      => '/admin', 
    admin_class     => 'Dezi::Admin',
    # or
    # admin           => Dezi::Admin->new(),
    
    base_uri        => '',
    server_class    => 'Dezi::Server',
    
    # authentication for non-idempotent requests.
    # if both username && password are defined,
    # then /index, /commit and /rollback require
    # basic authentication credentials.
    username        => 'someone',
    password        => 'somesecret',
    
    # optional
    # see Dezi::Stats
    stats_logger => Dezi::Stats->new(
        type        => 'DBI',
        dsn         => 'DBI::mysql:database=mydb;host=localhost;port=3306',
        username    => 'myuser',
        password    => 'mysecret',
    ),
    
    # see Search::OpenSearch::Engine
    engine_config => {

        default_response_format => 'JSON',
        
        # could be any Search::OpenSearch::Engine::* class
        type    => 'Lucy',

        # name of the index(es)
        index   => [qw( path/to/your.index )],

        # which facets to calculate, and how many results to consider
        facets => {
            names       => [qw( color size flavor )],
            sample_size => 10_000,
        },

        # result attributes in response
        fields => [qw( color size flavor )],

        # options passed to indexer defined by Engine type (above)
        # defaults to Dezi::Lucy::Indexer->new
        indexer_config => {
        
            # see Dezi::Indexer::Config
            # and https://dezi.org/swish-e-docs/SWISH-CONFIG.pod.html
            config => { 

                # searchable fields
                MetaNames => 'color size flavor',

                # attributes to store
                PropertyNames => 'color size flavor',

                # auto-vivify new fields based on POSTed docs.
                # use this if you want ElasticSearch-like effect.
                UndefinedMetaTags => 'auto',

                # treat unknown mime types as text/plain
                DefaultContents => 'TXT',

                # use English snowball stemmer
                FuzzyIndexingMode => 'Stemming_en1',

            }, 

            # store token positions to optimize snippet creation
            highlightable_fields => 1,



( run in 0.751 second using v1.01-cache-2.11-cpan-496ff517765 )