1 package stemmaweb::Controller::Microservice;
3 use namespace::autoclean;
7 #use Text::Tradition::Error;
8 use Text::Tradition::Stemma;
9 use Text::Tradition::StemmaUtil qw/ character_input phylip_pars newick_to_svg /;
11 BEGIN { extends 'Catalyst::Controller' }
15 stemmaweb::Controller::Microservice - Controller for stemmaweb standalone
20 This package contains the pieces of web functionality relating to text tradition
21 objects that are useful outside the framework of this application.
23 =head1 COLLATION PARSING INPUT
25 Each URL call which operates on a provided collation is called by POST with the
26 following form parameters in the body:
30 =item * type - Can be one of CollateX, CTE, CSV, JSON, nCritic, TEI, Tabular.
32 =item * data - The collation data itself.
40 GET microservice/parse
41 POST microservice/parse {
46 Attempt a parse of the passed collation data, and return diagnostic information about whether it was successful.
50 sub parse :Local :Args(0) {
52 if( $c->req->method eq 'POST' ) {
53 # Get the passed options...
57 'name' => $c->request->param('name') || 'Uploaded tradition',
58 'file' => $c->request->upload('file')->tempname,
59 'warnings_to' => $warnings,
61 my $type = $c->request->param( 'type' );
62 if( $type eq 'csv' ) {
63 $newopts{'input'} = 'Tabular';
64 $newopts{'sep_char'} = ',';
65 } elsif( $type eq 'tsv' ) {
66 $newopts{'input'} = 'Tabular';
67 $newopts{'sep_char'} = "\t";
68 } elsif( $type =~ /^xls/ ) {
69 $newopts{'input'} = 'Tabular';
70 $newopts{'excel'} = $type;
72 $newopts{'input'} = $type;
77 $c->stash->{'result'} = Text::Tradition->new( %newopts );
78 } catch ( Text::Tradition::Error $e ) {
79 $c->stash->{'errormsg'} = $e->message;
81 $c->stash->{'warnings'} = join( "\n", @$warnings );
83 $c->stash->{template} = 'testparse.tt';
88 POST microservice/renderSVG
90 Parse the passed collation data and return an SVG of the collated text.
94 # Utility function to render SVG from a collation in some recognized format.
95 sub renderSVG :Local :Args(0) {
97 my $tradition = _parse_to_tradition( $c->request );
99 $c->stash->{'result'} = $tradition->collation->as_svg;
100 $c->forward('View::SVG');
101 } catch( Text::Tradition::Error $e ) {
102 $c->detach( 'error', [ $e ] );
106 =head1 STEMMA / DISTANCE TREE URLs
110 POST microservice/stemma_svg
112 Parameter: dot => a string containing the dot description of the stemma.
116 sub stemma_svg :Local :Args(0) {
117 my( $self, $c ) = @_;
118 my $t = Text::Tradition->new();
121 $stemma = $t->add_stemma( 'dot' => $c->req->param('dot') );
122 } catch( Text::Tradition::Error $e ) {
123 $c->detach( 'error', [ $e ] );
125 $c->stash->{'result'} = $stemma->as_svg;
126 $c->forward('View::SVG');
129 =head2 character_matrix
131 POST microservice/character_matrix
133 Given an alignment table in JSON form, in the parameter 'alignment', returns a
134 character matrix suitable for input to Phylip PARS.
138 sub character_matrix :Local :Args(0) {
139 my( $self, $c ) = @_;
140 my $json = $c->request->params->{'alignment'};
141 $c->log->debug( $json );
142 my $table = from_json( $json );
143 my $matrix = character_input( $table );
144 $c->stash->{'result'} = { 'matrix' => $matrix };
145 $c->forward( 'View::JSON' );
150 POST microservice/run_pars
152 Runs Phylip PARS on the provided alignment, and returns the result. Parameters include:
156 =item * alignment - A JSON alignment table, as produced by CollateX
158 =item * matrix - A character matrix suitable for Phylip.
160 =item * format - The format in which to return the results. Default is 'newick'; also allowed is 'svg'.
164 Exactly one of 'alignment' or 'matrix' must be specified.
168 sub run_pars :Local :Args(0) {
169 my( $self, $c ) = @_;
171 if( $c->request->param('matrix') ) {
172 $matrix = $c->request->param('matrix');
173 } elsif( $c->request->param('alignment') ) {
174 # Make the matrix from the alignment
175 my $table = from_json( $c->request->param('alignment') );
176 $matrix = character_input( $table );
178 $c->detach( 'error', [ "Must pass either an alignment or a matrix" ] );
181 # Got the matrix, so try to run pars.
184 $output = phylip_pars( $matrix );
185 } catch( Text::Tradition::Error $e ) {
186 $c->detach( 'error', [ $e ] );
189 # Did we want newick or a graph?
190 my $view = 'View::JSON';
191 my $format = 'newick';
192 $format = $c->request->param('format') if $c->request->param('format');
193 if( $format eq 'svg' ) {
196 $c->stash->{'result'} = newick_to_svg( $output );
198 } catch( Text::Tradition::Error $e ) {
199 $c->detach( 'error', [ $e ] );
201 } elsif( $format ne 'newick' ) {
202 $c->detach( 'error', [ "Requested output format $format unknown" ] );
204 $c->stash->{'result'} = { 'tree' => $output };
207 $c->forward( $view );
211 =head1 OPENSOCIAL URLs
215 Simple gadget to return the analysis table for the stexaminer
219 sub view_table :Local :Args(0) {
220 my( $self, $c ) = @_;
221 my $m = $c->model('Directory');
222 my $id = $c->request->params->{'textid'};
223 my $t = run_analysis( $m->tradition( $id ), $m->stemma( $id ) );
224 $c->stash->{variants} = $t->{'variants'};
225 $c->stash->{template} = 'table_gadget.tt';
228 =head2 view_stemma_svg
230 Simple gadget to return the SVG for a given stemma
234 sub view_svg :Local :Args(0) {
235 my( $self, $c ) = @_;
236 my $m = $c->model('Directory');
237 my $stemma = $m->tradition( $c->request->params->{'textid'} )->stemma;
239 $c->stash->{svg} = $stemma->as_svg;
241 $c->stash->{template} = 'stemma_gadget.tt';
246 Default response when actions generate Text::Tradition::Error exceptions
251 my( $self, $c, $error ) = @_;
253 if( ref( $error ) eq 'Text::Tradition::Error' ) {
254 $errstr = $error->ident . ": " . $error->message;
256 $c->response->code( 500 );
257 $c->stash->{'error'} = $errstr;
258 $c->stash->{'template'} = 'error.tt';
263 Standard 404 error page
268 my ( $self, $c ) = @_;
269 $c->response->body( 'Page not found' );
270 $c->response->status(404);
273 ## Internal utility function
275 sub _parse_to_tradition {
277 my $type = $req->body_params->{'type'};
278 my $name = $req->param('name') || 'Collation graph';
279 my $data = $req->body_params->{'data'};
285 $opts->{'sep_char'} = ',' if $type eq 'CSV';
286 $opts->{'sep_char'} = "\t" if $type eq 'TabSep';
287 return Text::Tradition->new( $opts );
297 This library is free software. You can redistribute it and/or modify
298 it under the same terms as Perl itself.
302 __PACKAGE__->meta->make_immutable;