5 SGN::Controller::AJAX::Accessions - a REST controller class to provide the
6 backend for managing accessions
14 Jeremy Edwards <jde22@cornell.edu>
18 package SGN
::Controller
::AJAX
::Accessions
;
21 use List
::MoreUtils qw
/any /;
22 use CXGN
::Stock
::StockLookup
;
23 use CXGN
::BreedersToolbox
::Accessions
;
24 use CXGN
::BreedersToolbox
::StocksFuzzySearch
;
25 use CXGN
::BreedersToolbox
::OrganismFuzzySearch
;
26 use CXGN
::Stock
::Accession
;
27 use CXGN
::Chado
::Stock
;
31 use CXGN
::Stock
::ParseUpload
;
32 use CXGN
::BreederSearch
;
35 use JSON
::XS qw
| decode_json
|;
39 BEGIN { extends
'Catalyst::Controller::REST' }
42 default => 'application/json',
44 map => { 'application/json' => 'JSON' },
47 sub verify_accession_list
: Path
('/ajax/accession_list/verify') : ActionClass
('REST') { }
49 sub verify_accession_list_GET
: Args
(0) {
52 $self->verify_accession_list_POST($c);
55 sub verify_accession_list_POST
: Args
(0) {
60 my $session_id = $c->req->param("sgn_session_id");
63 my $dbh = $c->dbc->dbh;
64 my @user_info = CXGN
::Login
->new($dbh)->query_from_cookie($session_id);
66 $c->stash->{rest
} = {error
=>'You must be logged in to upload this info!'};
69 $user_id = $user_info[0];
70 $user_role = $user_info[1];
71 my $p = CXGN
::People
::Person
->new($dbh, $user_id);
72 $user_name = $p->get_username;
75 $c->stash->{rest
} = {error
=>'You must be logged in to upload this info!'};
78 $user_id = $c->user()->get_object()->get_sp_person_id();
79 $user_name = $c->user()->get_object()->get_username();
80 $user_role = $c->user->get_object->get_user_type();
83 my $accession_list_json = $c->req->param('accession_list');
84 my $organism_list_json = $c->req->param('organism_list');
85 my @accession_list = @
{_parse_list_from_json
($c, $accession_list_json)};
86 my @organism_list = $organism_list_json ? @
{_parse_list_from_json
($c, $organism_list_json)} : [];
88 my $do_fuzzy_search = $c->req->param('do_fuzzy_search');
89 if ($user_role ne 'curator' && !$do_fuzzy_search) {
90 $c->stash->{rest
} = {error
=>'Only a curator can add accessions without using the fuzzy search!'};
94 if ($do_fuzzy_search) {
95 $self->do_fuzzy_search($c, \
@accession_list, \
@organism_list);
98 $self->do_exact_search($c, \
@accession_list, \
@organism_list);
102 sub do_fuzzy_search
{
105 my $accession_list = shift;
106 my $organism_list = shift;
107 print STDERR
"DoFuzzySearch 1".localtime()."\n";
109 my $sp_person_id = $c->user() ?
$c->user->get_object()->get_sp_person_id() : undef;
110 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado', $sp_person_id);
111 my $fuzzy_accession_search = CXGN
::BreedersToolbox
::StocksFuzzySearch
->new({schema
=> $schema});
112 my $fuzzy_organism_search = CXGN
::BreedersToolbox
::OrganismFuzzySearch
->new({schema
=> $schema});
113 my $max_distance = 0.2;
114 my @accession_list = @
$accession_list;
115 my @organism_list = @
$organism_list;
116 my $found_accessions;
117 my $fuzzy_accessions;
118 my $absent_accessions;
121 my $absent_organisms;
124 $c->stash->{rest
} = {error
=> "You need to be logged in to add accessions." };
127 if (!any
{ $_ eq "curator" || $_ eq "submitter" } ($c->user()->roles) ) {
128 $c->stash->{rest
} = {error
=> "You have insufficient privileges to add accessions." };
131 #remove all trailing and ending spaces from accessions and organisms
132 s/^\s+|\s+$//g for @accession_list;
133 s/^\s+|\s+$//g for @organism_list;
135 my $fuzzy_search_result = $fuzzy_accession_search->get_matches(\
@accession_list, $max_distance, 'accession');
136 print STDERR
"DoFuzzySearch 2".localtime()."\n";
138 $found_accessions = $fuzzy_search_result->{'found'};
139 $fuzzy_accessions = $fuzzy_search_result->{'fuzzy'};
140 $absent_accessions = $fuzzy_search_result->{'absent'};
142 if (scalar @organism_list > 0){
143 my $fuzzy_organism_result = $fuzzy_organism_search->get_matches(\
@organism_list, $max_distance);
144 $found_organisms = $fuzzy_organism_result->{'found'};
145 $fuzzy_organisms = $fuzzy_organism_result->{'fuzzy'};
146 $absent_organisms = $fuzzy_organism_result->{'absent'};
147 #print STDERR "\n\nOrganismFuzzyResult:\n".Data::Dumper::Dumper($fuzzy_organism_result)."\n\n";
150 print STDERR
"DoFuzzySearch 3".localtime()."\n";
151 #print STDERR Dumper $fuzzy_accessions;
155 absent
=> $absent_accessions,
156 fuzzy
=> $fuzzy_accessions,
157 found
=> $found_accessions,
158 absent_organisms
=> $absent_organisms,
159 fuzzy_organisms
=> $fuzzy_organisms,
160 found_organisms
=> $found_organisms
163 if ($fuzzy_search_result->{'error'}){
164 $return{error
} = $fuzzy_search_result->{'error'};
167 $c->stash->{rest
} = \
%return;
171 sub do_exact_search
{
174 my $accession_list = shift;
176 my $sp_person_id = $c->user() ?
$c->user->get_object()->get_sp_person_id() : undef;
177 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado', $sp_person_id);
179 my @found_accessions;
180 my @fuzzy_accessions;
182 my $validator = CXGN
::List
::Validate
->new();
183 my @absent_accessions = @
{$validator->validate($schema, 'accessions', $accession_list)->{'missing'}};
184 my %accessions_missing_hash = map { $_ => 1 } @absent_accessions;
186 foreach (@
$accession_list){
187 if (!exists($accessions_missing_hash{$_})){
188 push @found_accessions, { unique_name
=> $_, matched_string
=> $_};
189 push @fuzzy_accessions, { unique_name
=> $_, matched_string
=> $_};
195 absent
=> \
@absent_accessions,
196 found
=> \
@found_accessions,
197 fuzzy
=> \
@fuzzy_accessions,
198 absent_organisms
=> [],
199 fuzzy_organisms
=> [],
200 found_organisms
=> []
203 #print STDERR Dumper($rest);
204 $c->stash->{rest
} = $rest;
207 sub verify_accessions_file
: Path
('/ajax/accessions/verify_accessions_file') : ActionClass
('REST') { }
208 sub verify_accessions_file_POST
: Args
(0) {
214 my $session_id = $c->req->param("sgn_session_id");
217 my $dbh = $c->dbc->dbh;
218 my @user_info = CXGN
::Login
->new($dbh)->query_from_cookie($session_id);
220 $c->stash->{rest
} = {error
=>'You must be logged in to upload this seedlot info!'};
223 $user_id = $user_info[0];
224 $user_role = $user_info[1];
225 my $p = CXGN
::People
::Person
->new($dbh, $user_id);
226 $user_name = $p->get_username;
229 $c->stash->{rest
} = {error
=>'You must be logged in to upload this seedlot info!'};
232 $user_id = $c->user()->get_object()->get_sp_person_id();
233 $user_name = $c->user()->get_object()->get_username();
234 $user_role = $c->user->get_object->get_user_type();
237 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado', $user_id);
238 my $upload = $c->req->upload('new_accessions_upload_file');
239 my $do_fuzzy_search = $user_role eq 'curator' && !$c->req->param('fuzzy_check_upload_accessions') ?
0 : 1;
240 my $append_synonyms = !$c->req->param('append_synonyms') ?
0 : 1;
242 if ($user_role ne 'curator' && !$do_fuzzy_search) {
243 $c->stash->{rest
} = {error
=>'Only a curator can add accessions without using the fuzzy search!'};
247 # These roles are required by CXGN::UploadFile
248 if ($user_role ne 'curator' && $user_role ne 'submitter' && $user_role ne 'sequencer' ) {
249 $c->stash->{rest
} = {error
=>'Only a curator, submitter or sequencer can upload a file'};
253 my $subdirectory = "accessions_spreadsheet_upload";
254 my $upload_original_name = $upload->filename();
255 my $upload_tempfile = $upload->tempname;
256 my $time = DateTime
->now();
257 my $timestamp = $time->ymd()."_".$time->hms();
259 ## Store uploaded temporary file in archive
260 my $uploader = CXGN
::UploadFile
->new({
261 tempfile
=> $upload_tempfile,
262 subdirectory
=> $subdirectory,
263 archive_path
=> $c->config->{archive_path
},
264 archive_filename
=> $upload_original_name,
265 timestamp
=> $timestamp,
267 user_role
=> $user_role
269 my $archived_filename_with_path = $uploader->archive();
270 my $md5 = $uploader->get_md5($archived_filename_with_path);
271 if (!$archived_filename_with_path) {
272 $c->stash->{rest
} = {error
=> "Could not save file $upload_original_name in archive",};
275 unlink $upload_tempfile;
277 my @editable_stock_props = split ',', $c->config->{editable_stock_props
};
278 my $parser = CXGN
::Stock
::ParseUpload
->new(chado_schema
=> $schema, filename
=> $archived_filename_with_path, editable_stock_props
=>\
@editable_stock_props, do_fuzzy_search
=>$do_fuzzy_search, append_synonyms
=>$append_synonyms);
279 $parser->load_plugin('AccessionsGeneric');
280 my $parsed_data = $parser->parse();
283 my $return_error = '';
285 if (!$parser->has_parse_errors() ){
286 $c->stash->{rest
} = {error_string
=> "Could not get parsing errors"};
289 $parse_errors = $parser->get_parse_errors();
290 #print STDERR Dumper $parse_errors;
292 foreach my $error_string (@
{$parse_errors->{'error_messages'}}){
293 $return_error .= $error_string."\n";
296 $c->stash->{rest
} = {error_string
=> $return_error, missing_species
=> $parse_errors->{'missing_species'}};
300 my $full_data = $parsed_data->{parsed_data
};
303 while (my ($k,$val) = each %$full_data){
304 push @accession_names, $val->{germplasmName
};
305 $full_accessions{$val->{germplasmName
}} = $val;
308 my $new_list_id = CXGN
::List
::create_list
($c->dbc->dbh, "AccessionsIn".$upload_original_name.$timestamp, 'Autocreated when upload accessions from file '.$upload_original_name.$timestamp, $user_id);
309 my $list = CXGN
::List
->new( { dbh
=> $c->dbc->dbh, list_id
=> $new_list_id } );
311 $list->add_bulk(\
@accession_names);
312 $list->type('accessions');
316 list_id
=> $new_list_id,
317 full_data
=> \
%full_accessions,
318 absent
=> $parsed_data->{absent_accessions
},
319 fuzzy
=> $parsed_data->{fuzzy_accessions
},
320 found
=> $parsed_data->{found_accessions
},
321 absent_organisms
=> $parsed_data->{absent_organisms
},
322 fuzzy_organisms
=> $parsed_data->{fuzzy_organisms
},
323 found_organisms
=> $parsed_data->{found_organisms
}
325 print STDERR
"verify_accessions_file returns: " . Dumper
%return;
326 if ($parsed_data->{error_string
}){
327 $return{error_string
} = $parsed_data->{error_string
};
331 $c->stash->{rest
} = \
%return;
334 sub verify_fuzzy_options
: Path
('/ajax/accession_list/fuzzy_options') : ActionClass
('REST') { }
336 sub verify_fuzzy_options_POST
: Args
(0) {
338 my $sp_person_id = $c->user() ?
$c->user->get_object()->get_sp_person_id() : undef;
339 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado', $sp_person_id);
340 my $accession_list_id = $c->req->param('accession_list_id');
341 my $fuzzy_option_hash = decode_json
( encode
("utf8", $c->req->param('fuzzy_option_data')));
342 my $names_to_add = _parse_list_from_json
($c, $c->req->param('names_to_add'));
343 #print STDERR Dumper $fuzzy_option_hash;
344 my $list = CXGN
::List
->new( { dbh
=> $c->dbc()->dbh(), list_id
=> $accession_list_id } );
346 my %names_to_add = map {$_ => 1} @
$names_to_add;
347 foreach my $form_name (keys %$fuzzy_option_hash){
348 my $item_name = $fuzzy_option_hash->{$form_name}->{'fuzzy_name'};
349 my $select_name = $fuzzy_option_hash->{$form_name}->{'fuzzy_select'};
350 my $fuzzy_option = $fuzzy_option_hash->{$form_name}->{'fuzzy_option'};
351 if ($fuzzy_option eq 'replace'){
352 $list->replace_by_name($item_name, $select_name);
353 delete $names_to_add{$item_name};
354 } elsif ($fuzzy_option eq 'keep'){
355 $names_to_add{$item_name} = 1;
356 } elsif ($fuzzy_option eq 'remove'){
357 $list->remove_by_name($item_name);
358 delete $names_to_add{$item_name};
359 } elsif ($fuzzy_option eq 'synonymize'){
360 my $stock_id = $schema->resultset('Stock::Stock')->find({uniquename
=>$select_name})->stock_id();
361 my $stock = CXGN
::Chado
::Stock
->new($schema, $stock_id);
362 $stock->add_synonym($item_name);
363 #$list->replace_by_name($item_name, $select_name);
364 delete $names_to_add{$item_name};
368 my @names_to_add = sort keys %names_to_add;
371 names_to_add
=> \
@names_to_add
373 #print STDERR Dumper($rest);
374 $c->stash->{rest
} = $rest;
378 sub add_accession_list
: Path
('/ajax/accession_list/add') : ActionClass
('REST') { }
380 sub add_accession_list_POST
: Args
(0) {
383 my $user_id = $c->user()->get_object()->get_sp_person_id();
384 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado', $user_id);
385 my $email_address = $c->req->param("email_address_upload");
386 my $email_option_enabled = $c->req->param("email_option_enabled");
387 print STDERR
"here is the email_address: $email_address\n";
389 my $full_info = $c->req->param('full_info') ? _parse_list_from_json
($c, $c->req->param('full_info')) : '';
390 my $allowed_organisms = $c->req->param('allowed_organisms') ? _parse_list_from_json
($c, $c->req->param('allowed_organisms')) : [];
391 my %allowed_organisms = map {$_=>1} @
$allowed_organisms;
392 my $phenome_schema = $c->dbic_schema("CXGN::Phenome::Schema", undef, $user_id);
395 $c->stash->{rest
} = {error
=> "You need to be logged in to submit accessions." };
399 my $user_name = $c->user()->get_object()->get_username();
401 if (!any
{ $_ eq "curator" || $_ eq "submitter" } ($c->user()->roles) ) {
402 $c->stash->{rest
} = {error
=> "You have insufficient privileges to submit accessions." };
406 my $type_id = SGN
::Model
::Cvterm
->get_cvterm_row($schema, 'accession', 'stock_type')->cvterm_id();
407 my $main_production_site_url = $c->config->{main_production_site_url
};
408 my @added_fullinfo_stocks;
411 my $coderef_bcs = sub {
412 foreach (@
$full_info){
413 if (exists($allowed_organisms{$_->{species
}})){
414 my $stock = CXGN
::Stock
::Accession
->new({
416 check_name_exists
=>0,
417 main_production_site_url
=>$main_production_site_url,
420 species
=>$_->{species
},
422 stock_id
=>$_->{stock_id
}, #For adding properties to an accessions
424 name
=>$_->{defaultDisplayName
},
425 uniquename
=>$_->{germplasmName
},
426 organization_name
=>$_->{organizationName
},
427 population_name
=>$_->{populationName
},
428 description
=>$_->{description
},
429 accessionNumber
=>$_->{accessionNumber
},
430 germplasmPUI
=>$_->{germplasmPUI
},
431 pedigree
=>$_->{pedigree
},
432 germplasmSeedSource
=>$_->{germplasmSeedSource
},
433 synonyms
=>$_->{synonyms
},
434 #commonCropName=>$_->{commonCropName},
435 instituteCode
=>$_->{instituteCode
},
436 instituteName
=>$_->{instituteName
},
437 biologicalStatusOfAccessionCode
=>$_->{biologicalStatusOfAccessionCode
},
438 countryOfOriginCode
=>$_->{countryOfOriginCode
},
439 typeOfGermplasmStorageCode
=>$_->{typeOfGermplasmStorageCode
},
440 #speciesAuthority=>$_->{speciesAuthority},
441 #subtaxa=>$_->{subtaxa},
442 #subtaxaAuthority=>$_->{subtaxaAuthority},
443 donors
=>$_->{donors
},
444 acquisitionDate
=>$_->{acquisitionDate
},
445 transgenic
=>$_->{transgenic
},
448 variety
=>$_->{variety
},
449 genomeStructure
=>$_->{genomeStructure
},
450 ploidyLevel
=>$_->{ploidyLevel
},
451 locationCode
=>$_->{locationCode
},
452 introgression_parent
=>$_->{introgression_parent
},
453 introgression_backcross_parent
=>$_->{introgression_backcross_parent
},
454 introgression_map_version
=>$_->{introgression_map_version
},
455 introgression_chromosome
=>$_->{introgression_chromosome
},
456 introgression_start_position_bp
=>$_->{introgression_start_position_bp
},
457 introgression_end_position_bp
=>$_->{introgression_end_position_bp
},
458 other_editable_stock_props
=>$_->{other_editable_stock_props
},
459 sp_person_id
=> $user_id,
460 user_name
=> $user_name,
461 modification_note
=> 'Bulk load of accession information'
463 my $added_stock_id = $stock->store();
464 push @added_stocks, $added_stock_id;
465 push @added_fullinfo_stocks, [$added_stock_id, $_->{germplasmName
}];
470 my $transaction_error;
471 my ($email_subject, $email_body);
473 $schema->txn_do($coderef_bcs);
475 my ($a_num, $b_num, $base_url, $accession_stocks);
476 my @sort_added_fullinfo_stocks = sort {
477 ($a_num) = $a->[1] =~ /(\d+)/;
478 ($b_num) = $b->[1] =~ /(\d+)/;
479 if (defined $a_num && defined $b_num) {
481 } elsif (defined $a_num) {
483 } elsif (defined $b_num) {
488 } @added_fullinfo_stocks;
490 if ($email_option_enabled == 1 && $email_address) {
491 # print STDERR "send email: $email_address\n";
492 print STDERR
"transaction succeeded! committing accessions\n\n";
494 $email_subject = "Accessions upload status";
495 $email_body = "Dear $user_name,\n\n";
496 $email_body.= "Congratulations, all your accessions have been successfully uploaded to the database.\n\n";
497 $email_body.= "Upload details:\n";
498 $email_body.= "Total accessions added: " . scalar(@added_stocks) . "\n\n";
499 $email_body.= "Accession ID\tAccession Name\tAccession URLs\n";
501 $base_url = "$main_production_site_url/stock/";
502 # $base_url = "http://localhost:8080/stock/";
503 # print STDERR "Added fullinfo stocks: " . Dumper \@added_fullinfo_stocks;
505 #uploading accessions upto or less than 1000 accessions
506 $accession_stocks = 0;
507 foreach my $stock (@sort_added_fullinfo_stocks) {
508 last if ($accession_stocks >= 1000);
509 $email_body .= "$stock->[0]\t$stock->[1]\t$base_url$stock->[0]/view\n";
513 #uploading more than 1000 accessions
514 if (scalar(@sort_added_fullinfo_stocks) > 1000) {
515 $email_body .= "... and more accessions are uploaded.\n";
518 $email_body.= "\nThank you.\nHave a nice day\n";
520 CXGN
::Contact
::send_email
($email_subject, $email_body, $email_address);
523 $c->stash->{rest
} = {
525 added
=> \
@added_fullinfo_stocks
526 # print STDERR Dumper \@added_fullinfo_stocks;
529 $transaction_error = $_;
530 my $error_message = "An error occurred while uploading accessions: $_\n";
531 print STDERR
$error_message;
533 if ($email_option_enabled == 1 && $email_address) {
534 $email_subject = 'Error in Accession Upload';
535 $email_body = "Dear $user_name,\n\n$error_message\n";
536 $email_body .= "Please correct these errors and try uploading again.\n\n";
537 $email_body .= "Thank you\nHave a nice day\n";
539 CXGN
::Contact
::send_email
($email_subject, $email_body, $email_address);
541 $c->stash->{rest
} = {error
=> $error_message};
543 if ($transaction_error) {
544 $c->stash->{rest
} = {error
=> "Transaction error storing stocks: $transaction_error" };
545 print STDERR
"Transaction error storing stocks: $transaction_error\n";
549 my $dbh = $c->dbc->dbh();
550 my $bs = CXGN
::BreederSearch
->new( { dbh
=>$dbh, dbname
=>$c->config->{dbname
}, } );
551 my $refresh = $bs->refresh_matviews($c->config->{dbhost
}, $c->config->{dbname
}, $c->config->{dbuser
}, $c->config->{dbpass
}, 'stockprop', 'concurrent', $c->config->{basepath
});
556 sub possible_seedlots
: Path
('/ajax/accessions/possible_seedlots') : ActionClass
('REST') { }
557 sub possible_seedlots_POST
: Args
(0) {
559 my $sp_person_id = $c->user() ?
$c->user->get_object()->get_sp_person_id() : undef;
560 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado', $sp_person_id);
561 my $people_schema = $c->dbic_schema('CXGN::People::Schema', undef, $sp_person_id);
562 my $phenome_schema = $c->dbic_schema('CXGN::Phenome::Schema', undef, $sp_person_id);
564 my $names = $c->req->body_data->{'names'};
565 my $type = $c->req->body_data->{'type'};
567 my $stock_lookup = CXGN
::Stock
::StockLookup
->new(schema
=> $schema);
568 my $accession_manager = CXGN
::BreedersToolbox
::Accessions
->new(schema
=>$schema, people_schema
=>$people_schema, phenome_schema
=>$phenome_schema);
572 if ($type eq 'accessions'){
573 $synonyms = $stock_lookup->get_stock_synonyms('any_name','accession',$names);
574 @uniquenames = keys %{$synonyms};
576 @uniquenames = @
$names;
579 my $seedlots = $accession_manager->get_possible_seedlots(\
@uniquenames, $type);
581 $c->stash->{rest
} = {
583 seedlots
=> $seedlots,
589 sub fuzzy_response_download
: Path
('/ajax/accession_list/fuzzy_download') : ActionClass
('REST') { }
591 sub fuzzy_response_download_POST
: Args
(0) {
593 my $sp_person_id = $c->user() ?
$c->user->get_object()->get_sp_person_id() : undef;
594 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado', $sp_person_id);
595 my $fuzzy_json = $c->req->param('fuzzy_response');
596 my $fuzzy_response = decode_json
(encode
("utf8", $fuzzy_json));
597 #print STDERR Dumper $fuzzy_response;
599 my $synonym_hash_lookup = CXGN
::Stock
::StockLookup
->new({schema
=> $schema})->get_synonym_hash_lookup();
601 push @data_out, ['In Your List', 'Database Accession Match', 'Database Synonym Match', 'Database Saved Synonyms', 'Distance'];
602 foreach (@
$fuzzy_response){
603 my $matches = $_->{matches
};
604 my $name = $_->{name
};
605 foreach my $m (@
$matches){
606 my $match_name = $m->{name
};
608 my $distance = $m->{distance
};
609 if ($m->{is_synonym
}){
610 $match_name = $m->{synonym_of
};
611 $synonym_of = $m->{name
};
613 my $synonyms = $synonym_hash_lookup->{$match_name};
614 my $synonyms_string = $synonyms ?
join ',', @
$synonyms : '';
615 push @data_out, [$name, $match_name, $synonym_of, $synonyms_string, $distance];
620 $string .= join("," , map {qq("$_")} @
$_);
623 $c->res->content_type("text/plain");
624 $c->res->body($string);
627 sub populations
: Path
('/ajax/manage_accessions/populations') : ActionClass
('REST') { }
629 sub populations_GET
: Args
(0) {
633 my $sp_person_id = $c->user() ?
$c->user->get_object()->get_sp_person_id() : undef;
634 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado', $sp_person_id);
635 my $ac = CXGN
::BreedersToolbox
::Accessions
->new( { schema
=>$schema });
636 my $populations = $ac->get_all_populations();
638 $c->stash->{rest
} = { populations
=> $populations };
641 sub population_members
: Path
('/ajax/manage_accessions/population_members') : ActionClass
('REST') { }
643 sub population_members_GET
: Args
(1) {
646 my $stock_id = shift;
648 my $sp_person_id = $c->user() ?
$c->user->get_object()->get_sp_person_id() : undef;
649 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado', $sp_person_id);
650 my $ac = CXGN
::BreedersToolbox
::Accessions
->new( { schema
=>$schema });
651 my $members = $ac->get_population_members($stock_id);
653 $c->stash->{rest
} = { data
=> $members };
656 sub _parse_list_from_json
{
658 my $list_json = shift;
659 my $json = JSON
::XS
->new();
662 #my $decoded_list = $json->allow_nonref->relaxed->escape_slash->loose->allow_singlequote->allow_barekey->decode($list_json);
663 debug
($c, "LIST_JSON is utf8? ".utf8
::is_utf8
($list_json)." valid utf8? ".utf8
::valid
($list_json)."\n");
664 print STDERR
"JSON NOW: $list_json\n";
665 my $decoded_list = $json->decode($list_json);# _json(encode("UTF-8", $list_json));
666 #my $decoded_list = decode_json($list_json);
668 my @array_of_list_items = ();
669 if (ref($decoded_list) eq "ARRAY" ) {
670 @array_of_list_items = @
{$decoded_list};
673 debug
($c, "Dont know what to do with $decoded_list");
676 return \
@array_of_list_items;
689 # my $encoding = find_encoding($message);
690 # open(my $F, ">> :encoding(UTF-8)", "/tmp/error_log.txt") || die "Can't open error_log.txt";
692 # print $F "### Request from ".$c->req->referer()."\n";
693 # print $F "### ENCODING: $encoding\n$message\n==========\n";