add JSON alignment table parsing
[scpubgit/stemmatology.git] / TreeOfTexts / lib / TreeOfTexts / Controller / Stemmagraph.pm
CommitLineData
3f9bd252 1package TreeOfTexts::Controller::Stemmagraph;
2use Moose;
3use namespace::autoclean;
cbd0c7d9 4use File::Temp;
68454b71 5use JSON;
3f9bd252 6use Text::Tradition::Collation;
27e2a8fe 7use Text::Tradition::StemmaUtil qw/ character_input phylip_pars newick_to_svg /;
3f9bd252 8
9BEGIN { extends 'Catalyst::Controller' }
10
11#
12# Sets the actions in this controller to be registered with no prefix
13# so they function identically to actions created in MyApp.pm
14#
15__PACKAGE__->config(namespace => '');
16
17=head1 NAME
18
3837c155 19TreeOfTexts::Controller::Stemmagraph - Simple controller for stemma display
3f9bd252 20
21=head1 DESCRIPTION
22
23[enter your description here]
24
25=head1 METHODS
26
a5b3c760 27=cut
28
3f9bd252 29sub get_graph :Local {
30 my( $self, $c ) = @_;
31 # If called interactively, we have params 'display', 'output', 'witnesses'
32 # If called non-interactively, we look at headers and content.
33 # The body is actually a File::Temp object; this is undocumented but
34 # so it seems to be.
cbd0c7d9 35 my $dotfile;
cbd0c7d9 36 my $must_unlink = 0;
37 if( $c->request->params->{'dot'} ) {
38 # Make a File::Temp object.
39 my $tmpfile = File::Temp->new( UNLINK => 0 );
40 print $tmpfile $c->request->params->{'dot'};
41 $dotfile = $tmpfile->filename;
42 $must_unlink = 1;
43 } else {
44 $dotfile = $c->request->body;
45 }
3f9bd252 46 my $format = 'svg';
47
48 # Render the dot in the given format.
49 my $collation = Text::Tradition::Collation->new();
cbd0c7d9 50 my $stemma = Text::Tradition::Stemma->new( 'collation' => $collation, 'dot' => $dotfile );
51 unlink( $dotfile ) if $must_unlink;
3f9bd252 52 $c->stash->{result} = $stemma->as_svg;
53 $c->forward( "View::SVG" );
54}
55
68454b71 56=head2 character_matrix
57
58Given an alignment table in JSON form, in the parameter 'alignment', returns a
59character matrix suitable for input to Phylip PARS.
60
61=cut
62
63sub character_matrix :Local {
64 my( $self, $c ) = @_;
65 my $json = $c->request->params->{'alignment'};
66 $c->log->debug( $json );
67 my $table = from_json( $json );
b02332ca 68 my $matrix = character_input( $table );
68454b71 69 $c->stash->{'result'} = { 'matrix' => $matrix };
70 $c->forward( 'View::JSON' );
71}
3f9bd252 72
27e2a8fe 73=head2 run_pars
74
75Takes either an alignment table in JSON format (passed as the parameter 'alignment')
76or a character matrix Phylip accepts (passed as the parameter 'matrix'). Returns
77either the Newick-format answer or an SVG representation of the graph.
3f9bd252 78
79=cut
80
27e2a8fe 81sub run_pars :Local {
82 my( $self, $c ) = @_;
83 my $error;
84 my $view = 'View::JSON';
85 my $matrix;
86 if( $c->request->param('matrix') ) {
87 $matrix = $c->request->param('matrix');
88 } elsif( $c->request->param('alignment') ) {
89 # Make the matrix from the alignment
90 my $table = from_json( $c->request->param('alignment') );
91 $matrix = character_input( $table );
92 } else {
93 $error = "Must pass either an alignment or a matrix";
94 }
95
96 # Got the matrix, so try to run pars.
97 my( $result, $output );
98 unless( $error ) {
99 ( $result, $output ) = phylip_pars( $matrix );
100 $error = $output unless( $result );
101 }
102
103 # Did we want newick or a graph?
104 unless( $error ) {
105 my $format = 'newick';
106 $format = $c->request->param('format') if $c->request->param('format');
107 if( $format eq 'svg' ) {
108 # Do something
109 $c->stash->{'result'} = newick_to_svg( $output );
110 $view = 'View::SVG';
111 } elsif( $format ne 'newick' ) {
112 $error = "Requested output format $format unknown";
113 } else {
114 $c->stash->{'result'} = { 'tree' => $output };
115 }
116 }
117
118 if( $error ) {
119 $c->stash->{'error'} = $error;
120 } # else the stash is populated.
121 $c->forward( $view );
122}
3f9bd252 123
124=head1 AUTHOR
125
126Tara L Andrews
127
128=head1 LICENSE
129
130This library is free software. You can redistribute it and/or modify
131it under the same terms as Perl itself.
132
133=cut
134
135__PACKAGE__->meta->make_immutable;
136
1371;