4 SGN::Controller::AJAX::FieldBook - a REST controller class to provide the
5 backend for field book operations
9 Creating and viewing trials
13 Jeremy Edwards <jde22@cornell.edu>
17 package SGN
::Controller
::AJAX
::FieldBook
;
20 use List
::MoreUtils qw
/any /;
21 use Scalar
::Util
qw(looks_like_number);
24 use File
::Basename qw
| basename dirname
|;
27 use File
::Spec
::Functions
;
29 use JSON
-support_by_pp
;
30 use Spreadsheet
::WriteExcel
;
31 use SGN
::View
::Trial qw
/design_layout_view design_info_view/;
32 use CXGN
::Location
::LocationLookup
;
33 use CXGN
::Stock
::StockLookup
;
35 use CXGN
::Fieldbook
::TraitInfo
;
36 use CXGN
::Fieldbook
::DownloadTrial
;
37 use SGN
::Model
::Cvterm
;
39 use CXGN
::List
::Validate
;
40 use CXGN
::List
::Transform
;
43 BEGIN { extends
'Catalyst::Controller::REST' }
46 default => 'application/json',
48 map => { 'application/json' => 'JSON', 'text/html' => 'JSON' },
52 sub create_fieldbook_from_trial
: Path
('/ajax/fieldbook/create') : ActionClass
('REST') { }
54 sub create_fieldbook_from_trial_POST
: Args
(0) {
56 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
57 my $trial_id = $c->req->param('trial_id');
58 my $data_level = $c->req->param('data_level') || 'plots';
59 my $treatment_project_ids = $c->req->param('treatment_project_id') ?
[$c->req->param('treatment_project_id')] : [];
60 my $metadata_schema = $c->dbic_schema('CXGN::Metadata::Schema');
61 my $phenome_schema = $c->dbic_schema('CXGN::Phenome::Schema');
65 $c->stash->{rest
} = {error
=> "You need to be logged in to create a field book" };
68 if (!any
{ $_ eq "curator" || $_ eq "submitter" } ($c->user()->roles) ) {
69 $c->stash->{rest
} = {error
=> "You have insufficient privileges to create a field book." };
73 $c->stash->{rest
} = {error
=> "No trial ID supplied." };
76 my $trial = $schema->resultset('Project::Project')->find({project_id
=> $trial_id});
78 $c->stash->{rest
} = {error
=> "Trial does not exist with id $trial_id." };
81 if ($data_level eq 'plants') {
82 my $trial = CXGN
::Trial
->new( { bcs_schema
=> $schema, trial_id
=> $trial_id });
83 if (!$trial->has_plant_entries()){
84 $c->stash->{rest
} = {error
=> "Trial does not have plant entries. You must first create plant entries." };
88 if ($data_level eq 'subplots' || $data_level eq 'plants_subplots') {
89 my $trial = CXGN
::Trial
->new( { bcs_schema
=> $schema, trial_id
=> $trial_id });
90 if (!$trial->has_subplot_entries()) {
91 $c->stash->{rest
} = {error
=> "Trial does not have subplot entries." };
96 my $selected_columns = $c->req->param('selected_columns') ? decode_json
$c->req->param('selected_columns') : {};
97 my $selected_trait_list_id = $c->req->param('trait_list');
100 if ($selected_trait_list_id){
101 my $list = CXGN
::List
->new({ dbh
=> $c->dbc->dbh, list_id
=> $selected_trait_list_id });
102 @trait_list = @
{$list->elements()};
103 my $validator = CXGN
::List
::Validate
->new();
104 my @absent_traits = @
{$validator->validate($schema, 'traits', \
@trait_list)->{'missing'}};
105 if (scalar(@absent_traits)>0){
106 $c->stash->{rest
} = {error
=> "Trait list is not valid because of these terms: ".join ',',@absent_traits };
109 my $lt = CXGN
::List
::Transform
->new();
110 @selected_traits = @
{$lt->transform($schema, "traits_2_trait_ids", \
@trait_list)->{transform
}};
113 my $dir = $c->tempfiles_subdir('/other');
114 my $tempfile = $c->config->{basepath
}."/".$c->tempfile( TEMPLATE
=> 'other/excelXXXX');
116 my $create_fieldbook = CXGN
::Fieldbook
::DownloadTrial
->new({
117 bcs_schema
=> $schema,
118 metadata_schema
=> $metadata_schema,
119 phenome_schema
=> $phenome_schema,
120 trial_id
=> $trial_id,
121 tempfile
=> $tempfile,
122 archive_path
=> $c->config->{archive_path
},
123 user_id
=> $c->user()->get_object()->get_sp_person_id(),
124 user_name
=> $c->user()->get_object()->get_username(),
125 data_level
=> $data_level,
126 treatment_project_ids
=> $treatment_project_ids,
127 selected_columns
=> $selected_columns,
128 selected_trait_ids
=> \
@selected_traits,
129 selected_trait_names
=> \
@trait_list
132 my $create_fieldbook_return = $create_fieldbook->download();
134 if ($create_fieldbook_return->{'error_messages'}){
135 $error = join ',', @
{$create_fieldbook_return->{'error_messages'}};
138 $c->stash->{rest
} = {
139 error_string
=> $error,
141 result
=> $create_fieldbook_return->{'result'},
142 file
=> $create_fieldbook_return->{'file'},
143 file_id
=> $create_fieldbook_return->{'file_id'},
147 sub create_trait_file_for_field_book
: Path
('/ajax/fieldbook/traitfile/create') : ActionClass
('REST') { }
149 sub create_trait_file_for_field_book_POST
: Args
(0) {
153 $c->stash->{rest
} = {error
=> "You need to be logged in to create a field book" };
156 if (!any
{ $_ eq "curator" || $_ eq "submitter" } ($c->user()->roles) ) {
157 $c->stash->{rest
} = {error
=> "You have insufficient privileges to create a field book." };
162 my $trait_file_name = $c->req->param('trait_file_name');
163 my $user_id = $c->user()->get_object()->get_sp_person_id();
164 my $user_name = $c->user()->get_object()->get_username();
165 my $time = DateTime
->now();
166 my $timestamp = $time->ymd()."_".$time->hms();
167 my $subdirectory_name = "tablet_trait_files";
168 my $archived_file_name = catfile
($user_id, $subdirectory_name,$timestamp."_".$trait_file_name.".trt");
169 my $archive_path = $c->config->{archive_path
};
170 my $file_destination = catfile
($archive_path, $archived_file_name);
171 my $dbh = $c->dbc->dbh();
172 my @trait_ids = @
{_parse_list_from_json
($c->req->param('trait_ids'))};
174 if ($c->req->param('trait_list')) {
175 @trait_list = @
{_parse_list_from_json
($c->req->param('trait_list'))};
178 if (!-d
$archive_path) {
182 if (! -d catfile
($archive_path, $user_id)) {
183 mkdir (catfile
($archive_path, $user_id));
186 if (! -d catfile
($archive_path, $user_id,$subdirectory_name)) {
187 mkdir (catfile
($archive_path, $user_id, $subdirectory_name));
190 open FILE
, ">$file_destination" or die $!;
191 my $chado_schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado');
192 print FILE
"trait,format,defaultValue,minimum,maximum,details,categories,isVisible,realPosition\n";
195 foreach my $term (@trait_list) {
196 #print STDERR "term is $term\n";
197 my @parts = split (/\|/ , $term);
198 my ($db_name, $accession) = split ":", pop @parts;
199 my $trait_name = join ("|", @parts);
200 #print STDERR "trait name is $trait_name, full cvterm accession is $full_cvterm_accession\n";
201 #my ( $db_name , $accession ) = split (/:/ , $full_cvterm_accession);
203 $accession =~ s/\s+$//;
204 $accession =~ s/^\s+//;
205 $db_name =~ s/\s+$//;
206 $db_name =~ s/^\s+//;
208 my $cvterm = CXGN
::Chado
::Cvterm
->new( $dbh, $trait_ids[$order] );
209 my $synonym = $cvterm->get_uppercase_synonym();
210 my $name = $synonym || $trait_name; # use uppercase synonym if defined, otherwise use full trait name
215 my $trait_info_lookup = CXGN
::Fieldbook
::TraitInfo
217 chado_schema
=> $chado_schema,
219 trait_accession
=> $accession,
221 my $trait_info_string = $trait_info_lookup->get_trait_info($trait_name);
223 #return error if not $trait_info_string;
224 #print line with trait info
225 #print FILE "$trait_name:$db_name:$accession,text,,,,,,TRUE,$order\n";
226 print STDERR
" Adding line \"$name\t\t\t|$db_name:$accession\",$trait_info_string,\"TRUE\",\"$order\" to trait file\n";
227 print FILE
"\"$name\t\t\t|$db_name:$accession\",$trait_info_string,\"TRUE\",\"$order\"\n";
232 open(my $F, "<", $file_destination) || die "Can't open file ";
234 my $md5 = Digest
::MD5
->new();
238 my $metadata_schema = $c->dbic_schema('CXGN::Metadata::Schema');
240 my $md_row = $metadata_schema->resultset("MdMetadata")->create({
241 create_person_id
=> $user_id,
245 my $file_row = $metadata_schema->resultset("MdFiles")->create({
246 basename
=> basename
($file_destination),
247 dirname
=> dirname
($file_destination),
248 filetype
=> 'tablet trait file',
249 md5checksum
=> $md5->hexdigest(),
250 metadata_id
=> $md_row->metadata_id(),
254 my $id = $file_row->file_id();
256 $c->stash->{rest
} = {success
=> "1", file_id
=> $id, };
261 sub _parse_list_from_json
{
262 my $list_json = shift;
265 my $decoded_list = $json->allow_nonref->utf8->relaxed->escape_slash->loose->allow_singlequote->allow_barekey->decode($list_json);
266 #my $decoded_list = decode_json($list_json);
267 my @array_of_list_items = @
{$decoded_list};
268 return \
@array_of_list_items;