From: Tara L Andrews Date: Tue, 17 Jan 2012 21:51:39 +0000 (+0100) Subject: finish reorganizing stemmaweb controllers X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=2376359f1ea2da0f3cf15fce586c55d046ef815a;p=scpubgit%2Fstemmatology.git finish reorganizing stemmaweb controllers --- diff --git a/TreeOfTexts/lib/TreeOfTexts/Controller/Microservice.pm b/TreeOfTexts/lib/TreeOfTexts/Controller/Microservice.pm new file mode 100644 index 0000000..210df15 --- /dev/null +++ b/TreeOfTexts/lib/TreeOfTexts/Controller/Microservice.pm @@ -0,0 +1,236 @@ +package TreeOfTexts::Controller::Microservice; +use Moose; +use namespace::autoclean; +use JSON; +use Text::Tradition; +use Text::Tradition::Stemma; +use Text::Tradition::StemmaUtil qw/ character_input phylip_pars newick_to_svg /; + +BEGIN { extends 'Catalyst::Controller' } + +=head1 NAME + +TreeOfTexts::Controller::Microservice - Controller for TreeOfTexts standalone +components + +=head1 DESCRIPTION + +This package contains the pieces of web functionality relating to text tradition +objects that are useful outside the framework of this application. + +=head1 COLLATION PARSING INPUT + +Each URL call which operates on a provided collation is called by POST with the +following form parameters in the body: + +=over 4 + +=item * type - Can be one of CollateX, CSV, JSON, nCritic, TEI, Tabular. + +=item * data - The collation data itself. + +=back + +=head1 COLLATION URLs + +=head2 renderSVG + + POST microservice/renderSVG + +Parse the passed collation data and return an SVG of the collated text. + +=cut + +# Utility function to render SVG from a collation in some recognized format. +sub renderSVG :Local :Args(0) { + my( $self, $c ) = @_; + my $tradition = _parse_to_tradition( $c->request ); + $c->stash->{'result'} = $tradition->collation->as_svg; + $c->forward('View::SVG'); +} + +=head1 STEMMA / DISTANCE TREE URLs + +=head2 stemma_svg + + POST microservice/stemma_svg + +Parameter: dot => a string containing the dot description of the stemma. + +=cut + +sub stemma_svg :Local :Args(0) { + my( $self, $c ) = @_; + my $t = Text::Tradition->new(); + my $stemma = $t->add_stemma( 'dot' => $c->req->param('dot') ); + $c->stash->{'result'} = $stemma->as_svg; + $c->forward('View::SVG'); +} + +=head2 character_matrix + + POST microservice/character_matrix + +Given an alignment table in JSON form, in the parameter 'alignment', returns a +character matrix suitable for input to Phylip PARS. + +=cut + +sub character_matrix :Local :Args(0) { + my( $self, $c ) = @_; + my $json = $c->request->params->{'alignment'}; + $c->log->debug( $json ); + my $table = from_json( $json ); + my $matrix = character_input( $table ); + $c->stash->{'result'} = { 'matrix' => $matrix }; + $c->forward( 'View::JSON' ); +} + +=head2 run_pars + + POST microservice/run_pars + +Runs Phylip PARS on the provided alignment, and returns the result. Parameters include: + +=over 4 + +=item * alignment - A JSON alignment table, as produced by CollateX + +=item * matrix - A character matrix suitable for Phylip. + +=item * format - The format in which to return the results. Default is 'newick'; also allowed is 'svg'. + +=back + +Exactly one of 'alignment' or 'matrix' must be specified. + +=cut + +sub run_pars :Local :Args(0) { + my( $self, $c ) = @_; + my $error; + my $view = 'View::JSON'; + my $matrix; + if( $c->request->param('matrix') ) { + $matrix = $c->request->param('matrix'); + } elsif( $c->request->param('alignment') ) { + # Make the matrix from the alignment + my $table = from_json( $c->request->param('alignment') ); + $matrix = character_input( $table ); + } else { + $error = "Must pass either an alignment or a matrix"; + } + + # Got the matrix, so try to run pars. + my( $result, $output ); + unless( $error ) { + ( $result, $output ) = phylip_pars( $matrix ); + $error = $output unless( $result ); + } + + # Did we want newick or a graph? + unless( $error ) { + my $format = 'newick'; + $format = $c->request->param('format') if $c->request->param('format'); + if( $format eq 'svg' ) { + # Do something + $c->stash->{'result'} = newick_to_svg( $output ); + $view = 'View::SVG'; + } elsif( $format ne 'newick' ) { + $error = "Requested output format $format unknown"; + } else { + $c->stash->{'result'} = { 'tree' => $output }; + } + } + + if( $error ) { + $c->stash->{'error'} = $error; + } # else the stash is populated. + $c->forward( $view ); +} + + +=head1 OPENSOCIAL URLs + +=head2 view_table + +Simple gadget to return the analysis table for the stexaminer + +=cut + +sub view_table :Local :Args(0) { + my( $self, $c ) = @_; + my $m = $c->model('Directory'); + my $id = $c->request->params->{'textid'}; + my $t = run_analysis( $m->tradition( $id ), $m->stemma( $id ) ); + $c->stash->{variants} = $t->{'variants'}; + $c->stash->{template} = 'table_gadget.tt'; +} + +=head2 view_stemma_svg + +Simple gadget to return the SVG for a given stemma + +=cut + +sub view_svg :Local :Args(0) { + my( $self, $c ) = @_; + my $m = $c->model('Directory'); + my $stemma = $m->tradition( $c->request->params->{'textid'} )->stemma; + if( $stemma ) { + $c->stash->{svg} = $stemma->as_svg; + } + $c->stash->{template} = 'stemma_gadget.tt'; +} + +=head2 default + +Standard 404 error page + +=cut + +sub default :Path { + my ( $self, $c ) = @_; + $c->response->body( 'Page not found' ); + $c->response->status(404); +} + +## Internal utility function + +sub _parse_to_tradition { + my $req = shift; + my $type = $req->body_params->{'type'}; + my $name = $req->param('name') || 'Collation graph'; + my $data = $req->body_params->{'data'}; + my $opts = { + 'name' => $name, + 'input' => $type, + 'string' => $data + }; + $opts->{'sep_char'} = ',' if $type eq 'CSV'; + $opts->{'sep_char'} = "\t" if $type eq 'TabSep'; + return Text::Tradition->new( $opts ); +} + +=head2 end + +Attempt to render a view, if needed. + +=cut + +sub end : ActionClass('RenderView') {} + +=head1 AUTHOR + +Tara L Andrews + +=head1 LICENSE + +This library is free software. You can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut + +__PACKAGE__->meta->make_immutable; + +1; diff --git a/TreeOfTexts/lib/TreeOfTexts/Controller/Relation.pm b/TreeOfTexts/lib/TreeOfTexts/Controller/Relation.pm new file mode 100644 index 0000000..3f7c559 --- /dev/null +++ b/TreeOfTexts/lib/TreeOfTexts/Controller/Relation.pm @@ -0,0 +1,60 @@ +package TreeOfTexts::Controller::Relation; +use Moose; +use namespace::autoclean; + +BEGIN { extends 'Catalyst::Controller' } + + +=head1 NAME + +TreeOfTexts::Controller::Relation - Controller for the relationship mapper + +=head1 DESCRIPTION + +The stemma analysis tool with the pretty colored table. + +=head1 METHODS + + GET relation/$textid + +Renders the application for the text identified by $textid. + +=head2 index + +The relationship editor tool. + +=cut + +sub index :Path :Args(1) { + my( $self, $c, $textid ) = @_; + my $m = $c->model('Directory'); + my $tradition = $m->tradition( $textid ); + my $table = $tradition->collation->make_alignment_table(); + my $witlist = map { $_->{'witness'} } @{$table->{'alignment'}}; + $c->stash->{witnesses} = $witlist; + $c->stash->{alignment} = $table; + $c->stash->{template} = 'relate.tt'; +} + +=head2 end + +Attempt to render a view, if needed. + +=cut + +sub end : ActionClass('RenderView') {} + +=head1 AUTHOR + +Tara L Andrews + +=head1 LICENSE + +This library is free software. You can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut + +__PACKAGE__->meta->make_immutable; + +1; diff --git a/TreeOfTexts/lib/TreeOfTexts/Controller/Root.pm b/TreeOfTexts/lib/TreeOfTexts/Controller/Root.pm index 91e3201..cb3b9d9 100644 --- a/TreeOfTexts/lib/TreeOfTexts/Controller/Root.pm +++ b/TreeOfTexts/lib/TreeOfTexts/Controller/Root.pm @@ -44,7 +44,7 @@ sub index :Path :Args(0) { Serves a snippet of HTML that lists the available texts. Eventually this will be available texts by user. =cut -sub directory :Path :Args(0) { +sub directory :Local :Args(0) { my( $self, $c ) = @_; my $m = $c->model('Directory'); # TODO not used yet, will load user texts later @@ -55,7 +55,7 @@ sub directory :Path :Args(0) { 'id' => $id, 'name' => $m->name( $id ), }; - push( @all_texts, $data ); + push( @textlist, $data ); } $c->stash->{texts} = \@textlist; @@ -70,7 +70,7 @@ Returns an alignment table for the text specified at $textid. =cut -sub alignment :Path :Args(1) { +sub alignment :Local :Args(1) { my( $self, $c, $textid ) = @_; my $m = $c->model('Directory'); my $collation = $m->tradition( $textid )->collation; @@ -102,7 +102,7 @@ returns the SVG as with GET. =cut -sub stemma :Path :Args(1) { +sub stemma :Local :Args(1) { my( $self, $c, $textid ) = @_; my $m = $c->model('Directory'); my $tradition = $m->tradition( $textid ); @@ -126,7 +126,7 @@ Returns the 'dot' format representation of the current stemma hypothesis. =cut -sub stemma :Path :Args(1) { +sub stemmadot :Local :Args(1) { my( $self, $c, $textid ) = @_; my $m = $c->model('Directory'); my $tradition = $m->tradition( $textid ); @@ -135,115 +135,6 @@ sub stemma :Path :Args(1) { $c->forward('View::Plain'); } -=head2 relationships - -The relationship editor tool. - -=cut - -sub relationships :Local { - my( $self, $c ) = @_; - my $m = $c->model('Directory'); - my $tradition = $m->tradition( $c->request->params->{'textid'} ); - my $table = $tradition->collation->make_alignment_table(); - my $witlist = map { $_->{'witness'} } @{$table->{'alignment'}}; - $c->stash->{witnesses} = $witlist; - $c->stash->{alignment} = $table; - $c->stash->{template} = 'relate.tt'; -} - -=head2 stexaminer - -The stemma analysis tool with the pretty colored table. - -=cut - -sub stexaminer :Local { - my( $self, $c ) = @_; - my $m = $c->model('Directory'); - my $tradition = $m->tradition( $c->request->params->{'textid'} ); - my $stemma = $tradition->stemma; - # TODO Think about caching the stemma in a session - $c->stash->{svg} = $stemma->as_svg; - $c->stash->{text_title} = $tradition->name; - $c->stash->{template} = 'index.tt'; - # TODO Run the analysis as AJAX from the loaded page. - my $t = run_analysis( $tradition ); - $c->stash->{variants} = $t->{'variants'}; - $c->stash->{total} = $t->{'variant_count'}; - $c->stash->{genealogical} = $t->{'genealogical_count'}; - $c->stash->{conflict} = $t->{'conflict_count'}; -} - -=head1 MICROSERVICE CALLS - -=head2 renderSVG - -Parse the passed collation data and return an SVG of the collated text. Takes -the following parameters: - -=over 4 - -=item * data - The collation data itself. - -=item * input - The data format. Valid values include CollateX, Self, TEI (for parallel segmentation) eventually Tabular. - -=item * name - A name for the text. Not so important for this function. - -=cut - -# Utility function to render SVG from a graph input. -sub renderSVG :Local { - my( $self, $c ) = @_; - my $format = $c->request->param('format') || 'string'; - my $type = $c->request->body_params->{'type'}; - my $name = $c->request->param('name') || 'Collation graph'; - my $data = $c->request->body_params->{'data'}; - $c->log->debug( $data ); - my $tradition = Text::Tradition->new( - 'name' => $name, - 'input' => $type, - $format => $data, - ); - $c->log->debug( "Got tradition with " . $tradition->collation->readings . " readings" ); - $c->stash->{'result'} = $tradition->collation->as_svg; - $c->forward('View::SVG'); -} - - -=head1 OPENSOCIAL URLs - -=head2 view_table - -Simple gadget to return the analysis table for the stexaminer - -=cut - -sub view_table :Local { - my( $self, $c ) = @_; - my $m = $c->model('Directory'); - my $id = $c->request->params->{'textid'}; - my $t = run_analysis( $m->tradition( $id ), $m->stemma( $id ) ); - $c->stash->{variants} = $t->{'variants'}; - $c->stash->{template} = 'table_gadget.tt'; -} - -=head2 view_svg - -Simple gadget to return the SVG for a given stemma - -=cut - -sub view_svg :Local { - my( $self, $c ) = @_; - my $m = $c->model('Directory'); - my $stemma = $m->tradition( $c->request->params->{'textid'} )->stemma; - if( $stemma ) { - $c->stash->{svg} = $stemma->as_svg; - } - $c->stash->{template} = 'stemma_gadget.tt'; -} - =head2 default Standard 404 error page diff --git a/TreeOfTexts/lib/TreeOfTexts/Controller/Stemmagraph.pm b/TreeOfTexts/lib/TreeOfTexts/Controller/Stemmagraph.pm deleted file mode 100644 index 3079312..0000000 --- a/TreeOfTexts/lib/TreeOfTexts/Controller/Stemmagraph.pm +++ /dev/null @@ -1,137 +0,0 @@ -package TreeOfTexts::Controller::Stemmagraph; -use Moose; -use namespace::autoclean; -use File::Temp; -use JSON; -use Text::Tradition::Collation; -use Text::Tradition::StemmaUtil qw/ character_input phylip_pars newick_to_svg /; - -BEGIN { extends 'Catalyst::Controller' } - -# -# Sets the actions in this controller to be registered with no prefix -# so they function identically to actions created in MyApp.pm -# -__PACKAGE__->config(namespace => ''); - -=head1 NAME - -TreeOfTexts::Controller::Stemmagraph - Simple controller for stemma display - -=head1 DESCRIPTION - -[enter your description here] - -=head1 METHODS - -=cut - -sub get_graph :Local { - my( $self, $c ) = @_; - # If called interactively, we have params 'display', 'output', 'witnesses' - # If called non-interactively, we look at headers and content. - # The body is actually a File::Temp object; this is undocumented but - # so it seems to be. - my $dotfile; - my $must_unlink = 0; - if( $c->request->params->{'dot'} ) { - # Make a File::Temp object. - my $tmpfile = File::Temp->new( UNLINK => 0 ); - print $tmpfile $c->request->params->{'dot'}; - $dotfile = $tmpfile->filename; - $must_unlink = 1; - } else { - $dotfile = $c->request->body; - } - my $format = 'svg'; - - # Render the dot in the given format. - my $collation = Text::Tradition::Collation->new(); - my $stemma = Text::Tradition::Stemma->new( 'collation' => $collation, 'dot' => $dotfile ); - unlink( $dotfile ) if $must_unlink; - $c->stash->{result} = $stemma->as_svg; - $c->forward( "View::SVG" ); -} - -=head2 character_matrix - -Given an alignment table in JSON form, in the parameter 'alignment', returns a -character matrix suitable for input to Phylip PARS. - -=cut - -sub character_matrix :Local { - my( $self, $c ) = @_; - my $json = $c->request->params->{'alignment'}; - $c->log->debug( $json ); - my $table = from_json( $json ); - my $matrix = character_input( $table ); - $c->stash->{'result'} = { 'matrix' => $matrix }; - $c->forward( 'View::JSON' ); -} - -=head2 run_pars - -Takes either an alignment table in JSON format (passed as the parameter 'alignment') -or a character matrix Phylip accepts (passed as the parameter 'matrix'). Returns -either the Newick-format answer or an SVG representation of the graph. - -=cut - -sub run_pars :Local { - my( $self, $c ) = @_; - my $error; - my $view = 'View::JSON'; - my $matrix; - if( $c->request->param('matrix') ) { - $matrix = $c->request->param('matrix'); - } elsif( $c->request->param('alignment') ) { - # Make the matrix from the alignment - my $table = from_json( $c->request->param('alignment') ); - $matrix = character_input( $table ); - } else { - $error = "Must pass either an alignment or a matrix"; - } - - # Got the matrix, so try to run pars. - my( $result, $output ); - unless( $error ) { - ( $result, $output ) = phylip_pars( $matrix ); - $error = $output unless( $result ); - } - - # Did we want newick or a graph? - unless( $error ) { - my $format = 'newick'; - $format = $c->request->param('format') if $c->request->param('format'); - if( $format eq 'svg' ) { - # Do something - $c->stash->{'result'} = newick_to_svg( $output ); - $view = 'View::SVG'; - } elsif( $format ne 'newick' ) { - $error = "Requested output format $format unknown"; - } else { - $c->stash->{'result'} = { 'tree' => $output }; - } - } - - if( $error ) { - $c->stash->{'error'} = $error; - } # else the stash is populated. - $c->forward( $view ); -} - -=head1 AUTHOR - -Tara L Andrews - -=head1 LICENSE - -This library is free software. You can redistribute it and/or modify -it under the same terms as Perl itself. - -=cut - -__PACKAGE__->meta->make_immutable; - -1; diff --git a/TreeOfTexts/lib/TreeOfTexts/Controller/Stexaminer.pm b/TreeOfTexts/lib/TreeOfTexts/Controller/Stexaminer.pm new file mode 100644 index 0000000..aba493c --- /dev/null +++ b/TreeOfTexts/lib/TreeOfTexts/Controller/Stexaminer.pm @@ -0,0 +1,67 @@ +package TreeOfTexts::Controller::Stexaminer; +use Moose; +use namespace::autoclean; +use File::Temp; +use JSON; +use Text::Tradition::Analysis qw/ run_analysis /; + +BEGIN { extends 'Catalyst::Controller' } + + +=head1 NAME + +TreeOfTexts::Controller::Stexaminer - Simple controller for stemma display + +=head1 DESCRIPTION + +The stemma analysis tool with the pretty colored table. + +=head1 METHODS + + GET stexaminer/$textid + +Renders the application for the text identified by $textid. + +=head2 index + +=cut + +sub index :Path :Args(1) { + my( $self, $c, $textid ) = @_; + my $m = $c->model('Directory'); + my $tradition = $m->tradition( $textid ); + my $stemma = $tradition->stemma; + # TODO Think about caching the stemma in a session + $c->stash->{svg} = $stemma->as_svg; + $c->stash->{text_title} = $tradition->name; + $c->stash->{template} = 'stexaminer.tt'; + # TODO Run the analysis as AJAX from the loaded page. + my $t = run_analysis( $tradition ); + $c->stash->{variants} = $t->{'variants'}; + $c->stash->{total} = $t->{'variant_count'}; + $c->stash->{genealogical} = $t->{'genealogical_count'}; + $c->stash->{conflict} = $t->{'conflict_count'}; +} + +=head2 end + +Attempt to render a view, if needed. + +=cut + +sub end : ActionClass('RenderView') {} + +=head1 AUTHOR + +Tara L Andrews + +=head1 LICENSE + +This library is free software. You can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut + +__PACKAGE__->meta->make_immutable; + +1; diff --git a/TreeOfTexts/lib/TreeOfTexts/View/Plain.pm b/TreeOfTexts/lib/TreeOfTexts/View/Plain.pm index 73e101f..e267272 100644 --- a/TreeOfTexts/lib/TreeOfTexts/View/Plain.pm +++ b/TreeOfTexts/lib/TreeOfTexts/View/Plain.pm @@ -2,3 +2,28 @@ package TreeOfTexts::View::Plain; use strict; use base 'Catalyst::View::Download::Plain'; + +=head1 NAME + +TreeOfTexts::View::Plain - Catalyst view for plaintext files + +=head1 SYNOPSIS + +See L + +=head1 DESCRIPTION + +Catalyst plaintext View. + +=head1 AUTHOR + +Tara Andrews + +=head1 LICENSE + +This library is free software, you can redistribute it and/or modify +it under the same terms as Perl itself. + +=cut + +1; diff --git a/TreeOfTexts/root/src/relate.tt b/TreeOfTexts/root/src/relate.tt new file mode 100644 index 0000000..e69de29