initial work on Stemweb client - we have a button! (#29)
[scpubgit/stemmaweb.git] / lib / stemmaweb / Controller / Stemweb.pm
CommitLineData
532cc23b 1package stemmaweb::Controller::Stemweb;
2use Moose;
3use namespace::autoclean;
4use JSON qw/ from_json /;
5use Safe::Isa;
6use TryCatch;
7
8BEGIN { extends 'Catalyst::Controller' }
9
10=head1 NAME
11
12stemmaweb::Controller::Stemweb - Client listener for Stemweb results
13
14=head1 DESCRIPTION
15
16This is a client listener for the Stemweb API as implemented by the protocol defined at
17L<https://docs.google.com/document/d/1aNYGAo1v1WPDZi6LXZ30FJSMJwF8RQPYbOkKqHdCZEc/pub>.
18
19=head1 METHODS
20
21=head2 result
22
23 POST stemweb/result
24 Content-Type: application/json
25 (On success):
26 { job_id: <ID number>
27 status: 0
28 format: <format>
29 result: <data> }
30 (On failure):
31 { jobid: <ID number>
32 status: >1
33 result: <error message> }
34
35Used by the Stemweb server to notify us that one or more stemma graphs
36has been calculated in response to an earlier request.
37
38=cut
39
40sub result :Local :Args(0) {
41 my( $self, $c ) = @_;
42 if( $c->request->method eq 'POST' ) {
43 # TODO: Verify the sender!
44 my $answer;
45 if( ref( $c->request->body ) eq 'File::Temp' ) {
46 # Read in the file and parse that.
47 open( POSTDATA, $c->request->body ) or die "Failed to open post data file";
48 binmode( POSTDATA, ':utf8' );
49 # JSON should be all one line
50 my $pdata = <POSTDATA>;
51 chomp $pdata;
52 close POSTDATA;
53 $answer = from_json( $pdata );
54 } else {
55 $answer = from_json( $c->request->body );
56 }
57 # Find a tradition with the defined Stemweb job ID.
58 # TODO: Maybe get Stemweb to pass back the tradition ID...
59 my $m = $c->model('Directory');
60 my @traditions;
61 $m->scan( sub{ push( @traditions, $_[0] )
62 if $_[0]->$_isa('Text::Tradition')
63 && $_[0]->has_stemweb_jobid
64 && $_[0]->stemweb_jobid eq $answer->{job_id};
65 } );
66 if( @traditions == 1 ) {
67 my $tradition = shift @traditions;
68 if( $answer->{status} == 0 ) {
69 try {
70 $tradition->record_stemweb_result( $answer );
71 $m->save( $tradition );
72 } catch( Text::Tradition::Error $e ) {
73 return _json_error( $c, 500, $e->message );
74 } catch {
75 return _json_error( $c, 500, $@ );
76 }
77 # If we got here, success!
78 $c->stash->{'result'} = { 'status' => 'success' };
79 $c->forward('View::JSON');
80 } else {
81 return _json_error( $c, 500,
82 "Stemweb failure not handled: " . $answer->{result} );
83 }
84 } elsif( @traditions ) {
85 return _json_error( $c, 500,
86 "Multiple traditions with Stemweb job ID " . $answer->{job_id} . "!" );
87 } else {
88 return _json_error( $c, 400,
89 "No tradition found with Stemweb job ID " . $answer->{job_id} );
90 }
91 } else {
92 return _json_error( $c, 403, 'Please use POST!' );
93 }
94}
95
96# Helper to throw a JSON exception
97sub _json_error {
98 my( $c, $code, $errmsg ) = @_;
99 $c->response->status( $code );
100 $c->stash->{'result'} = { 'error' => $errmsg };
101 $c->forward('View::JSON');
102 return 0;
103}
104
1051;