finish reorganizing stemmaweb controllers
Tara L Andrews [Tue, 17 Jan 2012 21:51:39 +0000 (22:51 +0100)]
TreeOfTexts/lib/TreeOfTexts/Controller/Microservice.pm [new file with mode: 0644]
TreeOfTexts/lib/TreeOfTexts/Controller/Relation.pm [new file with mode: 0644]
TreeOfTexts/lib/TreeOfTexts/Controller/Root.pm
TreeOfTexts/lib/TreeOfTexts/Controller/Stemmagraph.pm [deleted file]
TreeOfTexts/lib/TreeOfTexts/Controller/Stexaminer.pm [new file with mode: 0644]
TreeOfTexts/lib/TreeOfTexts/View/Plain.pm
TreeOfTexts/root/src/relate.tt [new file with mode: 0644]

diff --git a/TreeOfTexts/lib/TreeOfTexts/Controller/Microservice.pm b/TreeOfTexts/lib/TreeOfTexts/Controller/Microservice.pm
new file mode 100644 (file)
index 0000000..210df15
--- /dev/null
@@ -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 (file)
index 0000000..3f7c559
--- /dev/null
@@ -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;
index 91e3201..cb3b9d9 100644 (file)
@@ -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 (file)
index 3079312..0000000
+++ /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 (file)
index 0000000..aba493c
--- /dev/null
@@ -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;
index 73e101f..e267272 100644 (file)
@@ -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<TreeOfTexts>
+
+=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 (file)
index 0000000..e69de29