Merge pull request #5205 from solgenomics/topic/generic_trial_upload
[sgn.git] / lib / SGN / Controller / AJAX / Accessions.pm
blob2fec216059d6fbd647870adda11a6bdfc6768fad
3 =head1 NAME
5 SGN::Controller::AJAX::Accessions - a REST controller class to provide the
6 backend for managing accessions
8 =head1 DESCRIPTION
10 Managing accessions
12 =head1 AUTHOR
14 Jeremy Edwards <jde22@cornell.edu>
16 =cut
18 package SGN::Controller::AJAX::Accessions;
20 use Moose;
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;
28 use CXGN::List;
29 use Data::Dumper;
30 use Try::Tiny;
31 use CXGN::Stock::ParseUpload;
32 use CXGN::BreederSearch;
33 use Encode;
34 #use Encode::Detect;
35 use JSON::XS qw | decode_json |;
36 use utf8;
37 use CXGN::Contact;
39 BEGIN { extends 'Catalyst::Controller::REST' }
41 __PACKAGE__->config(
42 default => 'application/json',
43 stash_key => 'rest',
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) {
50 my $self = shift;
51 my $c = shift;
52 $self->verify_accession_list_POST($c);
55 sub verify_accession_list_POST : Args(0) {
56 my ($self, $c) = @_;
57 my $user_id;
58 my $user_name;
59 my $user_role;
60 my $session_id = $c->req->param("sgn_session_id");
62 if ($session_id){
63 my $dbh = $c->dbc->dbh;
64 my @user_info = CXGN::Login->new($dbh)->query_from_cookie($session_id);
65 if (!$user_info[0]){
66 $c->stash->{rest} = {error=>'You must be logged in to upload this info!'};
67 $c->detach();
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;
73 } else {
74 if (!$c->user){
75 $c->stash->{rest} = {error=>'You must be logged in to upload this info!'};
76 $c->detach();
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!'};
91 $c->detach();
94 if ($do_fuzzy_search) {
95 $self->do_fuzzy_search($c, \@accession_list, \@organism_list);
97 else {
98 $self->do_exact_search($c, \@accession_list, \@organism_list);
102 sub do_fuzzy_search {
103 my $self = shift;
104 my $c = shift;
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;
119 my $found_organisms;
120 my $fuzzy_organisms;
121 my $absent_organisms;
123 if (!$c->user()) {
124 $c->stash->{rest} = {error => "You need to be logged in to add accessions." };
125 return;
127 if (!any { $_ eq "curator" || $_ eq "submitter" } ($c->user()->roles) ) {
128 $c->stash->{rest} = {error => "You have insufficient privileges to add accessions." };
129 return;
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;
153 my %return = (
154 success => "1",
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;
168 return;
171 sub do_exact_search {
172 my $self = shift;
173 my $c = shift;
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 => $_};
193 my $rest = {
194 success => "1",
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) {
209 my ($self, $c) = @_;
211 my $user_id;
212 my $user_name;
213 my $user_role;
214 my $session_id = $c->req->param("sgn_session_id");
216 if ($session_id){
217 my $dbh = $c->dbc->dbh;
218 my @user_info = CXGN::Login->new($dbh)->query_from_cookie($session_id);
219 if (!$user_info[0]){
220 $c->stash->{rest} = {error=>'You must be logged in to upload this seedlot info!'};
221 $c->detach();
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;
227 } else {
228 if (!$c->user){
229 $c->stash->{rest} = {error=>'You must be logged in to upload this seedlot info!'};
230 $c->detach();
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!'};
244 $c->detach();
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'};
250 $c->detach();
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,
266 user_id => $user_id,
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",};
273 $c->detach();
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();
282 if (!$parsed_data) {
283 my $return_error = '';
284 my $parse_errors;
285 if (!$parser->has_parse_errors() ){
286 $c->stash->{rest} = {error_string => "Could not get parsing errors"};
287 $c->detach();
288 } else {
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'}};
297 $c->detach();
300 my $full_data = $parsed_data->{parsed_data};
301 my @accession_names;
302 my %full_accessions;
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');
314 my %return = (
315 success => "1",
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) {
337 my ($self, $c) = @_;
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;
369 my $rest = {
370 success => "1",
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) {
381 my ($self, $c) = @_;
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);
394 if (!$c->user()) {
395 $c->stash->{rest} = {error => "You need to be logged in to submit accessions." };
396 return;
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." };
403 return;
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;
409 my @added_stocks;
411 my $coderef_bcs = sub {
412 foreach (@$full_info){
413 if (exists($allowed_organisms{$_->{species}})){
414 my $stock = CXGN::Stock::Accession->new({
415 schema=>$schema,
416 check_name_exists=>0,
417 main_production_site_url=>$main_production_site_url,
418 type=>'accession',
419 type_id=>$type_id,
420 species=>$_->{species},
421 #genus=>$_->{genus},
422 stock_id=>$_->{stock_id}, #For adding properties to an accessions
423 is_saving=>1,
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},
446 notes=>$_->{notes},
447 state=>$_->{state},
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);
472 try {
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) {
480 $a_num <=> $b_num;
481 } elsif (defined $a_num) {
483 } elsif (defined $b_num) {
485 } else {
486 $a->[1] cmp $b->[1];
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";
510 $accession_stocks++;
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} = {
524 success => "1",
525 added => \@added_fullinfo_stocks
526 # print STDERR Dumper \@added_fullinfo_stocks;
528 } catch {
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";
546 return;
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});
553 return;
556 sub possible_seedlots : Path('/ajax/accessions/possible_seedlots') : ActionClass('REST') { }
557 sub possible_seedlots_POST : Args(0) {
558 my ($self, $c) = @_;
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);
570 my $synonyms;
571 my @uniquenames;
572 if ($type eq 'accessions'){
573 $synonyms = $stock_lookup->get_stock_synonyms('any_name','accession',$names);
574 @uniquenames = keys %{$synonyms};
575 } else {
576 @uniquenames = @$names;
579 my $seedlots = $accession_manager->get_possible_seedlots(\@uniquenames, $type);
581 $c->stash->{rest} = {
582 success => "1",
583 seedlots=> $seedlots,
584 synonyms=>$synonyms
586 return;
589 sub fuzzy_response_download : Path('/ajax/accession_list/fuzzy_download') : ActionClass('REST') { }
591 sub fuzzy_response_download_POST : Args(0) {
592 my ($self, $c) = @_;
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();
600 my @data_out;
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};
607 my $synonym_of = '';
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];
618 my $string ='';
619 foreach (@data_out){
620 $string .= join("," , map {qq("$_")} @$_);
621 $string .= "\n";
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) {
630 my $self = shift;
631 my $c = shift;
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) {
644 my $self = shift;
645 my $c = shift;
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 {
657 my $c = shift;
658 my $list_json = shift;
659 my $json = JSON::XS->new();
661 if ($list_json) {
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};
672 else {
673 debug($c, "Dont know what to do with $decoded_list");
676 return \@array_of_list_items;
678 else {
680 return;
684 sub debug {
685 my $c = shift;
686 my $message = shift;
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";
694 # close($F);