File Coverage

blib/lib/NLP/Service.pm
Criterion Covered Total %
statement 7 9 77.7
branch n/a
condition n/a
subroutine 3 3 100.0
pod n/a
total 10 12 83.3


line stmt bran cond sub pod time code
1             package NLP::Service;
2              
3 1     1   21654 use 5.010000;
  1         4  
  1         42  
4 1     1   5 use feature ':5.10';
  1         2  
  1         288  
5 1     1   442 use common::sense;
  0            
  0            
6             use Carp ();
7              
8             BEGIN {
9             use Exporter();
10             our @ISA = qw(Exporter);
11             our $VERSION = '0.02';
12             use NLP::StanfordParser;
13             }
14              
15             use Dancer qw(:tests); # we do not want the tests exporting the wrong functions.
16             use Dancer::Plugin::REST;
17              
18             my %_nlp = ();
19              
20             prepare_serializer_for_format;
21              
22             any [qw/get post/] => '/' => sub {
23              
24             #TODO: show a UI form based thing for easy use for the end user.
25             return 'This is ' . config->{appname} . "\n";
26             };
27              
28             any [qw/get post/] => '/nlp/models.:format' => sub {
29             return [ keys %_nlp ];
30             };
31              
32             any [qw/get post/] => '/nlp/languages.:format' => sub {
33             return [qw/en/];
34             };
35              
36             any [qw/get post/] => '/nlp/info.:format' => sub {
37             return {
38             version => $NLP::Service::VERSION,
39             nlplib_name => 'Stanford Parser',
40             nlplib_source => PARSER_SOURCE_URI,
41             nlplib_release => PARSER_RELEASE_DATE,
42             };
43             };
44              
45             any [qw/get post/] => '/nlp/relations.:format' => sub {
46             return NLP::StanfordParser::relations();
47             };
48              
49             #Dancer::forward does not forward the parameters, hence we have to explicitly
50             #forward them.
51             any [qw/get post/] => '/nlp/parse.:format' => sub {
52             my $model = 'en_pcfg';
53             my $route = "/nlp/parse/$model." . params->{format};
54             debug "Forwarding to $route";
55             if ( request->{method} eq 'GET' ) {
56             return forward $route,
57             {
58             format => params->{format},
59             model => $model,
60             data => params->{data}
61             };
62             } else {
63              
64             # HACK inserted until Dancer's forwarding bug gets fixed.
65             # https://github.com/sukria/Dancer/pull/545
66             #
67             my $data = params->{data};
68             $data =~ s/^\s+//g;
69             $data =~ s/\s+$//g;
70             my $data = params->{data}
71             or return send_error( { error => "Empty 'data' parameter" }, 500 );
72             debug "Data is $data\n";
73             if ( defined $_nlp{$model} ) {
74             my $str = $_nlp{$model}->parse($data);
75             my $aref = eval $str or Carp::carp "Unable to eval $str";
76             return defined $aref ? $aref : "$str\n";
77             }
78             return send_error( { error => "Invalid NLP object for $model" }, 500 );
79             }
80             };
81              
82             any [qw/get post/] => '/nlp/parse/:model.:format' => sub {
83             my $model = params->{model};
84             debug "Model is $model";
85             return send_error( { error => "Unknown parsing model $model" }, 500 )
86             unless defined $_nlp{$model};
87             my $data = params->{data};
88             $data =~ s/^\s+//g;
89             $data =~ s/\s+$//g;
90             my $data = params->{data}
91             or return send_error( { error => "Empty 'data' parameter" }, 500 );
92             debug "Data is $data\n";
93              
94             if ( defined $_nlp{$model} ) {
95             my $str = $_nlp{$model}->parse($data);
96             my $aref = eval $str or Carp::carp "Unable to eval $str";
97             return defined $aref ? $aref : "$str\n";
98             }
99             return send_error( { error => "Invalid NLP object for $model" }, 500 );
100             };
101              
102             sub load_models {
103             my ( $force, $jarpath ) = @_;
104             say 'Forcing loading of all NLP models.' if $force;
105             %_nlp = ();
106             $_nlp{en_pcfg} = new NLP::StanfordParser( model => MODEL_EN_PCFG )
107             or Carp::croak 'Unable to create MODEL_EN_PCFG for NLP::StanfordParser';
108              
109             # PCFG load times are reasonable ~ 5 sec. We force load on startup.
110             $_nlp{en_pcfg}->parser if $force;
111             $_nlp{en_factored} = new NLP::StanfordParser( model => MODEL_EN_FACTORED )
112             or Carp::croak
113             'Unable to create MODEL_EN_FACTORED for NLP::StanfordParser';
114              
115             # Factored load times can be quite slow ~ 30 sec. We force load on startup.
116             $_nlp{en_factored}->parser if $force;
117              
118             # PCFG WSJ takes ~ 2-3 seconds to load
119             $_nlp{en_pcfgwsj} = new NLP::StanfordParser( model => MODEL_EN_PCFG_WSJ )
120             or Carp::croak
121             'Unable to create MODEL_EN_PCFG_WSJ for NLP::StanfordParser';
122             $_nlp{en_pcfgwsj}->parser if $force;
123             $_nlp{en_factoredwsj} =
124             new NLP::StanfordParser( model => MODEL_EN_FACTORED_WSJ )
125             or Carp::croak
126             'Unable to create MODEL_EN_FACTORED_WSJ for NLP::StanfordParser';
127              
128             # FACTORED WSJ takes ~ 20 seconds to load
129             $_nlp{en_factoredwsj}->parser if $force;
130             return unless defined wantarray; # void context returns nothing
131             return wantarray ? %_nlp : scalar( keys(%_nlp) );
132             }
133              
134             sub run {
135             my %args = @_;
136             my $force = $args{force} if scalar( keys(%args) );
137             my $config = $args{config} if scalar( keys(%args) );
138             if ( defined $config and ref $config eq 'HASH' ) {
139             map { set( $_ => $config->{$_} ) } keys %$config;
140             } else {
141             set log => 'error';
142             set logger => 'console';
143             set show_errors => 1;
144             set startup_info => 0;
145             }
146             load_models($force);
147             dance; # invoke Dancer
148             }
149              
150             1;
151             __END__