2 package SGN
::Controller
::AJAX
::List
;
6 use List
::MoreUtils qw
| uniq
|;
10 use CXGN
::List
::Validate
;
11 use CXGN
::List
::Transform
;
13 BEGIN { extends
'Catalyst::Controller::REST'; }
16 default => 'application/json',
18 map => { 'application/json' => 'JSON', 'text/html' => 'JSON' },
21 sub get_list_action
:Path
('/list/get') Args
(0) {
25 my $list_id = $c->req->param("list_id");
27 my $user_id = $self->get_user($c);
29 $c->stash->{rest
} = { error
=> 'You must be logged in to use lists.', };
33 my $list = $self->retrieve_list($c, $list_id);
35 $c->stash->{rest
} = $list;
38 sub get_list_data_action
:Path
('/list/data') Args
(0) {
42 my $list_id = $c->req->param("list_id");
44 my $list = CXGN
::List
->new( { dbh
=> $c->dbc->dbh, list_id
=>$list_id });
45 my $public = $list->check_if_public();
47 my $error = $self->check_user($c, $list_id);
49 $c->stash->{rest
} = { error
=> $error };
54 $list = $self->retrieve_list($c, $list_id);
56 my $metadata = $self->get_list_metadata($c, $list_id);
60 type_id
=> $metadata->{type_id
},
61 type_name
=> $metadata->{list_type
},
67 sub retrieve_contents
:Path
('/list/contents') Args
(1) {
72 my $error = $self->check_user($c, $list_id);
74 $c->stash->{rest
} = { error
=> $error };
78 my $list = CXGN
::List
->new( { dbh
=>$c->dbc->dbh(), list_id
=>$list_id });
80 my $elements = $list->elements();
81 $c->stash->{rest
} = $elements;
84 sub get_list_metadata
{
89 my $list = CXGN
::List
->new( { dbh
=> $c->dbc->dbh(), list_id
=>$list_id });
91 return { name
=> $list->name(),
92 description
=> $list->description(),
93 type_id
=> $list->type_id(),
94 list_type
=> $list->type(),
98 sub get_type_action
:Path
('/list/type') Args
(1) {
103 my $data = $self->get_list_metadata($c, $list_id);
105 $c->stash->{rest
} = { type_id
=> $data->{type_id
},
106 list_type
=> $data->{list_type
},
110 sub update_list_name_action
:Path
('/list/name/update') :Args
(0) {
113 my $list_id = $c->req->param('list_id');
114 my $name = $c->req->param('name');
116 my $user_id = $self->get_user($c);
117 my $error = $self->check_user($c, $list_id);
120 $c->stash->{rest
} = { error
=> $error };
124 my $list = CXGN
::List
->new( { dbh
=>$c->dbc->dbh(), list_id
=>$list_id });
126 $error = $list->name($name);
129 $c->stash->{rest
} = { error
=> $error };
133 $c->stash->{rest
} = { success
=> 1 };
136 sub set_type
:Path
('/list/type') Args
(2) {
142 my $user_id = $self->get_user($c);
144 my $error = $self->check_user($c, $list_id);
146 $c->stash->{rest
} = { error
=> $error };
150 my $list = CXGN
::List
->new( { dbh
=> $c->dbc->dbh(), list_id
=> $list_id });
152 if ($list->owner() != $user_id) {
153 $c->stash->{rest
} = { error
=> "Only the list owner can change the type of a list" };
157 $error = $list->type($type);
160 $c->stash->{rest
} = { error
=> "List type not found: ".$type };
164 $c->stash->{rest
} = { success
=> 1 };
167 sub new_list_action
:Path
('/list/new') Args
(0) {
171 my $name = $c->req->param("name");
172 my $desc = $c->req->param("desc");
175 my $user_id = $self->get_user($c);
177 $c->stash->{rest
} = { error
=> "You must be logged in to use lists", };
183 $new_list_id = $self->new_list($c, $name, $desc, $user_id);
187 $c->stash->{rest
} = { error
=> "An error occurred, $@", };
191 $c->stash->{rest
} = { list_id
=> $new_list_id };
195 sub all_types
: Path
('/list/alltypes') :Args
(0) {
199 my $all_types = CXGN
::List
::all_types
($c->dbc->dbh());
201 $c->stash->{rest
} = $all_types;
204 sub download_list
:Path
('/list/download') Args
(0) {
207 my $list_id = $c->req->param("list_id");
209 my $list = CXGN
::List
->new( { dbh
=> $c->dbc->dbh, list_id
=>$list_id });
210 my $public = $list->check_if_public();
212 my $error = $self->check_user($c, $list_id);
214 $c->res->content_type("text/plain");
215 $c->res->body($error);
220 $list = $self->retrieve_list($c, $list_id);
222 $c->res->content_type("text/plain");
223 $c->res->body(join "\n", map { $_->[1] } @
$list);
226 =head2 available_lists()
229 Desc: returns the available lists. Optionally, a
230 parameter "list_type" can be provided that will limit the
231 lists to the provided type.
240 sub available_lists
: Path
('/list/available') Args
(0) {
244 my $requested_type = $c->req->param("type");
246 my $user_id = $self->get_user($c);
248 $c->stash->{rest
} = { error
=> "You must be logged in to use lists.", };
252 my $lists = CXGN
::List
::available_lists
($c->dbc->dbh(), $user_id, $requested_type);
254 $c->stash->{rest
} = $lists;
257 sub available_public_lists
: Path
('/list/available_public') Args
(0) {
261 my $requested_type = $c->req->param("type");
263 my $user_id = $self->get_user($c);
265 $c->stash->{rest
} = { error
=> "You must be logged in to use lists.", };
269 my $lists = CXGN
::List
::available_public_lists
($c->dbc->dbh(), $requested_type);
271 $c->stash->{rest
} = $lists;
274 sub add_item
:Path
('/list/item/add') Args
(0) {
278 my $list_id = $c->req->param("list_id");
279 my $element = $c->req->param("element");
281 my $user_id = $self->get_user($c);
283 my $error = $self->check_user($c, $list_id);
285 $c->stash->{rest
} = { error
=> $error };
289 $element =~ s/^\s*(.+?)\s*$/$1/;
292 $c->stash->{rest
} = { error
=> "You must provide an element to add to the list" };
297 $c->stash->{rest
} = { error
=> "Please specify a list_id." };
302 $self->insert_element($c, $list_id, $element);
305 $c->stash->{rest
} = { error
=> "An error occurred: $@" };
309 $c->stash->{rest
} = [ "SUCCESS" ];
313 sub toggle_public_list
: Path
('/list/public/toggle') Args
(0) {
316 my $list_id = $c->req->param("list_id");
318 my $error = $self->check_user($c, $list_id);
320 $c->stash->{rest
} = { error
=> $error };
324 my $list = CXGN
::List
->new( { dbh
=> $c->dbc->dbh, list_id
=>$list_id });
325 my ($public, $rows_affected) = $list->toggle_public();
326 if ($rows_affected == 1) {
327 $c->stash->{rest
} = { r
=> $public };
333 sub make_public_list
: Path
('/list/public/true') Args
(0) {
336 my $list_id = $c->req->param("list_id");
338 my $error = $self->check_user($c, $list_id);
340 $c->stash->{rest
} = { error
=> $error };
344 my $list = CXGN
::List
->new( { dbh
=> $c->dbc->dbh, list_id
=>$list_id });
345 my ($rows_affected) = $list->make_public();
346 if ($rows_affected == 1) {
347 $c->stash->{rest
} = { success
=>1 };
353 sub make_private_list
: Path
('/list/public/false') Args
(0) {
356 my $list_id = $c->req->param("list_id");
358 my $error = $self->check_user($c, $list_id);
360 $c->stash->{rest
} = { error
=> $error };
364 my $list = CXGN
::List
->new( { dbh
=> $c->dbc->dbh, list_id
=>$list_id });
365 my ($rows_affected) = $list->make_private();
366 if ($rows_affected == 1) {
367 $c->stash->{rest
} = { success
=>1 };
373 sub copy_public_list
: Path
('/list/public/copy') Args
(0) {
376 my $list_id = $c->req->param("list_id");
378 my $list = CXGN
::List
->new( { dbh
=> $c->dbc->dbh, list_id
=>$list_id });
379 my $public = $list->check_if_public();
380 my $user_id = $self->get_user($c);
381 if (!$user_id || $public == 0) {
382 $c->stash->{rest
} = { error
=> 'You must be logged in to use lists and list must be public!' };
386 my $copied = $list->copy_public($user_id);
388 $c->stash->{rest
} = { success
=> 'true' };
394 sub add_bulk
: Path
('/list/add/bulk') Args
(0) {
397 my $list_id = $c->req->param("list_id");
398 my $elements = $c->req->param("elements");
400 my $user_id = $self->get_user($c);
401 my $error = $self->check_user($c, $list_id);
403 $c->stash->{rest
} = { error
=> $error };
408 $c->stash->{rest
} = { error
=> "You must provide one or more elements to add to the list" };
412 my @elements = split "\t", $elements;
414 my $list = CXGN
::List
->new( { dbh
=>$c->dbc->dbh(), list_id
=> $list_id });
419 my $response = $list->add_bulk(\
@elements);
420 #print STDERR Dumper $response;
422 if ($response->{error
}) {
423 $c->stash->{rest
} = { error
=> $response->{error
}};
426 if (scalar(@
{$response->{duplicates
}}) > 0){
427 $c->stash->{rest
} = { duplicates
=> $response->{duplicates
} };
430 $c->stash->{rest
}->{success
} = $response->{count
};
433 sub insert_element
: Private
{
439 my $list = CXGN
::List
->new( { dbh
=>$c->dbc->dbh(), list_id
=> $list_id });
441 $list->add_element($element);
444 sub delete_list_action
:Path
('/list/delete') Args
(0) {
448 my $list_id = $c->req->param("list_id");
450 my $error = $self->check_user($c, $list_id);
452 $c->stash->{rest
} = { error
=> $error };
456 $error = CXGN
::List
::delete_list
($c->dbc->dbh(), $list_id);
459 $c->stash->{rest
} = { error
=> $error };
462 $c->stash->{rest
} = [ 1 ];
467 sub exists_list_action
: Path
('/list/exists') Args
(0) {
470 my $name = $c->req->param("name");
472 my $user_id = $self->get_user($c);
474 $c->stash->{rest
} = { error
=> 'You need to be logged in to use lists.' };
477 my $list_id = CXGN
::List
::exists_list
($c->dbc->dbh(), $name, $user_id);
480 $c->stash->{rest
} = { list_id
=> $list_id };
483 $c->stash->{rest
} = { list_id
=> undef };
487 sub exists_item_action
: Path
('/list/exists_item') :Args
(0) {
490 my $list_id = $c->req->param("list_id");
491 my $name = $c->req->param("name");
493 my $error = $self->check_user($c, $list_id);
495 $c->stash->{rest
} = { error
=> $error };
499 my $user_id = $self->get_user($c);
501 if ($self->get_list_owner($c, $list_id) != $user_id) {
502 $c->stash->{rest
} = { error
=> "You have insufficient privileges to manipulate this list.", };
506 my $list_item_id = $self->exists_item($c, $list_id, $name);
509 $c->stash->{rest
} = { list_item_id
=> $list_item_id };
512 $c->stash->{rest
} = { list_item_id
=> 0 };
516 sub list_size
: Path
('/list/size') Args
(0) {
519 my $list_id = $c->req->param("list_id");
521 my $list = CXGN
::List
->new( { dbh
=> $c->dbc->dbh, list_id
=>$list_id });
522 my $count = $list->list_size();
524 $c->stash->{rest
} = { count
=> $count };
527 sub validate
: Path
('/list/validate') Args
(2) {
533 my $list = $self->retrieve_list($c, $list_id);
535 my @flat_list = map { $_->[1] } @
$list;
537 my $lv = CXGN
::List
::Validate
->new();
538 my $data = $lv->validate($c->dbic_schema("Bio::Chado::Schema"), $type, \
@flat_list);
540 $c->stash->{rest
} = $data;
543 sub transform
:Path
('/list/transform/') Args
(2) {
547 my $transform_name = shift;
549 my $t = CXGN
::List
::Transform
->new();
551 my $data = $self->get_list_metadata($c, $list_id);
553 my $list_data = $self->retrieve_list($c, $list_id);
555 my @list_items = map { $_->[1] } @
$list_data;
557 my $result = $t->transform($c->dbic_schema("Bio::Chado::Schema"), $transform_name, \
@list_items);
559 if (exists($result->{missing
}) && (scalar(@
{$result->{missing
}}) > 0)) {
560 $c->stash->{rest
} = { error
=> "This lists contains elements that cannot be converted. Not converting list.", };
564 $c->stash->{rest
} = $result;
568 sub replace_elements
:Path
('/list/item/replace') Args
(2) {
573 my $new_list = shift; # tab delimited new list elements
577 sub combine_lists
: Path
('/list/combine') Args
(2) {
580 my $list1_id = shift;
581 my $list2_id = shift;
583 my $list1 = $self->get_list($c, $list1_id);
584 my $list2 = $self->get_list($c, $list2_id);
586 my $combined_list_id = $self->new_list(
588 $list1->{name
}."_".$list2->{name
},
589 $list1->{description
}.", ".$list2->{description
});
591 my @combined_elements = (@
{$list1->{elements
}}, @
{$list2->{elements
}});
593 my @unique_elements = uniq
(@combined_elements);
595 foreach my $item (@unique_elements) {
596 $self->add_item($c, $combined_list_id, $item);
600 sub intersect_lists
: Path
('/list/intersect') Args
(2) {
603 my $list1_id = shift;
604 my $list2_id = shift;
606 my $list1 = $self->get_list($c, $list1_id);
607 my $list2 = $self->get_list($c, $list2_id);
609 my $combined_list_id = $self->new_list(
611 $list1->{name
}."_".$list2->{name
}."_intersect",
612 $list1->{description
}.", ".$list2->{description
});
614 my @intersect_elements = ();
616 my $list1_hashref; my $list2_hashref;
617 map { $list1_hashref->{$_}=1 } @
{$list1->{elements
}};
618 map { $list2_hashref->{$_}=1 } @
{$list2->{elements
}};
620 foreach my $item (keys(%{$list1_hashref})) {
621 if (exists($list1_hashref->{$item}) && exists($list2_hashref->{$item})) {
622 push @intersect_elements, $item;
626 my @unique_elements = uniq
(@intersect_elements);
628 foreach my $item (@unique_elements) {
629 $self->add_item($c, $combined_list_id, $item);
634 sub remove_element_action
:Path
('/list/item/remove') Args
(0) {
638 my $list_id = $c->req->param("list_id");
639 my $item_id = $c->req->param("item_id");
641 my $error = $self->check_user($c, $list_id);
644 $c->stash->{rest
} = { error
=> $error };
648 my $response = $self->remove_element($c, $list_id, $item_id);
650 $c->stash->{rest
} = $response;
654 sub update_element_action
:Path
('/list/item/update') Args
(0) {
658 my $list_id = $c->req->param("list_id");
659 my $item_id = $c->req->param("item_id");
660 my $content = $c->req->param("content");
661 print STDERR
"update ".$list_id." ".$item_id." ".$content."\n";
663 my $error = $self->check_user($c, $list_id);
666 $c->stash->{rest
} = { error
=> $error };
670 my $list = CXGN
::List
->new( { dbh
=> $c->dbc()->dbh(), list_id
=> $list_id });
671 $error = $list->update_element_by_id($item_id, $content);
674 $c->stash->{rest
} = { error
=> "An error occurred while attempting to update item $item_id" };
677 $c->stash->{rest
} = { success
=> 1 };
681 sub new_list
: Private
{
684 my ($name, $desc, $owner) = @_;
686 my $user_id = $self->get_user($c);
688 my $new_list_id = CXGN
::List
::create_list
($c->dbc->dbh(), $name, $desc, $owner);
694 sub get_list
: Private
{
699 my $list = $self->retrieve_list($c, $list_id);
701 my ($name, $desc, $type_id, $list_type) = $self->get_list_metadata($c, $list_id);
703 $c->stash->{rest
} = {
705 description
=> $desc,
707 type_name
=> $list_type,
712 sub retrieve_list
: Private
{
717 my $list = CXGN
::List
->new( { dbh
=> $c->dbc->dbh, list_id
=>$list_id });
718 my $public = $list->check_if_public();
720 my $error = $self->check_user($c, $list_id);
722 $c->stash->{rest
} = { error
=> $error };
726 my $list_elements_with_ids = $list->retrieve_elements_with_ids($list_id);
728 #print STDERR "LIST ELEMENTS WITH IDS: ".Dumper($list_elements_with_ids);
729 return $list_elements_with_ids;
733 sub remove_element
: Private
{
740 my $list = CXGN
::List
->new( { dbh
=> $c->dbc()->dbh(), list_id
=> $list_id });
741 my $error = $list->remove_element_by_id($item_id);
744 return { error
=> "An error occurred while attempting to delete item $item_id" };
747 return { success
=> 1 };
752 sub exists_item
: Private
{
758 my $list = CXGN
::List
->new( { dbh
=> $c->dbc()->dbh(), list_id
=> $list_id });
759 my $list_item_id = $list->exists_element($item);
760 return $list_item_id;
763 sub get_list_owner
: Private
{
768 my $list = CXGN
::List
->new( { dbh
=> $c->dbc()->dbh(), list_id
=> $list_id });
769 my $owner = $list->owner();
774 sub get_user
: Private
{
778 my $user = $c->user();
781 my $user_object = $c->user->get_object();
782 return $user_object->get_sp_person_id();
787 sub check_user
: Private
{
792 my $user_id = $self->get_user($c);
797 $error = "You must be logged in to manipulate this list.";
800 elsif ($self->get_list_owner($c, $list_id) != $user_id) {
801 $error = "You have insufficient privileges to manipulate this list.";