91e32013f7642b500f0536348e58dabf38f03072
[scpubgit/stemmatology.git] / TreeOfTexts / lib / TreeOfTexts / Controller / Root.pm
1 package TreeOfTexts::Controller::Root;
2 use Moose;
3 use namespace::autoclean;
4 use Text::Tradition::Analysis qw/ run_analysis /;
5
6
7 BEGIN { extends 'Catalyst::Controller' }
8
9 #
10 # Sets the actions in this controller to be registered with no prefix
11 # so they function identically to actions created in MyApp.pm
12 #
13 __PACKAGE__->config(namespace => '');
14
15 =head1 NAME
16
17 TreeOfTexts::Controller::Root - Root Controller for TreeOfTexts
18
19 =head1 DESCRIPTION
20
21 Serves up the main container pages.
22
23 =head1 URLs
24
25 =head2 index
26
27 The root page (/).  Serves the main container page, from which the various
28 components will be loaded.
29
30 =cut
31
32 sub index :Path :Args(0) {
33     my ( $self, $c ) = @_;
34
35     $c->stash->{template} = 'index.tt';
36 }
37
38 =head1 Elements of index page
39
40 =head2 directory
41
42  GET /directory
43
44 Serves a snippet of HTML that lists the available texts.  Eventually this will be available texts by user.
45
46 =cut
47 sub directory :Path :Args(0) {
48         my( $self, $c ) = @_;
49     my $m = $c->model('Directory');
50     # TODO not used yet, will load user texts later
51     my $user = $c->request->param( 'user' ) || 'ALL';
52     my @textlist;
53     foreach my $id ( $m->tradition_ids ) {
54         my $data = { 
55                 'id' => $id,
56                 'name' => $m->name( $id ),
57         };
58         push( @all_texts, $data );
59     }
60     
61     $c->stash->{texts} = \@textlist;
62         $c->stash->{template} = 'directory.tt';
63 }
64
65 =head2 alignment
66
67  GET /alignment/$textid
68
69 Returns an alignment table for the text specified at $textid.
70
71 =cut
72
73 sub alignment :Path :Args(1) {
74         my( $self, $c, $textid ) = @_;
75         my $m = $c->model('Directory');
76         my $collation = $m->tradition( $textid )->collation;
77         my $alignment = $collation->make_alignment_table;
78         
79         # Turn the table, so that witnesses are by column and the rows
80         # are by rank.
81         my $wits = [ map { $_->{'witness'} } @{$alignment->{'alignment'}} ];
82         my $rows;
83         foreach my $i ( 0 .. $alignment->{'length'} - 1 ) {
84                 my @rankrdgs = map { $_->{'tokens'}->[$i]->{'t'} } 
85                         @{$alignment->{'alignment'}};
86                 push( @$rows, { 'rank' => $i+1, 'readings' => \@rankrdgs } );
87         }
88         $c->log->debug( Dumper( $rows ) );
89         $c->stash->{'witnesses'} = $wits;
90         $c->stash->{'table'} = $rows;
91         $c->stash->{'template'} = 'alignment.tt';
92 }
93
94 =head2 stemma
95
96  GET /stemma/$textid
97  POST /stemma/$textid, { 'dot' => $dot_string }
98
99 Returns an SVG representation of the stemma hypothesis for the text.  If 
100 the URL is called with POST and a new dot string, updates the stemma and
101 returns the SVG as with GET.
102
103 =cut
104
105 sub stemma :Path :Args(1) {
106         my( $self, $c, $textid ) = @_;
107         my $m = $c->model('Directory');
108         my $tradition = $m->tradition( $textid );
109         
110         if( $c->req->method eq 'POST' ) {
111                 # Update the stemma
112                 my $dot = $c->request->body_params->{'dot'};
113                 $tradition->add_stemma( $dot );
114                 $m->store( $tradition );
115         }
116         
117         $c->stash->{'result'} = $tradition->stemma->as_svg;
118         $c->forward('View::SVG');
119 }
120
121 =head2 stemmadot
122
123  GET /stemmadot/$textid
124  
125 Returns the 'dot' format representation of the current stemma hypothesis.
126
127 =cut
128
129 sub stemma :Path :Args(1) {
130         my( $self, $c, $textid ) = @_;
131         my $m = $c->model('Directory');
132         my $tradition = $m->tradition( $textid );
133         
134         $c->response->body( $tradition->stemma->editable );
135         $c->forward('View::Plain');
136 }
137
138 =head2 relationships
139
140 The relationship editor tool.
141
142 =cut
143
144 sub relationships :Local {
145         my( $self, $c ) = @_;
146         my $m = $c->model('Directory');
147         my $tradition = $m->tradition( $c->request->params->{'textid'} );
148         my $table = $tradition->collation->make_alignment_table();
149         my $witlist = map { $_->{'witness'} } @{$table->{'alignment'}};
150         $c->stash->{witnesses} = $witlist;
151         $c->stash->{alignment} = $table;
152         $c->stash->{template} = 'relate.tt';    
153 }
154
155 =head2 stexaminer
156
157 The stemma analysis tool with the pretty colored table.
158
159 =cut
160
161 sub stexaminer :Local {
162     my( $self, $c ) = @_;
163     my $m = $c->model('Directory');
164         my $tradition = $m->tradition( $c->request->params->{'textid'} );
165         my $stemma = $tradition->stemma;
166         # TODO Think about caching the stemma in a session 
167         $c->stash->{svg} = $stemma->as_svg;
168         $c->stash->{text_title} = $tradition->name;
169         $c->stash->{template} = 'index.tt'; 
170         # TODO Run the analysis as AJAX from the loaded page.
171         my $t = run_analysis( $tradition );
172         $c->stash->{variants} = $t->{'variants'};
173         $c->stash->{total} = $t->{'variant_count'};
174         $c->stash->{genealogical} = $t->{'genealogical_count'};
175         $c->stash->{conflict} = $t->{'conflict_count'};
176 }
177
178 =head1 MICROSERVICE CALLS
179
180 =head2 renderSVG
181
182 Parse the passed collation data and return an SVG of the collated text.  Takes
183 the following parameters:
184
185 =over 4
186
187 =item * data - The collation data itself.
188
189 =item * input - The data format.  Valid values include CollateX, Self, TEI (for parallel segmentation) eventually Tabular.
190
191 =item * name - A name for the text. Not so important for this function.
192
193 =cut
194
195 # Utility function to render SVG from a graph input.
196 sub renderSVG :Local {
197         my( $self, $c ) = @_;
198         my $format = $c->request->param('format') || 'string';
199         my $type = $c->request->body_params->{'type'};
200         my $name = $c->request->param('name') || 'Collation graph';
201         my $data = $c->request->body_params->{'data'};
202         $c->log->debug( $data );
203         my $tradition = Text::Tradition->new( 
204                 'name' => $name,
205                 'input' => $type,
206                 $format => $data,
207                 );
208         $c->log->debug( "Got tradition with " . $tradition->collation->readings . " readings" );
209         $c->stash->{'result'} = $tradition->collation->as_svg;
210         $c->forward('View::SVG');
211 }
212
213
214 =head1 OPENSOCIAL URLs
215
216 =head2 view_table
217
218 Simple gadget to return the analysis table for the stexaminer
219
220 =cut
221
222 sub view_table :Local {
223     my( $self, $c ) = @_;
224     my $m = $c->model('Directory');
225         my $id = $c->request->params->{'textid'};
226         my $t = run_analysis( $m->tradition( $id ), $m->stemma( $id ) );
227         $c->stash->{variants} = $t->{'variants'};
228     $c->stash->{template} = 'table_gadget.tt';
229 }
230
231 =head2 view_svg
232
233 Simple gadget to return the SVG for a given stemma
234
235 =cut
236
237 sub view_svg :Local {
238     my( $self, $c ) = @_;
239     my $m = $c->model('Directory');
240     my $stemma = $m->tradition( $c->request->params->{'textid'} )->stemma;
241         if( $stemma ) {
242                 $c->stash->{svg} = $stemma->as_svg;
243         }
244     $c->stash->{template} = 'stemma_gadget.tt';
245 }
246
247 =head2 default
248
249 Standard 404 error page
250
251 =cut
252
253 sub default :Path {
254     my ( $self, $c ) = @_;
255     $c->response->body( 'Page not found' );
256     $c->response->status(404);
257 }
258
259 =head2 end
260
261 Attempt to render a view, if needed.
262
263 =cut
264
265 sub end : ActionClass('RenderView') {}
266
267 =head1 AUTHOR
268
269 Tara L Andrews
270
271 =head1 LICENSE
272
273 This library is free software. You can redistribute it and/or modify
274 it under the same terms as Perl itself.
275
276 =cut
277
278 __PACKAGE__->meta->make_immutable;
279
280 1;