2 package SGN
::Controller
::AJAX
::List
;
6 use List
::MoreUtils qw
| uniq
|;
10 use CXGN
::List
::Validate
;
11 use CXGN
::List
::Transform
;
12 use CXGN
::List
::FuzzySearch
;
13 use CXGN
::List
::Desynonymize
;
17 use File
::Slurp qw
| read_file
|;
18 use File
::Temp
'tempfile';
26 BEGIN { extends
'Catalyst::Controller::REST'; }
29 default => 'application/json',
31 map => { 'application/json' => 'JSON' },
34 sub get_list_action
:Path
('/list/get') Args
(0) {
38 my $list_id = $c->req->param("list_id");
40 my $user_id = $self->get_user($c);
42 $c->stash->{rest
} = { error
=> 'You must be logged in to use lists.', };
46 my $list = $self->retrieve_list($c, $list_id);
48 $c->stash->{rest
} = $list;
51 sub get_list_data_action
:Path
('/list/data') Args
(0) {
55 my $list_id = $c->req->param("list_id");
57 my $list = CXGN
::List
->new( { dbh
=> $c->dbc->dbh, list_id
=>$list_id });
58 my $public = $list->check_if_public();
60 my $error = $self->check_user($c, $list_id);
62 $c->stash->{rest
} = { error
=> $error };
66 my $description = $list->description;
68 $list = $self->retrieve_list($c, $list_id);
70 my $metadata = $self->get_list_metadata($c, $list_id);
74 type_id
=> $metadata->{type_id
},
75 type_name
=> $metadata->{list_type
},
77 description
=> $description
82 sub retrieve_contents
:Path
('/list/contents') Args
(1) {
87 my $list = CXGN
::List
->new( { dbh
=>$c->dbc->dbh(), list_id
=>$list_id });
88 my $public = $list->check_if_public();
90 my $error = $self->check_user($c, $list_id);
92 $c->stash->{rest
} = { error
=> $error };
97 my $elements = $list->elements();
98 $c->stash->{rest
} = $elements;
101 sub get_list_metadata
{
106 my $list = CXGN
::List
->new( { dbh
=> $c->dbc->dbh(), list_id
=>$list_id });
108 return { name
=> $list->name(),
109 description
=> $list->description(),
110 type_id
=> $list->type_id(),
111 list_type
=> $list->type(),
115 sub get_type_action
:Path
('/list/type') Args
(1) {
120 my $data = $self->get_list_metadata($c, $list_id);
122 $c->stash->{rest
} = { type_id
=> $data->{type_id
},
123 list_type
=> $data->{list_type
},
127 sub update_list_name_action
:Path
('/list/name/update') :Args
(0) {
130 my $list_id = $c->req->param('list_id');
131 my $name = $c->req->param('name');
133 my $user_id = $self->get_user($c);
134 my $error = $self->check_user($c, $list_id);
137 $c->stash->{rest
} = { error
=> $error };
141 my $list = CXGN
::List
->new( { dbh
=>$c->dbc->dbh(), list_id
=>$list_id });
144 $c->stash->{rest
} = { success
=> 1 };
147 sub update_list_description_action
:Path
('/list/description/update') :Args
(0) {
150 my $list_id = $c->req->param('list_id');
151 my $description = $c->req->param('description');
153 my $user_id = $self->get_user($c);
154 my $error = $self->check_user($c, $list_id);
157 $c->stash->{rest
} = { error
=> $error };
161 my $list = CXGN
::List
->new( { dbh
=>$c->dbc->dbh(), list_id
=>$list_id });
162 $list->description($description);
164 $c->stash->{rest
} = { success
=> 1 };
167 sub set_type
:Path
('/list/type') Args
(2) {
173 my $user_id = $self->get_user($c);
175 my $error = $self->check_user($c, $list_id);
177 $c->stash->{rest
} = { error
=> $error };
181 my $list = CXGN
::List
->new( { dbh
=> $c->dbc->dbh(), list_id
=> $list_id });
183 if ($list->owner() != $user_id) {
184 $c->stash->{rest
} = { error
=> "Only the list owner can change the type of a list" };
188 $error = $list->type($type);
191 $c->stash->{rest
} = { error
=> "List type not found: ".$type };
195 $c->stash->{rest
} = { success
=> 1 };
198 sub new_list_action
:Path
('/list/new') Args
(0) {
202 my $name = $c->req->param("name");
203 my $desc = $c->req->param("desc");
206 my $user_id = $self->get_user($c);
208 $c->stash->{rest
} = { error
=> "You must be logged in to use lists", };
214 $new_list_id = $self->new_list($c, $name, $desc, $user_id);
218 $c->stash->{rest
} = { error
=> "An error occurred, $@", };
222 $c->stash->{rest
} = { list_id
=> $new_list_id };
226 sub all_types
: Path
('/list/alltypes') :Args
(0) {
230 my $all_types = CXGN
::List
::all_types
($c->dbc->dbh());
232 $c->stash->{rest
} = $all_types;
235 sub download_list
:Path
('/list/download') Args
(0) {
238 my $list_id = $c->req->param("list_id");
240 my $list = CXGN
::List
->new( { dbh
=> $c->dbc->dbh, list_id
=>$list_id });
241 my $public = $list->check_if_public();
243 my $error = $self->check_user($c, $list_id);
245 $c->res->content_type("text/plain");
246 $c->res->body($error);
251 $list = $self->retrieve_list($c, $list_id);
252 my ($name_ref) = $self->get_list_metadata($c, $list_id);
253 my $name = $name_ref->{name
};
255 $c->res->content_type("text/plain");
256 $c->res->header('Content-Disposition'=>"attachment; filename=$name.txt");
257 $c->res->body(join "\n", map { $_->[1] } @
$list);
260 =head2 available_lists()
263 Desc: returns the available lists. Optionally, a
264 parameter "list_type" can be provided that will limit the
265 lists to the provided type.
274 sub available_lists
: Path
('/list/available') Args
(0) {
278 my $requested_type = $c->req->param("type");
280 my $user_id = $self->get_user($c);
282 $c->stash->{rest
} = { error
=> "You must be logged in to use lists.", };
286 my $lists = CXGN
::List
::available_lists
($c->dbc->dbh(), $user_id, $requested_type);
288 $c->stash->{rest
} = $lists;
291 sub available_public_lists
: Path
('/list/available_public') Args
(0) {
295 my $requested_type = $c->req->param("type");
297 my $user_id = $self->get_user($c);
299 $c->stash->{rest
} = { error
=> "You must be logged in to use lists." };
303 my $lists = CXGN
::List
::available_public_lists
($c->dbc->dbh(), $requested_type);
305 $c->stash->{rest
} = $lists;
308 sub add_item
:Path
('/list/item/add') Args
(0) {
312 my $list_id = $c->req->param("list_id");
313 my $element = $c->req->param("element");
315 my $user_id = $self->get_user($c);
317 my $error = $self->check_user($c, $list_id);
319 $c->stash->{rest
} = { error
=> $error };
323 $element =~ s/^\s*(.+?)\s*$/$1/;
326 $c->stash->{rest
} = { error
=> "You must provide an element to add to the list" };
331 $c->stash->{rest
} = { error
=> "Please specify a list_id." };
336 $self->insert_element($c, $list_id, $element);
339 $c->stash->{rest
} = { error
=> "An error occurred: $@" };
343 $c->stash->{rest
} = [ "SUCCESS" ];
347 sub toggle_public_list
: Path
('/list/public/toggle') Args
(0) {
350 my $list_id = $c->req->param("list_id");
352 my $error = $self->check_user($c, $list_id);
354 $c->stash->{rest
} = { error
=> $error };
358 my $list = CXGN
::List
->new( { dbh
=> $c->dbc->dbh, list_id
=>$list_id });
359 my ($public, $rows_affected) = $list->toggle_public();
360 if ($rows_affected == 1) {
361 $c->stash->{rest
} = { r
=> $public };
367 sub make_public_list
: Path
('/list/public/true') Args
(0) {
370 my $list_id = $c->req->param("list_id");
372 my $error = $self->check_user($c, $list_id);
374 $c->stash->{rest
} = { error
=> $error };
378 my $list = CXGN
::List
->new( { dbh
=> $c->dbc->dbh, list_id
=>$list_id });
379 my ($rows_affected) = $list->make_public();
380 if ($rows_affected == 1) {
381 $c->stash->{rest
} = { success
=>1 };
387 sub make_private_list
: Path
('/list/public/false') Args
(0) {
390 my $list_id = $c->req->param("list_id");
392 my $error = $self->check_user($c, $list_id);
394 $c->stash->{rest
} = { error
=> $error };
398 my $list = CXGN
::List
->new( { dbh
=> $c->dbc->dbh, list_id
=>$list_id });
399 my ($rows_affected) = $list->make_private();
400 if ($rows_affected == 1) {
401 $c->stash->{rest
} = { success
=>1 };
407 sub copy_public_list
: Path
('/list/public/copy') Args
(0) {
410 my $list_id = $c->req->param("list_id");
412 my $list = CXGN
::List
->new( { dbh
=> $c->dbc->dbh, list_id
=>$list_id });
413 my $public = $list->check_if_public();
414 my $user_id = $self->get_user($c);
415 if (!$user_id || $public == 0) {
416 $c->stash->{rest
} = { error
=> 'You must be logged in to use lists and list must be public!' };
420 my $copied = $list->copy_public($user_id);
422 $c->stash->{rest
} = { success
=> 'true' };
428 sub sort_list_items
: Path
('/list/sort') Args
(0) {
431 my $list_id = $c->req->param("list_id");
432 my $sort = $c->req->param("sort");
434 my $list = CXGN
::List
->new( { dbh
=> $c->dbc->dbh, list_id
=>$list_id });
435 my $return = $list->sort_items($sort);
437 $c->stash->{rest
} = { success
=> 1 };
439 $c->stash->{rest
} = { error
=> 1 };
443 sub add_cross_progeny
: Path
('/list/add_cross_progeny') Args
(0) {
446 my $sp_person_id = $c->user() ?
$c->user->get_object()->get_sp_person_id() : undef;
447 my $cross_id_list = decode_json
($c->req->param("cross_id_list"));
448 #print STDERR Dumper $cross_id_list;
449 my $list_id = $c->req->param("list_id");
451 my $list = CXGN
::List
->new( { dbh
=>$c->dbc->dbh(), list_id
=> $list_id });
454 $response{'count'} = 0;
455 foreach (@
$cross_id_list) {
456 my $cross = CXGN
::Cross
->new({ schema
=> $c->dbic_schema("Bio::Chado::Schema", undef, $sp_person_id), cross_stock_id
=>$_});
457 my ($maternal_parent, $paternal_parent, $progeny) = $cross->get_cross_relationships();
460 foreach (@
$progeny) {
461 push @accession_names, $_->[0];
464 my $r = $list->add_bulk(\
@accession_names);
466 $c->stash->{rest
} = { error
=> $r->{error
}};
469 if (scalar(@
{$r->{duplicates
}}) > 0){
470 $response{'duplicates'} = $r->{duplicates
};
472 $response{'count'} += $r->{count
};
474 #print STDERR Dumper \%response;
475 $c->stash->{rest
} = { duplicates
=> $response{'duplicates'} };
476 $c->stash->{rest
}->{success
} = { count
=> $response{'count'} };
479 sub add_bulk
: Path
('/list/add/bulk') Args
(0) {
482 my $list_id = $c->req->param("list_id");
483 my $elements = $c->req->param("elements");
485 my $user_id = $self->get_user($c);
486 my $error = $self->check_user($c, $list_id);
488 $c->stash->{rest
} = { error
=> $error };
493 $c->stash->{rest
} = { error
=> "You must provide one or more elements to add to the list" };
497 my @elements = split "\t", $elements;
499 my $list = CXGN
::List
->new( { dbh
=>$c->dbc->dbh(), list_id
=> $list_id });
504 my $response = $list->add_bulk(\
@elements);
505 #print STDERR Dumper $response;
507 if ($response->{error
}) {
508 $c->stash->{rest
} = { error
=> $response->{error
}};
511 if (scalar(@
{$response->{duplicates
}}) > 0){
512 $c->stash->{rest
} = { duplicates
=> $response->{duplicates
} };
515 $c->stash->{rest
}->{success
} = $response->{count
};
518 sub insert_element
: Private
{
524 my $list = CXGN
::List
->new( { dbh
=>$c->dbc->dbh(), list_id
=> $list_id });
526 $list->add_bulk([$element]);
529 sub delete_list_action
:Path
('/list/delete') Args
(0) {
533 my $list_id = $c->req->param("list_id");
535 my $error = $self->check_user($c, $list_id);
537 $c->stash->{rest
} = { error
=> $error };
541 $error = CXGN
::List
::delete_list
($c->dbc->dbh(), $list_id);
544 $c->stash->{rest
} = { error
=> $error };
547 $c->stash->{rest
} = [ 1 ];
552 sub exists_list_action
: Path
('/list/exists') Args
(0) {
555 my $name = $c->req->param("name") || undef;
557 my $user_id = $self->get_user($c);
559 $c->stash->{rest
} = { error
=> 'You need to be logged in to use lists.' };
562 my $list_info = CXGN
::List
::exists_list
($c->dbc->dbh(), $name, $user_id);
564 print STDERR
"List info is ".Dumper
($list_info);
565 $c->stash->{rest
} = $list_info;
569 sub exists_item_action
: Path
('/list/exists_item') :Args
(0) {
572 my $list_id = $c->req->param("list_id");
573 my $name = $c->req->param("name");
575 my $error = $self->check_user($c, $list_id);
577 $c->stash->{rest
} = { error
=> $error };
581 my $user_id = $self->get_user($c);
583 if ($self->get_list_owner($c, $list_id) != $user_id) {
584 $c->stash->{rest
} = { error
=> "You have insufficient privileges to manipulate this list.", };
588 my $list_item_id = $self->exists_item($c, $list_id, $name);
591 $c->stash->{rest
} = { list_item_id
=> $list_item_id };
594 $c->stash->{rest
} = { list_item_id
=> 0 };
598 sub list_size
: Path
('/list/size') Args
(0) {
601 my $list_id = $c->req->param("list_id");
603 my $list = CXGN
::List
->new( { dbh
=> $c->dbc->dbh, list_id
=>$list_id });
604 my $count = $list->list_size();
606 $c->stash->{rest
} = { count
=> $count };
610 # Validate an existing list for a specified data type
612 # PATH: GET /list/validate/{list}/{type}
613 # {list} is the list id
614 # {type} is the name of the supported list type (accessions, trials, seedlots, etc...)
617 # missing: array list item names not in the database
619 sub validate
: Path
('/list/validate') Args
(2) {
624 my $sp_person_id = $c->user() ?
$c->user->get_object()->get_sp_person_id() : undef;
626 my $list = $self->retrieve_list($c, $list_id);
628 my @flat_list = map { $_->[1] } @
$list;
630 my $lv = CXGN
::List
::Validate
->new();
631 my $data = $lv->validate($c->dbic_schema("Bio::Chado::Schema", undef, $sp_person_id), $type, \
@flat_list);
633 print STDERR
"DATA = ".Dumper
($data);
634 $c->stash->{rest
} = $data;
637 sub validate_lists
:Path
('/ajax/list/validate_lists') Args
(0) {
641 my $list_ids_string = $c->req->param('list_ids');
642 my $list_types_string = $c->req->param('list_types');
644 my @list_ids = split /\,/, $list_ids_string;
645 my @list_types = split /\,/, $list_types_string;
647 my @invalid_lists = ();
648 for (my $n = 0; $n<@list_ids; $n++) {
650 my $list = $self->retrieve_list($c, $list_ids[$n]);
652 my @flat_list = map { $_->[1] } @
$list;
654 print STDERR
"LIST TYPE = ".$list_types[$n]."\n";
655 my $lv = CXGN
::List
::Validate
->new();
656 my $sp_person_id = $c->user() ?
$c->user->get_object()->get_sp_person_id() : undef;
657 my $data = $lv->validate($c->dbic_schema("Bio::Chado::Schema", undef, $sp_person_id), $list_types[$n], \
@flat_list);
660 print STDERR
"Return data = ".Dumper
($data);
662 if ($list_types[$n] eq "accessions" && $data->{valid
} == 0) {
663 print STDERR
"list $list_ids[$n] is invalid! ($data->{valid}) \n";
664 push @invalid_lists, [ $list_ids[$n], $list_types[$n] ];
666 elsif ($list_types[$n] ne "accessions" && scalar(@
{$data->{missing
}}) > 0) {
667 print STDERR
"list $list_ids[$n] is invalid! (missing = ".scalar(@
{$data->{missing
}}).")\n";
668 push @invalid_lists, [ $list_ids[$n], $list_types[$n] ];
672 print STDERR
"List $list_ids[$n] of type $list_types[$n] is valid :-) \n";
675 $c->stash->{rest
} = { invalid_lists
=> \
@invalid_lists };
679 # Validate a temp list of names for a specified data type
680 # - Validate the temp list
681 # - Return lists of missing and existing items
683 # PATH: POST /list/validate/temp
686 # type: the name of a supported list type (accessions, trials, seedlots, etc...)
687 # items: array of item names to validate
690 # error: error message, if an error was encountered
691 # missing: array list item names not in the database
692 # existing: array list item names found in the database
694 sub temp_validate
: Path
('/list/validate/temp') ActionClass
('REST') {};
695 sub temp_validate_POST
: Args
(0) {
698 my $type = $c->req->param("type");
699 my $items = $c->req->param("items") ? decode_json
$c->req->param("items") : [];
701 my $lv = CXGN
::List
::Validate
->new();
702 my $sp_person_id = $c->user() ?
$c->user->get_object()->get_sp_person_id() : undef;
703 my $data = $lv->validate($c->dbic_schema("Bio::Chado::Schema", undef, $sp_person_id), $type, $items);
706 my $m = $data->{missing
};
709 my %comp = map { $_ => 1 } @
$m;
710 my @e = grep !$comp{$_}, @
$items;
712 $c->stash->{rest
} = {
718 sub fuzzysearch
: Path
('/list/fuzzysearch') Args
(2) {
722 my $list_type = shift;
724 my $list = $self->retrieve_list($c, $list_id);
726 my @flat_list = map { $_->[1] } @
$list;
728 my $f = CXGN
::List
::FuzzySearch
->new();
729 my $sp_person_id = $c->user() ?
$c->user->get_object()->get_sp_person_id() : undef;
730 my $data = $f->fuzzysearch($c->dbic_schema("Bio::Chado::Schema", undef, $sp_person_id), $list_type, \
@flat_list);
732 $c->stash->{rest
} = $data;
735 sub transform
:Path
('/list/transform/') Args
(2) {
739 my $transform_name = shift;
741 my $t = CXGN
::List
::Transform
->new();
743 my $data = $self->get_list_metadata($c, $list_id);
745 my $list_data = $self->retrieve_list($c, $list_id);
747 my @list_items = map { $_->[1] } @
$list_data;
748 my $sp_person_id = $c->user() ?
$c->user->get_object()->get_sp_person_id() : undef;
749 my $result = $t->transform($c->dbic_schema("Bio::Chado::Schema", undef, $sp_person_id), $transform_name, \
@list_items);
751 if (exists($result->{missing
}) && (scalar(@
{$result->{missing
}}) > 0)) {
752 $result->{error
} = "Warning. This lists contains elements that cannot be converted.";
755 $c->stash->{rest
} = $result;
759 sub temp_transform
:Path
('/list/transform/temp') Args
(0) {
762 my $type = $c->req->param("type");
763 my $items = $c->req->param("items") ? decode_json
$c->req->param("items") : [];
765 my $t = CXGN
::List
::Transform
->new();
766 my $sp_person_id = $c->user() ?
$c->user->get_object()->get_sp_person_id() : undef;
767 my $result = $t->transform($c->dbic_schema("Bio::Chado::Schema", undef, $sp_person_id), $type, $items);
769 if (exists($result->{missing
}) && (scalar(@
{$result->{missing
}}) > 0)) {
770 $result->{error
} = "Warning. This temporary list contains elements that cannot be converted.";
773 $c->stash->{rest
} = $result;
777 sub replace_elements
:Path
('/list/item/replace') Args
(2) {
782 my $new_list = shift; # tab delimited new list elements
786 sub combine_lists
: Path
('/list/combine') Args
(2) {
789 my $list1_id = shift;
790 my $list2_id = shift;
792 my $list1 = $self->get_list($c, $list1_id);
793 my $list2 = $self->get_list($c, $list2_id);
795 my $combined_list_id = $self->new_list(
797 $list1->{name
}."_".$list2->{name
},
798 $list1->{description
}.", ".$list2->{description
});
800 my @combined_elements = (@
{$list1->{elements
}}, @
{$list2->{elements
}});
802 my @unique_elements = uniq
(@combined_elements);
804 foreach my $item (@unique_elements) {
805 $self->add_item($c, $combined_list_id, $item);
809 sub intersect_lists
: Path
('/list/intersect') Args
(2) {
812 my $list1_id = shift;
813 my $list2_id = shift;
815 my $list1 = $self->get_list($c, $list1_id);
816 my $list2 = $self->get_list($c, $list2_id);
818 my $combined_list_id = $self->new_list(
820 $list1->{name
}."_".$list2->{name
}."_intersect",
821 $list1->{description
}.", ".$list2->{description
});
823 my @intersect_elements = ();
825 my $list1_hashref; my $list2_hashref;
826 map { $list1_hashref->{$_}=1 } @
{$list1->{elements
}};
827 map { $list2_hashref->{$_}=1 } @
{$list2->{elements
}};
829 foreach my $item (keys(%{$list1_hashref})) {
830 if (exists($list1_hashref->{$item}) && exists($list2_hashref->{$item})) {
831 push @intersect_elements, $item;
835 my @unique_elements = uniq
(@intersect_elements);
837 foreach my $item (@unique_elements) {
838 $self->add_item($c, $combined_list_id, $item);
843 sub remove_element_action
:Path
('/list/item/remove') Args
(0) {
847 my $list_id = $c->req->param("list_id");
848 my $item_id = $c->req->param("item_id");
850 my $error = $self->check_user($c, $list_id);
853 $c->stash->{rest
} = { error
=> $error };
857 my $response = $self->remove_element($c, $list_id, $item_id);
859 $c->stash->{rest
} = $response;
863 sub update_element_action
:Path
('/list/item/update') Args
(0) {
867 my $list_id = $c->req->param("list_id");
868 my $item_id = $c->req->param("item_id");
869 my $content = $c->req->param("content");
870 my $error = $self->check_user($c, $list_id);
873 print STDERR
"update ".$list_id." ".$item_id." ".$content."\n";
876 $c->stash->{rest
} = { error
=> $error };
880 my $list = CXGN
::List
->new( { dbh
=> $c->dbc()->dbh(), list_id
=> $list_id });
881 $error = $list->update_element_by_id($item_id, $content);
885 $c->stash->{rest
} = { error
=> "An error occurred while attempting to update item $item_id" };
888 $c->stash->{rest
} = { success
=> 1 };
892 sub new_list
: Private
{
895 my ($name, $desc, $owner) = @_;
897 my $user_id = $self->get_user($c);
899 my $new_list_id = CXGN
::List
::create_list
($c->dbc->dbh(), $name, $desc, $owner);
905 sub get_list
: Private
{
910 my $list = $self->retrieve_list($c, $list_id);
912 my ($name, $desc, $type_id, $list_type) = $self->get_list_metadata($c, $list_id);
914 $c->stash->{rest
} = {
916 description
=> $desc,
918 type_name
=> $list_type,
923 sub retrieve_list
: Private
{
928 my $list = CXGN
::List
->new( { dbh
=> $c->dbc->dbh, list_id
=>$list_id });
929 my $public = $list->check_if_public();
931 my $error = $self->check_user($c, $list_id);
933 $c->stash->{rest
} = { error
=> $error };
937 my $list_elements_with_ids = $list->retrieve_elements_with_ids($list_id);
939 #print STDERR "LIST ELEMENTS WITH IDS: ".Dumper($list_elements_with_ids);
940 return $list_elements_with_ids;
944 sub remove_element
: Private
{
951 my $list = CXGN
::List
->new( { dbh
=> $c->dbc()->dbh(), list_id
=> $list_id });
952 my $error = $list->remove_element_by_id($item_id);
955 return { error
=> "An error occurred while attempting to delete item $item_id" };
958 return { success
=> 1 };
963 sub exists_item
: Private
{
969 my $list = CXGN
::List
->new( { dbh
=> $c->dbc()->dbh(), list_id
=> $list_id });
970 my $list_item_id = $list->exists_element($item);
971 return $list_item_id;
974 sub get_list_owner
: Private
{
979 my $list = CXGN
::List
->new( { dbh
=> $c->dbc()->dbh(), list_id
=> $list_id });
980 my $owner = $list->owner();
985 sub get_user
: Private
{
989 my $user = $c->user();
992 my $user_object = $c->user->get_object();
993 return $user_object->get_sp_person_id();
998 sub check_user
: Private
{
1001 my $list_id = shift;
1003 my $user_id = $self->get_user($c);
1008 $error = "You must be logged in to manipulate this list.";
1010 elsif ($c->user->get_object->get_user_type() ne 'curator' && $self->get_list_owner($c, $list_id) != $user_id) {
1011 $error = "You have insufficient privileges to manipulate this list.";
1016 sub desynonymize_list
: Path
('/list/desynonymize') Args
(0) {
1020 my $list_id = $c->req->param("list_id");
1022 my $user_id = $self->get_user($c);
1024 $c->stash->{rest
} = { error
=> 'You must be logged in to use lists.', };
1027 my $schema = $c->dbic_schema("Bio::Chado::Schema", undef, $user_id);
1028 my $dbh = $schema->storage->dbh;
1030 my $list = CXGN
::List
->new( { dbh
=> $dbh, list_id
=> $list_id } );
1031 my $flat_list = $list->retrieve_elements_with_ids($list_id);
1032 my @name_list = map {@
{$_}[1]} @
{$flat_list};
1033 my $dsyner = CXGN
::List
::Desynonymize
->new();
1034 my $results = $dsyner
1035 ->desynonymize($schema,$list->type(),\
@name_list);
1036 $results->{'previous_list'} = \
@name_list;
1037 $results->{'list_type'} = $list->type();
1039 $c->stash->{rest
} = $results;
1043 sub available_marker_sets
: Path
('/marker_sets/available') Args
(0) {
1047 my $user_id = $self->get_user($c);
1049 $c->stash->{rest
} = { error
=> "You must be logged in to use markerset.", };
1053 my $lists = CXGN
::List
::available_lists
($c->dbc->dbh(), $user_id, 'markers');
1055 foreach my $list (@
$lists){
1056 my ($id, $name, $desc, $item_count, $type_id, $type, $public) = @
$list;
1057 push @marker_sets, {
1058 markerset_id
=> $id,
1059 markerset_name
=> $name,
1060 number_of_markers
=> $item_count - 1,
1061 description
=> $desc,
1065 $c->stash->{rest
} = {data
=> \
@marker_sets};
1069 sub delete_markerset
: Path
('/markerset/delete') Args
(0) {
1073 my $user_id = $self->get_user($c);
1075 $c->stash->{rest
} = { error
=> 'You must be logged in to delete markerset.', };
1079 my $markerset_id = $c->req->param("markerset_id");
1081 my $error = $self->check_user($c, $markerset_id);
1083 $c->stash->{rest
} = { error
=> $error };
1087 $error = CXGN
::List
::delete_list
($c->dbc->dbh(), $markerset_id);
1090 $c->stash->{rest
} = { success
=> 1 };
1093 $c->stash->{rest
} = { error
=> $error };
1099 sub get_markerset_items
:Path
('/markerset/items') Args
(0) {
1102 my $markerset_id = $c->req->param("markerset_id");
1103 my $sp_person_id = $c->user() ?
$c->user->get_object()->get_sp_person_id() : undef;
1104 my $schema = $c->dbic_schema("Bio::Chado::Schema", "sgn_chado", $sp_person_id);
1106 my $user_id = $self->get_user($c);
1108 $c->stash->{rest
} = { error
=> 'You must be logged in to use markerset.', };
1112 my $markerset = CXGN
::List
->new({dbh
=> $schema->storage->dbh, list_id
=> $markerset_id});
1113 my $markerset_items_ref = $markerset->retrieve_elements_with_ids($markerset_id);
1116 foreach my $markerset_item (@
$markerset_items_ref){
1117 my ($id, $name) = @
$markerset_item;
1124 $c->stash->{rest
} = {success
=> 1, data
=> \
@items};
1129 sub get_markerset_type
:Path
('/markerset/type') Args
(0) {
1132 my $markerset_id = $c->req->param("markerset_id");
1133 my $sp_person_id = $c->user() ?
$c->user->get_object()->get_sp_person_id() : undef;
1134 my $schema = $c->dbic_schema("Bio::Chado::Schema", "sgn_chado", $sp_person_id);
1136 my $user_id = $self->get_user($c);
1138 $c->stash->{rest
} = { error
=> 'You must be logged in to use markerset.', };
1142 my $markerset = CXGN
::List
->new({dbh
=> $schema->storage->dbh, list_id
=> $markerset_id});
1143 my $markerset_items_ref = $markerset->retrieve_elements($markerset_id);
1144 my @markerset_items = @
{$markerset_items_ref};
1147 foreach my $item (@markerset_items){
1148 my $item_ref = decode_json
$item;
1149 my %item_hash = %{$item_ref};
1150 my $markerset_type = $item_hash{genotyping_data_type
};
1152 if ($markerset_type){
1153 $type = $markerset_type;
1156 # print STDERR "MARKERSET TYPE =".Dumper($type)."\n";
1157 $c->stash->{rest
} = {success
=> 1, type
=> $type};
1162 sub adjust_case
: Path
('/ajax/list/adjust_case') Args
(0) {
1165 my $list_id = $c->req->param("list_id");
1167 my $user_id = $self->get_user($c);
1169 $c->stash->{rest
} = { error
=> "You must be logged in to use lists.", };
1173 my $list = CXGN
::List
->new( { dbh
=> $c->dbc->dbh, list_id
=> $list_id } );
1175 if ($user_id != $list->owner()) {
1176 $c->stash->{rest
} = { error
=> "You don't own this list and you cannot modify it." };
1180 if ($list->type() ne "accessions") {
1181 $c->stash->{rest
} = { error
=> "Only lists with type 'accessions' can be adjusted for case in the database." };
1184 my $lt = CXGN
::List
::Transform
->new();
1185 my $elements = $list->elements();
1187 print STDERR
"Elements: ".Dumper
($elements);
1189 my $schema = $c->dbic_schema("Bio::Chado::Schema", undef, $user_id);
1191 my $data = $lt->transform($schema, 'accessions_2_accession_case', $elements);
1193 print STDERR
"Converted data: ".Dumper
($data);
1196 $c->stash->{rest
} = { error
=> "No data!" };
1199 my $error_message = "";
1200 my $replace_count = 0;
1202 foreach my $item (@
$elements) {
1203 print STDERR
"Replacing element $item...\n";
1204 if ($data->{mapping
}->{$item}) {
1205 print STDERR
" with $data->{mapping}->{$item}...\n";
1206 my $error = $list->replace_by_name($item, $data->{mapping
}->{$item});
1208 $error_message .= "Error: $item not replaced. ";
1216 $c->stash->{rest
} = {
1217 transform
=> $data->{transform
},
1218 error
=> $error_message,
1219 replace_count
=> $replace_count,
1220 missing
=> $data->{missing
} || [],
1221 duplicated
=> $data->{duplicated
} || [],
1222 mapping
=> $data->{mapping
},
1227 sub adjust_synonyms
:Path
('/ajax/list/adjust_synonyms') Args
(0) {
1231 my $list_id = $c->req->param("list_id");
1233 my $user_id = $self->get_user($c);
1235 $c->stash->{rest
} = { error
=> "You must be logged in to use lists.", };
1239 my $list = CXGN
::List
->new( { dbh
=> $c->dbc->dbh, list_id
=> $list_id } );
1241 if ($user_id != $list->owner()) {
1242 $c->stash->{rest
} = { error
=> "You don't own this list and you cannot modify it." };
1246 if ($list->type() ne "accessions") {
1247 $c->stash->{rest
} = { error
=> "Only lists with type 'accessions' can be adjusted for synonyms in the database." };
1250 my $lt = CXGN
::List
::Transform
->new();
1251 my $elements = $list->elements();
1252 print STDERR
"Elements: ".Dumper
($elements);
1254 my $schema = $c->dbic_schema("Bio::Chado::Schema", undef, $user_id);
1256 my $data = $lt->transform($schema, 'synonyms2accession_uniquename', $elements);
1258 print STDERR
"Converted data: ".Dumper
($data);
1260 print STDERR Dumper
($data);
1263 $c->stash->{rest
} = { error
=> "No data!" };
1266 my $error_message = "";
1267 my $replace_count = 0;
1269 foreach my $item (@
$elements) {
1270 print STDERR
"Replacing element $item...\n";
1271 if ($data->{mapping
}->{$item}) {
1272 print STDERR
" with $data->{mapping}->{$item}...\n";
1273 my $error = $list->replace_by_name($item, $data->{mapping
}->{$item});
1275 $error_message .= "Error: $item not replaced. ";
1283 $c->stash->{rest
} = {
1284 transform
=> $data->{transform
},
1285 error
=> $error_message,
1286 replace_count
=> $replace_count,
1287 missing
=> $data->{missing
} || [],
1288 duplicated
=> $data->{duplicated
} || [],
1289 mapping
=> $data->{mapping
},
1294 sub get_list_details
:Path
('/ajax/list/details') :Args
(1) {
1297 my $list_id = shift;
1298 my $sp_person_id = $c->user() ?
$c->user->get_object()->get_sp_person_id() : undef;
1299 my $schema = $c->dbic_schema('Bio::Chado::Schema', 'sgn_chado', $sp_person_id);
1300 my $phenome_schema = $c->dbic_schema("CXGN::Phenome::Schema", undef, $sp_person_id);
1301 my $dbh = $c->dbc->dbh;
1303 my $list = CXGN
::List
->new( { dbh
=>$dbh, schema
=>$schema, phenome_schema
=>$phenome_schema, list_id
=>$list_id });
1304 my $type = $list->type();
1305 my $items = $list->elements();
1307 my $item_validator = CXGN
::List
::Validate
->new();
1308 my @items_missing = @
{$item_validator->validate($schema, $type, $items)->{'missing'}};
1309 if (scalar(@items_missing) > 0){
1310 $c->stash->{rest
} = {error
=> "The following items are not in the database: ".join(',',@items_missing)};
1315 if ($type eq 'seedlots') {
1316 my $result = $list->seedlot_list_details();
1317 my @details = @
$result;
1318 foreach my $seedlot (@details) {
1319 push @list_details, {
1320 seedlot_id
=> $seedlot->[0],
1321 seedlot_name
=> $seedlot->[1],
1322 content_id
=> $seedlot->[2],
1323 content_name
=> $seedlot->[3],
1324 content_type
=> $seedlot->[4],
1325 description
=> $seedlot->[5],
1326 box_name
=> $seedlot->[6],
1327 current_count
=> $seedlot->[7],
1328 current_weight
=> $seedlot->[8],
1329 quality
=> $seedlot->[9],
1334 $c->stash->{rest
} = {data
=> \
@list_details};
1339 sub download_list_details
: Path
('/list/download_details') {
1342 my $sp_person_id = $c->user() ?
$c->user->get_object()->get_sp_person_id() : undef;
1343 my $schema = $c->dbic_schema("Bio::Chado::Schema", "sgn_chado", $sp_person_id);
1344 my $phenome_schema = $c->dbic_schema("CXGN::Phenome::Schema", undef, $sp_person_id);
1345 my $dbh = $c->dbc->dbh;
1347 my $list_id = $c->req->param("list_id");
1348 my $list = CXGN
::List
->new( { dbh
=>$dbh, schema
=>$schema, phenome_schema
=>$phenome_schema, list_id
=>$list_id });
1349 my $type = $list->type();
1350 my $list_name = $list->name();
1354 if ($type eq 'seedlots') {
1355 my $result = $list->seedlot_list_details();
1356 my @details = @
$result;
1357 foreach my $seedlot_ref (@details) {
1358 my @seedlot = @
$seedlot_ref;
1359 push @list_details, "$seedlot[1]\t$seedlot[3]\t$seedlot[4]\t$seedlot[5]\t$seedlot[6]\t$seedlot[7]\t$seedlot[8]\t$seedlot[9]\n";
1361 $header = "Seedlot_Name\tContent_Name\tContent_type\tDescription\tBox_Name\tCurrent_Count\tCurrent_Weight\tQuality";
1364 my $dl_token = $c->req->param("list_download_token") || "no_token";
1365 my $dl_cookie = "download".$dl_token;
1366 print STDERR
"Token is: $dl_token\n";
1368 my ($tempfile, $uri) = $c->tempfile(TEMPLATE
=> "list_details_download_XXXXX", UNLINK
=> 0);
1370 open(my $FILE, '> :encoding(UTF-8)', $tempfile) or die "Cannot open tempfile $tempfile: $!";
1371 print $FILE $header."\n";
1373 foreach my $each_row (@list_details) {
1374 print $FILE $each_row;
1379 $c->res->content_type("application/text");
1380 $c->res->cookies->{$dl_cookie} = {
1385 $c->res->header("Content-Disposition", qq[attachment
; filename
="$list_name.txt"]);
1387 open(my $F, "< :encoding(UTF-8)", $tempfile) || die "Can't open file $tempfile for reading.";
1393 $c->res->body($output);