# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User peterjc <p.j.a.cock(a)googlemail.com>
# Date 1287998919 -3600
# Node ID d8184d91928c83f0269bd0267be949bc5d676e8b
# Parent 5c212dfc6189bb41d334b0519411ca4f04fde9ec
Remove FASTA filter script from BLAST+ tools (I want to generalise it)
--- a/tool_conf.xml.sample
+++ b/tool_conf.xml.sample
@@ -269,7 +269,6 @@
<tool file="ncbi_blast_plus/ncbi_tblastn_wrapper.xml" /><tool file="ncbi_blast_plus/ncbi_tblastx_wrapper.xml" /><tool file="ncbi_blast_plus/blastxml_to_tabular.xml" />
- <tool file="ncbi_blast_plus/blast_filter_fasta.xml" /></section><section name="NGS: Mapping" id="solexa_tools"><tool file="sr_mapping/lastz_wrapper.xml" />
--- a/tools/ncbi_blast_plus/blast_filter_fasta.py
+++ /dev/null
@@ -1,38 +0,0 @@
-#!/usr/bin/env python
-"""Filter a FASTA file using tabular output, e.g. from BLAST.
-
-Takes five command line options, tabular BLAST filename, ID column number
-(using one based counting), input FASTA filename, and two output FASTA
-filenames (for records with and without any BLAST hits).
-
-In the default NCBI BLAST+ tabular output, the query sequence ID is in column
-one, and the ID of the match from the database is in column two.
-"""
-import sys
-from galaxy_utils.sequence.fasta import fastaReader, fastaWriter
-
-#Parse Command Line
-blast_file, blast_col, in_file, out_positive_file, out_negative_file = sys.argv[1:]
-blast_col = int(blast_col)-1
-assert blast_col >= 0
-
-#Read tabular BLAST file and record all queries with hit(s)
-ids = set()
-blast_handle = open(blast_file, "rU")
-for line in blast_handle:
- ids.add(line.split("\t")[blast_col])
-blast_handle.close()
-
-#Write filtered FASTA file based on IDs from BLAST file
-reader = fastaReader(open(in_file, "rU"))
-positive_writer = fastaWriter(open(out_positive_file, "w"))
-negative_writer = fastaWriter(open(out_negative_file, "w"))
-for record in reader:
- #The [1:] is because the fastaReader leaves the > on the identifer.
- if record.identifier and record.identifier.split()[0][1:] in ids:
- positive_writer.write(record)
- else:
- negative_writer.write(record)
-positive_writer.close()
-negative_writer.close()
-reader.close()
--- a/tools/ncbi_blast_plus/blast_filter_fasta.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<tool id="blast_filter_fasta" name="Filter FASTA using BLAST output" version="0.0.1">
- <description>Divide a FASTA file based on BLAST hits</description>
- <command interpreter="python">
- blast_filter_fasta.py $blast_file $blast_col $in_file $out_positive_file $out_negative_file
- </command>
- <inputs>
- <param name="in_file" type="data" format="fasta" label="FASTA file to filter"/>
- <param name="blast_file" type="data" format="tabular" label="Tabular BLAST output"/>
- <param name="blast_col" type="select" label="Column containing FASTA identifiers">
- <option value="1">Column 1 - BLAST query ID</option>
- <option value="2">Column 2 - BLAST match ID</option>
- </param>
- </inputs>
- <outputs>
- <data name="out_positive_file" format="fasta" label="Sequences with BLAST hits" />
- <data name="out_negative_file" format="fasta" label="Sequences without BLAST hits" />
- </outputs>
- <requirements>
- </requirements>
- <tests>
- </tests>
- <help>
-
-**What it does**
-
-Typical use would be to take a multi-sequence FASTA and the tabular output of
-running BLAST on it, and divide the FASTA file in two: those sequence with a
-BLAST hit, and those without.
-
-In the default NCBI BLAST+ tabular output, the query sequence ID is in column
-one, and the ID of the match from the database is in column two.
-
-This allows you to filter the FASTA file for the subjects in the BLAST search,
-rather than filtering the FASTA file for the queries in the BLAST search.
-
- </help>
-</tool>
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Kanwei Li <kanwei(a)gmail.com>
# Date 1289525191 18000
# Node ID caed55b53f5a811226e0bfa1c177e7b3e57a909a
# Parent ff7327f2946e9121139cefbf4a45dba2791b7162
Allows the downloading of metadata files associated with datasets (such as bai indices for bam files). This is done by adding a dropdown menu to the Save icon of appropriate datasets. Could potentially be modified to access implicitly converted datatypes as well in the future. Closes #410
--- a/templates/root/history_common.mako
+++ b/templates/root/history_common.mako
@@ -1,8 +1,10 @@
<% _=n_ %>
## Render the dataset `data` as history item, using `hid` as the displayed id
<%def name="render_dataset( data, hid, show_deleted_on_refresh = False, for_editing = True )">
- <a name="${trans.security.encode_id( data.id )}"></a><%
+ dataset_id = trans.security.encode_id( data.id )
+ from galaxy.datatypes.metadata import FileParameter
+
if data.state in ['no state','',None]:
data_state = "queued"
else:
@@ -41,7 +43,6 @@
%endif
%else:
<%
- dataset_id = trans.security.encode_id( data.id )
if for_editing:
display_url = h.url_for( controller='dataset', action='display', dataset_id=dataset_id, preview=True, filename='' )
else:
@@ -117,10 +118,25 @@
%endif
</div><div class="info">${_('Info: ')}${data.display_info()}</div>
- <div>
- <% dataset_id=trans.security.encode_id( data.id ) %>
+ <div>
%if data.has_data():
+
+ ## Check for downloadable metadata files
+ <% meta_files = [ k for k in data.metadata.spec.keys() if isinstance( data.metadata.spec[k].param, FileParameter ) ] %>
+ %if meta_files:
+ <div popupmenu="dataset-${dataset_id}-popup">
+ %for file_type in meta_files:
+ <a class="action-button" href="${h.url_for( controller='dataset', action='get_metadata_file', hda_id=dataset_id, metadata_type=file_type )}">
+ Download ${file_type}</a>
+ %endfor
+ </div>
+ <div style="float:left;" class="menubutton split popup" id="dataset-${dataset_id}-popup">
+ %endif
<a href="${h.url_for( controller='dataset', action='display', dataset_id=dataset_id, to_ext=data.ext )}" title="Save" class="icon-button disk tooltip"></a>
+ %if meta_files:
+ </div>
+ %endif
+
%if for_editing:
<a href="${h.url_for( controller='tool_runner', action='rerun', id=data.id )}" target="galaxy_main" title="Run this job again" class="icon-button arrow-circle tooltip"></a>
%if app.config.get_bool( 'enable_tracks', False ) and data.ext in app.datatypes_registry.get_available_tracks():
--- a/templates/root/history.mako
+++ b/templates/root/history.mako
@@ -277,6 +277,7 @@ var updater_callback = function ( tracke
// Keep going (if there are still any items to track)
updater( tracked_datasets );
}
+ make_popup_menus();
},
error: function() {
// Just retry, like the old method, should try to be smarter
--- a/lib/galaxy/web/controllers/dataset.py
+++ b/lib/galaxy/web/controllers/dataset.py
@@ -305,7 +305,18 @@ class DatasetInterface( BaseController,
return trans.show_error_message( msg )
-
+ @web.expose
+ def get_metadata_file(self, trans, hda_id, metadata_type):
+ """ Allows the downloading of metadata files associated with datasets (eg. bai index for bam files) """
+ data = trans.sa_session.query( trans.app.model.HistoryDatasetAssociation ).get( trans.security.decode_id( hda_id ) )
+ if not data or not trans.app.security_agent.can_access_dataset( trans.get_current_user_roles(), data.dataset ):
+ return trans.show_error_message( "You are not allowed to access this dataset" )
+
+ valid_chars = '.,^_-()[]0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
+ fname = ''.join(c in valid_chars and c or '_' for c in data.name)[0:150]
+ trans.response.headers["Content-Disposition"] = "attachment; filename=Galaxy%s-[%s].%s" % (data.hid, fname, metadata_type)
+ return open(data.metadata.get(metadata_type).file_name)
+
@web.expose
def display(self, trans, dataset_id=None, preview=False, filename=None, to_ext=None, **kwd):
"""Catches the dataset id and displays file contents as directed"""
@@ -323,8 +334,7 @@ class DatasetInterface( BaseController,
data = None
if not data:
raise paste.httpexceptions.HTTPRequestRangeNotSatisfiable( "Invalid reference dataset id: %s." % str( dataset_id ) )
- current_user_roles = trans.get_current_user_roles()
- if not trans.app.security_agent.can_access_dataset( current_user_roles, data.dataset ):
+ if not trans.app.security_agent.can_access_dataset( trans.get_current_user_roles(), data.dataset ):
return trans.show_error_message( "You are not allowed to access this dataset" )
if data.state == trans.model.Dataset.states.UPLOAD:
@@ -358,8 +368,7 @@ class DatasetInterface( BaseController,
if not to_ext:
to_ext = data.extension
valid_chars = '.,^_-()[]0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
- fname = data.name
- fname = ''.join(c in valid_chars and c or '_' for c in fname)[0:150]
+ fname = ''.join(c in valid_chars and c or '_' for c in data.name)[0:150]
trans.response.headers["Content-Disposition"] = "attachment; filename=Galaxy%s-[%s].%s" % (data.hid, fname, to_ext)
return open( data.file_name )
if not os.path.exists( data.file_name ):
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Greg Von Kuster <greg(a)bx.psu.edu>
# Date 1289522279 18000
# Node ID ff7327f2946e9121139cefbf4a45dba2791b7162
# Parent f2383b761f4e05442fd5ba6b1cde517732aa2c03
When generating the list of target libraries for transferring sample datasets, use all libraries accessible to the request's user rather than all libraries for which that user has LIBRARY_ADD permission.
--- a/lib/galaxy/model/__init__.py
+++ b/lib/galaxy/model/__init__.py
@@ -53,6 +53,8 @@ class User( object ):
roles.append( role )
return roles
def accessible_libraries( self, trans, actions ):
+ # TODO: eliminate this method - instead use
+ # trans.app.security_agent.get_accessible_libraries().
# Get all permitted libraries for this user
all_libraries = trans.sa_session.query( trans.app.model.Library ) \
.filter( trans.app.model.Library.table.c.deleted == False ) \
--- a/lib/galaxy/web/controllers/requests_common.py
+++ b/lib/galaxy/web/controllers/requests_common.py
@@ -2,6 +2,7 @@ from galaxy.web.base.controller import *
from galaxy.web.framework.helpers import time_ago, iff, grids
from galaxy.model.orm import *
from galaxy import model, util
+from galaxy.util.odict import odict
from galaxy.web.form_builder import *
import logging, os, csv
@@ -413,8 +414,7 @@ class RequestsCommon( BaseController, Us
cntrller=cntrller,
id=request_id,
editing_samples=editing_samples ) )
- # Get all libraries for which the current user has permission to add items.
- libraries = request.user.accessible_libraries( trans, [ trans.app.security_agent.permitted_actions.LIBRARY_ADD ] )
+ libraries = self.__get_accessible_libraries( trans, request.user )
# Build a list of sample widgets (based on the attributes of each sample) for display.
displayable_sample_widgets = self.__get_sample_widgets( trans, request, request.samples, **kwd )
encoded_selected_sample_ids = self.__get_encoded_selected_sample_ids( trans, request, **kwd )
@@ -815,8 +815,7 @@ class RequestsCommon( BaseController, Us
else:
sample_index = len( displayable_sample_widgets )
if params.get( 'add_sample_button', False ):
- # Get all libraries for which the current user has permission to add items
- libraries = request.user.accessible_libraries( trans, [ trans.app.security_agent.permitted_actions.LIBRARY_ADD ] )
+ libraries = self.__get_accessible_libraries( trans, request.user )
num_samples_to_add = int( params.get( 'num_sample_to_copy', 1 ) )
# See if the user has selected a sample to copy.
copy_sample_index = int( params.get( 'copy_sample_index', -1 ) )
@@ -1186,9 +1185,9 @@ class RequestsCommon( BaseController, Us
# the first time a bar code was added to the sample, so change it's state
# to the next associated SampleState.
if sample.state.id == request.type.states[0].id:
- event = trans.app.model.SampleEvent(sample,
- request.type.states[1],
- 'Bar code associated with the sample' )
+ event = trans.model.SampleEvent( sample,
+ request.type.states[1],
+ 'Bar code associated with the sample' )
trans.sa_session.add( event )
trans.sa_session.flush()
sample.bar_code = bar_code
@@ -1216,6 +1215,19 @@ class RequestsCommon( BaseController, Us
folder = None
return library, folder
# ===== Methods for handling form definition widgets =====
+ def __get_accessible_libraries( self, trans, user ):
+ # Return a dictionary whose keys are libraries that user can
+ # access and whose values are empty string ''. This is because
+ # methods expect the dictionary instead of a simple list because
+ # this method replaces the deprecated model.User.accessible_libraries()
+ # method. TODO: fix methods that call this method to expect the list
+ # returne dby trans.app.securoty_agent.get_accessible_libraries() and
+ # then eliminate this method.
+ accessible_libraries = trans.app.security_agent.get_accessible_libraries( trans, user )
+ accessible_libraries_dict = odict()
+ for library in accessible_libraries:
+ accessible_libraries_dict[ library ] = ''
+ return accessible_libraries_dict
def __get_request_widgets( self, trans, id ):
"""Get the widgets for the request"""
request = trans.sa_session.query( trans.model.Request ).get( id )
@@ -1263,8 +1275,7 @@ class RequestsCommon( BaseController, Us
# Build the list of widgets which will be used to render each sample row on the request page
if not request:
return sample_widgets
- # Get the list of libraries for which the current user has permission to add items.
- libraries = request.user.accessible_libraries( trans, [ trans.app.security_agent.permitted_actions.LIBRARY_ADD ] )
+ libraries = self.__get_accessible_libraries( trans, request.user )
# Build the list if sample widgets, populating the values from kwd.
for index, sample in enumerate( samples ):
id_index = index + 1
--- a/lib/galaxy/webapps/community/__init__.py
+++ b/lib/galaxy/webapps/community/__init__.py
@@ -1,3 +1,3 @@
-"""The Galaxy Reports application."""
+"""The Galaxy Tool Shed application."""
from galaxy.web.framework import expose, url_for
--- a/lib/galaxy/security/__init__.py
+++ b/lib/galaxy/security/__init__.py
@@ -74,6 +74,8 @@ class RBACAgent:
raise "Unimplemented Method"
def make_library_public( self, library ):
raise "Unimplemented Method"
+ def get_accessible_libraries( self, trans, user ):
+ raise "Unimplemented Method"
def folder_is_public( self, library ):
raise "Unimplemented Method"
def make_folder_public( self, folder, count=0 ):
@@ -244,6 +246,26 @@ class GalaxyRBACAgent( RBACAgent ):
return self.allow_action( roles, self.permitted_actions.DATASET_MANAGE_PERMISSIONS, dataset )
def can_access_library( self, roles, library ):
return self.library_is_public( library ) or self.allow_action( roles, self.permitted_actions.LIBRARY_ACCESS, library )
+ def get_accessible_libraries( self, trans, user ):
+ """Return all data libraries that user can access"""
+ accessible_libraries = []
+ current_user_role_ids = [ role.id for role in user.all_roles() ]
+ library_access_action = self.permitted_actions.LIBRARY_ACCESS.action
+ restricted_library_ids = [ lp.library_id for lp in trans.sa_session.query( trans.model.LibraryPermissions ) \
+ .filter( trans.model.LibraryPermissions.table.c.action == library_access_action ) \
+ .distinct() ]
+ accessible_restricted_library_ids = [ lp.library_id for lp in trans.sa_session.query( trans.model.LibraryPermissions ) \
+ .filter( and_( trans.model.LibraryPermissions.table.c.action == library_access_action,
+ trans.model.LibraryPermissions.table.c.role_id.in_( current_user_role_ids ) ) ) ]
+ # Filter to get libraries accessible by the current user. Get both
+ # public libraries and restricted libraries accessible by the current user.
+ for library in trans.sa_session.query( trans.model.Library ) \
+ .filter( and_( trans.model.Library.table.c.deleted == False,
+ ( or_( not_( trans.model.Library.table.c.id.in_( restricted_library_ids ) ),
+ trans.model.Library.table.c.id.in_( accessible_restricted_library_ids ) ) ) ) ) \
+ .order_by( trans.app.model.Library.name ):
+ accessible_libraries.append( library )
+ return accessible_libraries
def can_access_library_item( self, roles, item, user ):
if type( item ) == self.model.Library:
return self.can_access_library( roles, item )
# HG changeset patch -- Bitbucket.org
# Project galaxy-dist
# URL http://bitbucket.org/galaxy/galaxy-dist/overview
# User Greg Von Kuster <greg(a)bx.psu.edu>
# Date 1289427445 18000
# Node ID bbc0f56e3e16f93bf3c81d09b0fa12876a3f2579
# Parent b1813ff5bb4ef20d0b5d5a1fdcfc16cf6ec3ba53
A few more bug fixes in the new sample tracking code.
--- a/templates/admin/requests/select_datasets_to_transfer.mako
+++ b/templates/admin/requests/select_datasets_to_transfer.mako
@@ -127,7 +127,7 @@
</div>
%if sample and sample.datasets:
- <% title = 'Datasets currently selected for "%s"' % sample.name %>
+ <% title = 'All selected datasets for "%s"' % sample.name %><p/>
${render_sample_datasets( 'requests_admin', sample, sample.datasets, title )}
%endif
--- a/lib/galaxy/web/controllers/requests_common.py
+++ b/lib/galaxy/web/controllers/requests_common.py
@@ -952,9 +952,10 @@ class RequestsCommon( BaseController, Us
sample_datasets = sample.transfer_error_dataset_files
return trans.fill_template( '/requests/common/view_sample_datasets.mako',
cntrller=cntrller,
+ title=title,
sample=sample,
sample_datasets=sample_datasets,
- transfer_status=transferr_status,
+ transfer_status=transfer_status,
message=message,
status=status,
files=[],
--- a/templates/requests/common/common.mako
+++ b/templates/requests/common/common.mako
@@ -329,10 +329,26 @@
%endif
</td><td>
- %if is_admin and sample.untransferred_dataset_files:
- <a id="sampleDatasets-${sample.id}" href="${h.url_for( controller='requests_admin', action='manage_datasets', cntrller=cntrller, sample_id=trans.security.encode_id( sample.id ) )}">${len( sample.transferred_dataset_files )}</a>
+ %if is_admin:
+ %if sample.untransferred_dataset_files:
+ ## At least 1 selected dataset is not yet transferred, so this link
+ ## will direct the admin to a page allowing them to transfer datasets.
+ <a href="${h.url_for( controller='requests_common', action='manage_datasets', cntrller=cntrller, sample_id=trans.security.encode_id( sample.id ) )}">${len( sample.transferred_dataset_files )}</a>
+ %else:
+ ## All selected datasets have successfully transferred, so this link
+ ## will direct the admin to a page displaying all transferred datasets.
+ <a href="${h.url_for( controller='requests_common', action='view_sample_datasets', cntrller=cntrller, sample_id=trans.security.encode_id( sample.id ), transfer_status=trans.model.SampleDataset.transfer_status.COMPLETE )}">${len( sample.transferred_dataset_files )}</a>
+ %endif
%else:
- ${len( sample.transferred_dataset_files )}
+ %if sample.transferred_dataset_files:
+ ## The cuurent user is not an admin, so this link will direct the
+ ## user to the target data library containing those datasets that
+ ## were successfully transferred.
+ <a href="${h.url_for( controller='library_common', action='browse_library', cntrller='library', id=trans.security.encode_id( sample.library.id ) )}">${len( sample.transferred_dataset_files )}</a>
+ %else:
+ ## Display a 0 with no link.
+ ${len( sample.transferred_dataset_files )}
+ %endif
%endif
</td>
%endif
--- a/templates/requests/common/view_sample_datasets.mako
+++ b/templates/requests/common/view_sample_datasets.mako
@@ -40,4 +40,5 @@
No datasets with status ${transfer_status}" belong to this sample
%else:
No datasets have been selected for this sample.
+ %endif
%endif