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 )