Browse files

Merge pull request #268 from jaredbischof/develop

Added inbox resource to new API.
  • Loading branch information...
2 parents bcbd707 + 5f9979e commit a643a1344f3a87b18fa48bfe881cd95e1c5053b2 @teharrison teharrison committed Mar 1, 2013
View
180 src/MGRAST/lib/resources2/inbox.pm
@@ -0,0 +1,180 @@
+package resources2::inbox;
+
+use strict;
+use warnings;
+no warnings('once');
+
+use Data::Dumper;
+use Conf;
+use parent qw(resources2::resource);
+
+# Override parent constructor
+sub new {
+ my ($class, @args) = @_;
+
+ # Call the constructor of the parent class
+ my $self = $class->SUPER::new(@args);
+
+ # Add name
+ $self->{name} = "inbox";
+ return $self;
+}
+
+# resource is called without any parameters
+# this method must return a description of the resource
+sub info {
+ my ($self) = @_;
+ my $content = { 'name' => $self->name,
+ 'url' => $self->cgi->url."/".$self->name,
+ 'description' => "inbox receives user inbox data upload, requires authentication, see http://blog.metagenomics.anl.gov/mg-rast-v3-2-faq/#api_submission for details",
+ 'type' => 'object',
+ 'documentation' => $Conf::cgi_url.'/Html/api.html#'.$self->name,
+ 'requests' => [ { 'name' => "info",
+ 'request' => $self->cgi->url."/".$self->name,
+ 'description' => "Returns description of parameters and attributes.",
+ 'method' => "GET",
+ 'type' => "synchronous",
+ 'attributes' => "self",
+ 'parameters' => { 'options' => {},
+ 'required' => {},
+ 'body' => {} } },
+ { 'name' => "view",
+ 'request' => $self->cgi->url."/".$self->name."/view",
+ 'description' => "lists the contents of the user inbox",
+ 'method' => "GET",
+ 'type' => "synchronous",
+ 'attributes' => { 'id' => [ 'string', "user login" ],
+ 'timestamp' => [ 'string', "timestamp for return of this query" ],
+ 'files' => [ 'list', [ 'object', [ { 'filename' => [ 'string', "path of file from within user inbox" ],
+ 'filesize' => [ 'string', "disk size of file in bytes" ],
+ 'timestamp' => [ 'string', "timestamp of file" ]
+ }, "list of file objects"] ] ],
+ 'url' => [ 'uri', "resource location of this object instance" ] },
+ 'parameters' => { 'options' => {},
+ 'required' => { "auth" => [ "string", "unique string of text generated by MG-RAST for your account" ] },
+ 'body' => {} } },
+ { 'name' => "upload",
+ 'request' => $self->cgi->url."/".$self->name."/upload",
+ 'description' => "receives user inbox data upload",
+ 'method' => "POST",
+ 'type' => "synchronous",
+ 'attributes' => { 'id' => [ 'string', "user login" ],
+ 'status' => [ 'string', "status message" ],
+ 'timestamp' => [ 'string', "timestamp for return of this query" ]
+ },
+ 'parameters' => { 'options' => {},
+ 'required' => { "auth" => [ "string", "unique string of text generated by MG-RAST for your account" ] },
+ 'body' => {} } }
+ ]
+ };
+
+ $self->return_data($content);
+}
+
+sub instance {
+ my ($self) = @_;
+
+ if (($self->rest->[0] eq 'upload') && ($self->method eq 'POST')) {
+ $self->upload_file();
+ } elsif ($self->rest->[0] eq 'view') {
+ $self->view_inbox();
+ } else {
+ $self->info();
+ }
+}
+
+sub view_inbox {
+ my ($self) = @_;
+
+ my $black_list = "USER";
+ my $black_list_seq_ext = "stats_info|error_log|lock|";
+ if($self->user) {
+ use Digest::MD5 qw(md5_hex);
+ my $base_dir = "$Conf::incoming";
+ my $udir = $base_dir."/".md5_hex($self->user->login);
+ my @files = ();
+ foreach my $file (`ls $udir`) {
+ chomp $file;
+ if(-d "$udir/$file") {
+ my $subdir = $file;
+ foreach my $subfile (`ls $udir/$subdir`) {
+ chomp $subfile;
+ unless($subfile =~ /^$black_list$/ || $subfile =~ /^\S+\.($black_list_seq_ext)$/) {
+ my $filesize = -s "$udir/$subdir/$subfile";
+ my $timestamp = scalar localtime((stat("$udir/$subdir/$subfile"))[9]);
+ push @files, { 'filename' => "$subdir/$subfile",
+ 'filesize', => $filesize." bytes",
+ 'timestamp', => $timestamp };
+ }
+ }
+ } else {
+ unless($file =~ /^$black_list$/ || $file =~ /^\S+\.($black_list_seq_ext)$/) {
+ my $filesize = -s "$udir/$file";
+ my $timestamp = scalar localtime((stat("$udir/$file"))[9]);
+ push @files, { 'filename' => $file,
+ 'filesize', => $filesize." bytes",
+ 'timestamp', => $timestamp };
+ }
+ }
+ }
+ $self->return_data( { 'id' => $self->user->login,
+ 'timestamp' => scalar localtime,
+ 'files' => \@files,
+ 'url' => $self->cgi->url."/".$self->name."/view" } );
+ } else {
+ $self->return_data( {"ERROR" => "authentication failed"}, 401 );
+ }
+}
+
+sub upload_file {
+ my ($self) = @_;
+
+ if($self->user) {
+ use Digest::MD5 qw(md5_hex);
+ my $base_dir = "$Conf::incoming";
+ my $udir = $base_dir."/".md5_hex($self->user->login);
+ my $fn = $self->cgi->param('upload');
+
+ if ($fn) {
+
+ if ($fn =~ /\.\./) {
+ $self->return_data( {"ERROR" => "invalid parameters, trying to change directory with filename, aborting"}, 400 );
+ }
+
+ if ($fn !~ /^[\w\d_\.\-\:\, ]+$/) {
+ $self->return_data({"ERROR" => "Invalid parameters, filename allows only word, underscore, dash, colon, comma, dot (.), space, and number characters"}, 400);
+ }
+
+ if (-f "$udir/$fn") {
+ $self->return_data( {"ERROR" => "the file already exists"}, 400 );
+ }
+
+ my $fh = $self->cgi->upload('upload');
+ if (defined $fh) {
+ my $io_handle = $fh->handle;
+ if (open FH, ">$udir/$fn") {
+ my ($bytesread, $buffer);
+ while ($bytesread = $io_handle->read($buffer,4096)) {
+ print FH $buffer;
+ }
+ close FH;
+ $self->return_data( { 'id' => $self->user->login,
+ 'status' => "data received successfully",
+ 'timestamp' => scalar localtime } );
+ } else {
+ $self->return_data( {"ERROR" => "storing object failed - could not open target file"}, 507 );
+ }
+ } else {
+ $self->return_data( {"ERROR" => "storing object failed - could not obtain filehandle"}, 507 );
+ }
+
+ } else {
+ $self->return_data( {"ERROR" => "invalid parameters, requires filename and data"}, 400 );
+ }
+
+ } else {
+ $self->return_data( {"ERROR" => "authentication failed"}, 401 );
+ }
+}
+
+1;
View
28 src/MGRAST/lib/resources2/project.pm
@@ -182,23 +182,23 @@ sub prepare_data {
if ($self->cgi->param('verbosity')) {
if ($self->cgi->param('verbosity') eq 'full') {
- my @jobs = map { ["mgm".$_, $url.'/metagenome/mgm'.$_] } @{ $project->all_metagenome_ids };
- my @colls = @{ $project->collections };
- my @samples = map { ["mgs".$_->{ID}, $url."/sample/mgs".$_->{ID}] } grep { $_ && ref($_) && ($_->{type} eq 'sample') } @colls;
- my @libraries = map { ["mgl".$_->{ID}, $url."/library/mgl".$_->{ID}] } grep { $_ && ref($_) && ($_->{type} eq 'library') } @colls;
- $obj->{analyzed} = \@jobs;
- $obj->{samples} = \@samples;
- $obj->{libraries} = \@libraries;
+ my @jobs = map { ["mgm".$_, $url.'/metagenome/mgm'.$_] } @{ $project->all_metagenome_ids };
+ my @colls = @{ $project->collections };
+ my @samples = map { ["mgs".$_->{ID}, $url."/sample/mgs".$_->{ID}] } grep { $_ && ref($_) && ($_->{type} eq 'sample') } @colls;
+ my @libraries = map { ["mgl".$_->{ID}, $url."/library/mgl".$_->{ID}] } grep { $_ && ref($_) && ($_->{type} eq 'library') } @colls;
+ $obj->{analyzed} = \@jobs;
+ $obj->{samples} = \@samples;
+ $obj->{libraries} = \@libraries;
}
if (($self->cgi->param('verbosity') eq 'verbose') || ($self->cgi->param('verbosity') eq 'full')) {
- my $metadata = $project->data();
- my $desc = $metadata->{project_description} || $metadata->{study_abstract} || " - ";
- my $fund = $metadata->{project_funding} || " - ";
- $obj->{metadata} = $metadata;
- $obj->{description} = $desc;
- $obj->{funding_source} = $fund;
+ my $metadata = $project->data();
+ my $desc = $metadata->{project_description} || $metadata->{study_abstract} || " - ";
+ my $fund = $metadata->{project_funding} || " - ";
+ $obj->{metadata} = $metadata;
+ $obj->{description} = $desc;
+ $obj->{funding_source} = $fund;
} elsif ($self->cgi->param('verbosity') ne 'minimal') {
- $self->return_data( {"ERROR" => "invalid value for option verbosity"}, 400 );
+ $self->return_data( {"ERROR" => "invalid value for option verbosity"}, 400 );
}
}
push @$objects, $obj;
View
12 src/MGRAST/lib/resources2/status.pm
@@ -17,6 +17,12 @@ sub new {
# Add name / attributes
$self->{name} = "status";
+ $self->{attributes} = { "id" => [ 'integer', 'process id' ],
+ "status" => [ 'string', 'cv', [ ['processing', 'process is still computing'],
+ ['done', 'process is done computing'] ] ],
+ "url" => [ 'url', 'resource location of this object instance'],
+ "data" => [ 'hash', 'if status is done, data holds the result, otherwise data is not present']
+ };
return $self;
}
@@ -95,15 +101,15 @@ sub prepare_data {
my $obj = {};
if ($process_status ne "") {
$obj->{id} = $id;
- $obj->{status} = "Processing";
+ $obj->{status} = "processing";
$obj->{url} = $self->cgi->url."/".$self->name."/".$id;
} elsif ($process_status eq "" && $self->cgi->param('verbosity') && ($self->cgi->param('verbosity') eq 'minimal')) {
$obj->{id} = $id;
- $obj->{status} = "Done";
+ $obj->{status} = "done";
$obj->{url} = $self->cgi->url."/".$self->name."/".$id;
} else {
$obj->{id} = $id;
- $obj->{status} = "Done";
+ $obj->{status} = "done";
$obj->{url} = $self->cgi->url."/".$self->name."/".$id;
local $/;
open my $fh, "<", $fname;
View
11 src/MGRAST/lib/resources2/user.pm
@@ -5,6 +5,7 @@ use warnings;
no warnings('once');
use Conf;
+use Data::Dumper;
use parent qw(resources2::resource);
use WebApplicationDBHandle;
use DBMaster;
@@ -73,24 +74,24 @@ sub instance {
my $id = $rest->[0];
if ($rest && scalar(@$rest) == 1) {
- unless ($self->user && $self->user->has_right(undef, 'edit', 'user', $self->user->{_id})) {
- $self->return_data( {"ERROR" => "insufficient permissions for user call"}, 400 );
- }
+ unless ($self->user && $self->user->has_right(undef, 'edit', 'user', $self->user->{_id})) {
+ $self->return_data( {"ERROR" => "insufficient permissions for user call"}, 400 );
+ }
}
use WebApplicationDBHandle;
use DBMaster;
my ($dbmaster, $error) = WebApplicationDBHandle->new();
if ($error) {
- $self->return_data( {"ERROR" => "could not connect to user database - $error"}, 500 );
+ $self->return_data( {"ERROR" => "could not connect to user database - $error"}, 500 );
}
# get data
my $user = $dbmaster->User->get_objects( { "login" => $id } );
unless (scalar(@$user)) {
- $self->return_data( {"ERROR" => "login $id does not exists"}, 404 );
+ $self->return_data( {"ERROR" => "login $id does not exists"}, 404 );
}
# prepare data

0 comments on commit a643a13

Please sign in to comment.