mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-21 13:50:20 +08:00
Several data library improvements:
1. Enhance importing library dataset into the current history by now allowing the user to select from a list of existing histories or create a new named history ( similar to copying datasets ).  This feature is available for a specific library dataset, a folder ( or root folder ), when selecting multiple datasets from in a library,  and on the results page for searched library datasets. 2. Add Brad Chapman's latest patch for fixing the lucene search implementation 3. Eliminate searches on dataset state for both whoosh and lucene searches 4. Clarify the objects being searched in the regular search and advanced search boxes in the data libraries grids. 5. Add the ability to perform certain actions on 1 or more selected library datasets on the results page for searched library datasets. 6. Add a "select all" checkbox to the browse_library.mako template. 7. Fixed library functional tests accordingly.
This commit is contained in:
@@ -6,7 +6,7 @@ from galaxy.model.orm import *
|
||||
from galaxy.datatypes import sniff
|
||||
from galaxy import model, util
|
||||
from galaxy.util.odict import odict
|
||||
from library_common import lucene_search, whoosh_search
|
||||
from library_common import get_comptypes, lucene_search, whoosh_search
|
||||
|
||||
log = logging.getLogger( __name__ )
|
||||
|
||||
@@ -25,17 +25,17 @@ class LibraryListGrid( grids.Grid ):
|
||||
template='/library/grid.mako'
|
||||
default_sort_key = "name"
|
||||
columns = [
|
||||
NameColumn( "Name",
|
||||
NameColumn( "Data library name",
|
||||
key="name",
|
||||
link=( lambda library: dict( operation="browse", id=library.id ) ),
|
||||
attach_popup=False,
|
||||
filterable="advanced" ),
|
||||
DescriptionColumn( "Description",
|
||||
DescriptionColumn( "Data library description",
|
||||
key="description",
|
||||
attach_popup=False,
|
||||
filterable="advanced" ),
|
||||
]
|
||||
columns.append( grids.MulticolFilterColumn( "Search",
|
||||
columns.append( grids.MulticolFilterColumn( "search library dataset name, info, message, dbkey",
|
||||
cols_to_filter=[ columns[0], columns[1] ],
|
||||
key="free-text-search",
|
||||
visible=False,
|
||||
@@ -74,8 +74,9 @@ class Library( BaseController ):
|
||||
params = util.Params( kwd )
|
||||
message = util.restore_text( params.get( 'message', '' ) )
|
||||
status = params.get( 'status', 'done' )
|
||||
default_action = params.get( 'default_action', None )
|
||||
return trans.fill_template( "/library/index.mako",
|
||||
default_action=params.get( 'default_action', None ),
|
||||
default_action=default_action,
|
||||
message=message,
|
||||
status=status )
|
||||
@web.expose
|
||||
@@ -91,8 +92,9 @@ class Library( BaseController ):
|
||||
search_term = kwd[ "f-free-text-search" ]
|
||||
if trans.app.config.enable_lucene_library_search:
|
||||
indexed_search_enabled = True
|
||||
search_url = trans.app.config.config_dict.get( "fulltext_find_url", "" )
|
||||
search_url = trans.app.config.config_dict.get( "fulltext_url", "" )
|
||||
if search_url:
|
||||
indexed_search_enabled = True
|
||||
status, message, lddas = lucene_search( trans, 'library', search_term, search_url, **kwd )
|
||||
elif trans.app.config.enable_whoosh_library_search:
|
||||
indexed_search_enabled = True
|
||||
@@ -100,11 +102,15 @@ class Library( BaseController ):
|
||||
else:
|
||||
indexed_search_enabled = False
|
||||
if indexed_search_enabled:
|
||||
comptypes = get_comptypes( trans )
|
||||
show_deleted = util.string_as_bool( kwd.get( 'show_deleted', False ) )
|
||||
use_panels = util.string_as_bool( kwd.get( 'use_panels', False ) )
|
||||
return trans.fill_template( '/library/common/library_dataset_search_results.mako',
|
||||
cntrller='library',
|
||||
search_term=search_term,
|
||||
comptypes=comptypes,
|
||||
lddas=lddas,
|
||||
show_deleted=show_deleted,
|
||||
use_panels=use_panels,
|
||||
message=message,
|
||||
status=status )
|
||||
|
||||
@@ -3,7 +3,7 @@ from galaxy import model, util
|
||||
from galaxy.web.base.controller import *
|
||||
from galaxy.web.framework.helpers import time_ago, iff, grids
|
||||
from galaxy.model.orm import *
|
||||
from library_common import lucene_search, whoosh_search
|
||||
from library_common import get_comptypes, lucene_search, whoosh_search
|
||||
# Older py compatibility
|
||||
try:
|
||||
set()
|
||||
@@ -35,12 +35,12 @@ class LibraryListGrid( grids.Grid ):
|
||||
template='/admin/library/grid.mako'
|
||||
default_sort_key = "name"
|
||||
columns = [
|
||||
NameColumn( "Name",
|
||||
NameColumn( "Data library name",
|
||||
key="name",
|
||||
link=( lambda library: dict( operation="browse", id=library.id ) ),
|
||||
attach_popup=False,
|
||||
filterable="advanced" ),
|
||||
DescriptionColumn( "Description",
|
||||
DescriptionColumn( "Data library description",
|
||||
key="description",
|
||||
attach_popup=False,
|
||||
filterable="advanced" ),
|
||||
@@ -50,7 +50,7 @@ class LibraryListGrid( grids.Grid ):
|
||||
# Columns that are valid for filtering but are not visible.
|
||||
grids.DeletedColumn( "Deleted", key="deleted", visible=False, filterable="advanced" )
|
||||
]
|
||||
columns.append( grids.MulticolFilterColumn( "Search",
|
||||
columns.append( grids.MulticolFilterColumn( "search library dataset name, info, message, dbkey",
|
||||
cols_to_filter=[ columns[0], columns[1] ],
|
||||
key="free-text-search",
|
||||
visible=False,
|
||||
@@ -133,11 +133,15 @@ class LibraryAdmin( BaseController ):
|
||||
else:
|
||||
indexed_search_enabled = False
|
||||
if indexed_search_enabled:
|
||||
comptypes = get_comptypes( trans )
|
||||
show_deleted = util.string_as_bool( kwd.get( 'show_deleted', False ) )
|
||||
use_panels = util.string_as_bool( kwd.get( 'use_panels', False ) )
|
||||
return trans.fill_template( '/library/common/library_dataset_search_results.mako',
|
||||
cntrller='library_admin',
|
||||
search_term=search_term,
|
||||
comptypes=comptypes,
|
||||
lddas=lddas,
|
||||
show_deleted=show_deleted,
|
||||
use_panels=use_panels,
|
||||
message=message,
|
||||
status=status )
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import os, os.path, shutil, urllib, StringIO, re, gzip, tempfile, shutil, zipfile, copy, glob, string
|
||||
import os, os.path, shutil, urllib, StringIO, re, gzip, tempfile, shutil, zipfile, copy, glob, string, urllib2
|
||||
from galaxy.web.base.controller import *
|
||||
from galaxy import util, jobs
|
||||
from galaxy.datatypes import sniff
|
||||
@@ -7,6 +7,7 @@ from galaxy.util.json import to_json_string
|
||||
from galaxy.tools.actions import upload_common
|
||||
from galaxy.model.orm import *
|
||||
from galaxy.util.streamball import StreamBall
|
||||
from galaxy.util import inflector
|
||||
from galaxy.web.form_builder import AddressField, CheckboxField, SelectField, TextArea, TextField, WorkflowField, WorkflowMappingField, HistoryField
|
||||
import logging, tempfile, zipfile, tarfile, os, sys, operator
|
||||
from galaxy.eggs import require
|
||||
@@ -20,7 +21,7 @@ try:
|
||||
whoosh_search_enabled = True
|
||||
# The following must be defined exactly like the
|
||||
# schema in ~/scripts/data_libraries/build_whoosh_index.py
|
||||
schema = Schema( id=STORED, name=TEXT, info=TEXT, dbkey=TEXT, message=TEXT, state=TEXT )
|
||||
schema = Schema( id=STORED, name=TEXT, info=TEXT, dbkey=TEXT, message=TEXT )
|
||||
except ImportError, e:
|
||||
whoosh_search_enabled = False
|
||||
schema = None
|
||||
@@ -125,16 +126,7 @@ class LibraryCommon( BaseController, UsesFormDefinitions ):
|
||||
message += "Don't navigate away from Galaxy or use the browser's \"stop\" or \"reload\" buttons (on this tab) until the "
|
||||
message += "message \"This job is running\" is cleared from the \"Information\" column below for each selected dataset."
|
||||
status = "info"
|
||||
comptypes_t = comptypes
|
||||
if trans.app.config.nginx_x_archive_files_base:
|
||||
comptypes_t = ['ngxzip']
|
||||
for comptype in trans.app.config.disable_library_comptypes:
|
||||
# TODO: do this once, not every time (we're gonna raise an
|
||||
# exception every time after the first time)
|
||||
try:
|
||||
comptypes_t.remove( comptype )
|
||||
except:
|
||||
pass
|
||||
comptypes = get_comptypes( trans )
|
||||
try:
|
||||
return trans.fill_template( '/library/common/browse_library.mako',
|
||||
cntrller=cntrller,
|
||||
@@ -143,17 +135,18 @@ class LibraryCommon( BaseController, UsesFormDefinitions ):
|
||||
created_ldda_ids=created_ldda_ids,
|
||||
hidden_folder_ids=hidden_folder_ids,
|
||||
show_deleted=show_deleted,
|
||||
comptypes=comptypes_t,
|
||||
comptypes=comptypes,
|
||||
current_user_roles=current_user_roles,
|
||||
message=message,
|
||||
status=status )
|
||||
except Exception, e:
|
||||
message = 'Error attempting to display contents of library (%s): %s.' % ( str( library.name ), str( e ) )
|
||||
status = 'error'
|
||||
default_action = params.get( 'default_action', None )
|
||||
return trans.response.send_redirect( web.url_for( use_panels=use_panels,
|
||||
controller=cntrller,
|
||||
action='browse_libraries',
|
||||
default_action=params.get( 'default_action', None ),
|
||||
default_action=default_action,
|
||||
message=util.sanitize_text( message ),
|
||||
status=status ) )
|
||||
@web.expose
|
||||
@@ -871,7 +864,7 @@ class LibraryCommon( BaseController, UsesFormDefinitions ):
|
||||
message += "Click the Go button at the bottom of this page to edit the permissions on these datasets if necessary."
|
||||
default_action = 'manage_permissions'
|
||||
else:
|
||||
default_action = 'add'
|
||||
default_action = 'import_to_histories'
|
||||
trans.response.send_redirect( web.url_for( controller='library_common',
|
||||
action='browse_library',
|
||||
cntrller=cntrller,
|
||||
@@ -1247,7 +1240,7 @@ class LibraryCommon( BaseController, UsesFormDefinitions ):
|
||||
message += "Click the Go button at the bottom of this page to edit the permissions on these datasets if necessary."
|
||||
default_action = 'manage_permissions'
|
||||
else:
|
||||
default_action = 'add'
|
||||
default_action = 'import_to_histories'
|
||||
return trans.response.send_redirect( web.url_for( controller='library_common',
|
||||
action='browse_library',
|
||||
cntrller=cntrller,
|
||||
@@ -1512,7 +1505,12 @@ class LibraryCommon( BaseController, UsesFormDefinitions ):
|
||||
message=util.sanitize_text( message ),
|
||||
status=status ) )
|
||||
@web.expose
|
||||
def act_on_multiple_datasets( self, trans, cntrller, library_id, ldda_ids='', **kwd ):
|
||||
def act_on_multiple_datasets( self, trans, cntrller, library_id=None, ldda_ids='', **kwd ):
|
||||
# This method is called from 1 of 3 places:
|
||||
# - this controller's download_dataset_from_folder() method
|
||||
# - he browse_library.mako template
|
||||
# - the library_dataset_search_results.mako template
|
||||
# In the last case above, we will not have a library_id
|
||||
class NgxZip( object ):
|
||||
def __init__( self, url_base ):
|
||||
self.files = {}
|
||||
@@ -1534,6 +1532,16 @@ class LibraryCommon( BaseController, UsesFormDefinitions ):
|
||||
show_deleted = util.string_as_bool( params.get( 'show_deleted', False ) )
|
||||
use_panels = util.string_as_bool( params.get( 'use_panels', False ) )
|
||||
action = params.get( 'do_action', None )
|
||||
if action == 'import_to_histories':
|
||||
return trans.response.send_redirect( web.url_for( controller='library_common',
|
||||
action='import_datasets_to_histories',
|
||||
cntrller=cntrller,
|
||||
library_id=library_id,
|
||||
ldda_ids=ldda_ids,
|
||||
use_panels=use_panels,
|
||||
show_deleted=show_deleted,
|
||||
message=message,
|
||||
status=status ) )
|
||||
lddas = []
|
||||
error = False
|
||||
is_admin = trans.user_is_admin() and cntrller == 'library_admin'
|
||||
@@ -1557,27 +1565,177 @@ class LibraryCommon( BaseController, UsesFormDefinitions ):
|
||||
message = "Invalid library dataset id ( %s ) specified." % str( ldda_id )
|
||||
break
|
||||
lddas.append( ldda )
|
||||
if action == 'import_to_history' or action == 'add':
|
||||
if trans.get_history() is None:
|
||||
# Must be a bot sending a request without having a history.
|
||||
error = True
|
||||
message = "You do not have a current history"
|
||||
elif action == 'manage_permissions':
|
||||
if not is_admin:
|
||||
if not is_admin:
|
||||
if action == 'manage_permissions':
|
||||
for ldda in lddas:
|
||||
if not ( trans.app.security_agent.can_manage_library_item( current_user_roles, ldda ) and \
|
||||
trans.app.security_agent.can_manage_dataset( current_user_roles, ldda.dataset ) ):
|
||||
error = True
|
||||
message = "You are not authorized to manage permissions on library dataset '%s'." % ldda.name
|
||||
break
|
||||
elif action == 'delete':
|
||||
if not is_admin:
|
||||
elif action == 'delete':
|
||||
for ldda in lddas:
|
||||
if not trans.app.security_agent.can_modify_library_item( current_user_roles, ldda ):
|
||||
error = True
|
||||
message = "You are not authorized to modify library dataset '%s'." % ldda.name
|
||||
break
|
||||
if error:
|
||||
if not error:
|
||||
if action == 'manage_permissions':
|
||||
trans.response.send_redirect( web.url_for( controller='library_common',
|
||||
action='ldda_permissions',
|
||||
cntrller=cntrller,
|
||||
use_panels=use_panels,
|
||||
library_id=library_id,
|
||||
folder_id=trans.security.encode_id( lddas[0].library_dataset.folder.id ),
|
||||
id=",".join( ldda_ids ),
|
||||
show_deleted=show_deleted,
|
||||
message=util.sanitize_text( message ),
|
||||
status=status ) )
|
||||
elif action == 'delete':
|
||||
for ldda in lddas:
|
||||
# Do not delete the association, just delete the library_dataset. The
|
||||
# cleanup_datasets.py script handles everything else.
|
||||
ld = ldda.library_dataset
|
||||
ld.deleted = True
|
||||
trans.sa_session.add( ld )
|
||||
trans.sa_session.flush()
|
||||
message = "The selected datasets have been deleted."
|
||||
elif action in ['zip','tgz','tbz','ngxzip']:
|
||||
error = False
|
||||
killme = string.punctuation + string.whitespace
|
||||
trantab = string.maketrans(killme,'_'*len(killme))
|
||||
try:
|
||||
outext = 'zip'
|
||||
if action == 'zip':
|
||||
# Can't use mkstemp - the file must not exist first
|
||||
tmpd = tempfile.mkdtemp()
|
||||
tmpf = os.path.join( tmpd, 'library_download.' + action )
|
||||
if ziptype == '64' and trans.app.config.upstream_gzip:
|
||||
archive = zipfile.ZipFile( tmpf, 'w', zipfile.ZIP_STORED, True )
|
||||
elif ziptype == '64':
|
||||
archive = zipfile.ZipFile( tmpf, 'w', zipfile.ZIP_DEFLATED, True )
|
||||
elif trans.app.config.upstream_gzip:
|
||||
archive = zipfile.ZipFile( tmpf, 'w', zipfile.ZIP_STORED )
|
||||
else:
|
||||
archive = zipfile.ZipFile( tmpf, 'w', zipfile.ZIP_DEFLATED )
|
||||
archive.add = lambda x, y: archive.write( x, y.encode('CP437') )
|
||||
elif action == 'tgz':
|
||||
if trans.app.config.upstream_gzip:
|
||||
archive = util.streamball.StreamBall( 'w|' )
|
||||
outext = 'tar'
|
||||
else:
|
||||
archive = util.streamball.StreamBall( 'w|gz' )
|
||||
outext = 'tgz'
|
||||
elif action == 'tbz':
|
||||
archive = util.streamball.StreamBall( 'w|bz2' )
|
||||
outext = 'tbz2'
|
||||
elif action == 'ngxzip':
|
||||
archive = NgxZip( trans.app.config.nginx_x_archive_files_base )
|
||||
except ( OSError, zipfile.BadZipfile ):
|
||||
error = True
|
||||
log.exception( "Unable to create archive for download" )
|
||||
message = "Unable to create archive for download, please report this error"
|
||||
status = 'error'
|
||||
except:
|
||||
error = True
|
||||
log.exception( "Unexpected error %s in create archive for download" % sys.exc_info()[0] )
|
||||
message = "Unable to create archive for download, please report - %s" % sys.exc_info()[0]
|
||||
status = 'error'
|
||||
if not error:
|
||||
composite_extensions = trans.app.datatypes_registry.get_composite_extensions()
|
||||
seen = []
|
||||
for ldda in lddas:
|
||||
if ldda.dataset.state in [ 'new', 'upload', 'queued', 'running', 'empty', 'discarded' ]:
|
||||
continue
|
||||
ext = ldda.extension
|
||||
is_composite = ext in composite_extensions
|
||||
path = ""
|
||||
parent_folder = ldda.library_dataset.folder
|
||||
while parent_folder is not None:
|
||||
# Exclude the now-hidden "root folder"
|
||||
if parent_folder.parent is None:
|
||||
path = os.path.join( parent_folder.library_root[0].name, path )
|
||||
break
|
||||
path = os.path.join( parent_folder.name, path )
|
||||
parent_folder = parent_folder.parent
|
||||
path += ldda.name
|
||||
while path in seen:
|
||||
path += '_'
|
||||
seen.append( path )
|
||||
zpath = os.path.split(path)[-1] # comes as base_name/fname
|
||||
outfname,zpathext = os.path.splitext(zpath)
|
||||
if is_composite:
|
||||
# need to add all the components from the extra_files_path to the zip
|
||||
if zpathext == '':
|
||||
zpath = '%s.html' % zpath # fake the real nature of the html file
|
||||
try:
|
||||
archive.add(ldda.dataset.file_name,zpath) # add the primary of a composite set
|
||||
except IOError:
|
||||
error = True
|
||||
log.exception( "Unable to add composite parent %s to temporary library download archive" % ldda.dataset.file_name)
|
||||
message = "Unable to create archive for download, please report this error"
|
||||
status = 'error'
|
||||
continue
|
||||
flist = glob.glob(os.path.join(ldda.dataset.extra_files_path,'*.*')) # glob returns full paths
|
||||
for fpath in flist:
|
||||
efp,fname = os.path.split(fpath)
|
||||
if fname > '':
|
||||
fname = fname.translate(trantab)
|
||||
try:
|
||||
archive.add( fpath,fname )
|
||||
except IOError:
|
||||
error = True
|
||||
log.exception( "Unable to add %s to temporary library download archive %s" % (fname,outfname))
|
||||
message = "Unable to create archive for download, please report this error"
|
||||
status = 'error'
|
||||
continue
|
||||
else: # simple case
|
||||
try:
|
||||
archive.add( ldda.dataset.file_name, path )
|
||||
except IOError:
|
||||
error = True
|
||||
log.exception( "Unable to write %s to temporary library download archive" % ldda.dataset.file_name)
|
||||
message = "Unable to create archive for download, please report this error"
|
||||
status = 'error'
|
||||
if not error:
|
||||
if library_id:
|
||||
lname = trans.sa_session.query( trans.app.model.Library ).get( trans.security.decode_id( library_id ) ).name
|
||||
else:
|
||||
# Request must have coe from the library_dataset_search_results page.
|
||||
lname = 'selected_dataset'
|
||||
fname = lname.replace( ' ', '_' ) + '_files'
|
||||
if action == 'zip':
|
||||
archive.close()
|
||||
tmpfh = open( tmpf )
|
||||
# clean up now
|
||||
try:
|
||||
os.unlink( tmpf )
|
||||
os.rmdir( tmpd )
|
||||
except OSError:
|
||||
error = True
|
||||
log.exception( "Unable to remove temporary library download archive and directory" )
|
||||
message = "Unable to create archive for download, please report this error"
|
||||
status = 'error'
|
||||
if not error:
|
||||
trans.response.set_content_type( "application/x-zip-compressed" )
|
||||
trans.response.headers[ "Content-Disposition" ] = "attachment; filename=%s.%s" % (fname,outext)
|
||||
return tmpfh
|
||||
elif action == 'ngxzip':
|
||||
trans.response.set_content_type( "application/zip" )
|
||||
trans.response.headers[ "Content-Disposition" ] = "attachment; filename=%s.%s" % (fname,outext)
|
||||
trans.response.headers[ "X-Archive-Files" ] = "zip"
|
||||
return archive
|
||||
else:
|
||||
trans.response.set_content_type( "application/x-tar" )
|
||||
trans.response.headers[ "Content-Disposition" ] = "attachment; filename=%s.%s" % (fname,outext)
|
||||
archive.wsgi_status = trans.response.wsgi_status()
|
||||
archive.wsgi_headeritems = trans.response.wsgi_headeritems()
|
||||
return archive.stream
|
||||
else:
|
||||
status = 'error'
|
||||
message = 'Invalid action ( %s ) specified.' % action
|
||||
if library_id:
|
||||
# If we have a library_id, browse the associated library
|
||||
return trans.response.send_redirect( web.url_for( controller='library_common',
|
||||
action='browse_library',
|
||||
cntrller=cntrller,
|
||||
@@ -1585,181 +1743,129 @@ class LibraryCommon( BaseController, UsesFormDefinitions ):
|
||||
id=library_id,
|
||||
show_deleted=show_deleted,
|
||||
message=util.sanitize_text( message ),
|
||||
status='error' ) )
|
||||
if action == 'import_to_history' or action == 'add':
|
||||
history = trans.get_history()
|
||||
total_imported_lddas = 0
|
||||
message = ''
|
||||
status = 'done'
|
||||
for ldda in lddas:
|
||||
if ldda.dataset.state in [ 'new', 'upload', 'queued', 'running', 'empty', 'discarded' ]:
|
||||
message += "Cannot import dataset '%s' since its state is '%s'. " % ( ldda.name, ldda.dataset.state )
|
||||
status = 'error'
|
||||
elif ldda.dataset.state in [ 'ok', 'error' ]:
|
||||
hda = ldda.to_history_dataset_association( target_history=history, add_to_history=True )
|
||||
total_imported_lddas += 1
|
||||
if total_imported_lddas:
|
||||
trans.sa_session.add( history )
|
||||
trans.sa_session.flush()
|
||||
message += "%i dataset(s) have been imported into your history. " % total_imported_lddas
|
||||
elif action == 'manage_permissions':
|
||||
trans.response.send_redirect( web.url_for( controller='library_common',
|
||||
action='ldda_permissions',
|
||||
cntrller=cntrller,
|
||||
use_panels=use_panels,
|
||||
library_id=library_id,
|
||||
folder_id=trans.security.encode_id( lddas[0].library_dataset.folder.id ),
|
||||
id=",".join( ldda_ids ),
|
||||
show_deleted=show_deleted,
|
||||
message=util.sanitize_text( message ),
|
||||
status=status ) )
|
||||
elif action == 'delete':
|
||||
for ldda in lddas:
|
||||
# Do not delete the association, just delete the library_dataset. The
|
||||
# cleanup_datasets.py script handles everything else.
|
||||
ld = ldda.library_dataset
|
||||
ld.deleted = True
|
||||
trans.sa_session.add( ld )
|
||||
trans.sa_session.flush()
|
||||
message = "The selected datasets have been removed from this data library"
|
||||
elif action in ['zip','tgz','tbz','ngxzip']:
|
||||
error = False
|
||||
killme = string.punctuation + string.whitespace
|
||||
trantab = string.maketrans(killme,'_'*len(killme))
|
||||
try:
|
||||
outext = 'zip'
|
||||
if action == 'zip':
|
||||
# Can't use mkstemp - the file must not exist first
|
||||
tmpd = tempfile.mkdtemp()
|
||||
tmpf = os.path.join( tmpd, 'library_download.' + action )
|
||||
if ziptype == '64' and trans.app.config.upstream_gzip:
|
||||
archive = zipfile.ZipFile( tmpf, 'w', zipfile.ZIP_STORED, True )
|
||||
elif ziptype == '64':
|
||||
archive = zipfile.ZipFile( tmpf, 'w', zipfile.ZIP_DEFLATED, True )
|
||||
elif trans.app.config.upstream_gzip:
|
||||
archive = zipfile.ZipFile( tmpf, 'w', zipfile.ZIP_STORED )
|
||||
else:
|
||||
archive = zipfile.ZipFile( tmpf, 'w', zipfile.ZIP_DEFLATED )
|
||||
archive.add = lambda x, y: archive.write( x, y.encode('CP437') )
|
||||
elif action == 'tgz':
|
||||
if trans.app.config.upstream_gzip:
|
||||
archive = util.streamball.StreamBall( 'w|' )
|
||||
outext = 'tar'
|
||||
else:
|
||||
archive = util.streamball.StreamBall( 'w|gz' )
|
||||
outext = 'tgz'
|
||||
elif action == 'tbz':
|
||||
archive = util.streamball.StreamBall( 'w|bz2' )
|
||||
outext = 'tbz2'
|
||||
elif action == 'ngxzip':
|
||||
archive = NgxZip( trans.app.config.nginx_x_archive_files_base )
|
||||
except (OSError, zipfile.BadZipfile):
|
||||
error = True
|
||||
log.exception( "Unable to create archive for download" )
|
||||
message = "Unable to create archive for download, please report this error"
|
||||
status = 'error'
|
||||
except:
|
||||
error = True
|
||||
log.exception( "Unexpected error %s in create archive for download" % sys.exc_info()[0])
|
||||
message = "Unable to create archive for download, please report - %s" % sys.exc_info()[0]
|
||||
status = 'error'
|
||||
if not error:
|
||||
composite_extensions = trans.app.datatypes_registry.get_composite_extensions( )
|
||||
seen = []
|
||||
for ldda in lddas:
|
||||
if ldda.dataset.state in [ 'new', 'upload', 'queued', 'running', 'empty', 'discarded' ]:
|
||||
continue
|
||||
ext = ldda.extension
|
||||
is_composite = ext in composite_extensions
|
||||
path = ""
|
||||
parent_folder = ldda.library_dataset.folder
|
||||
while parent_folder is not None:
|
||||
# Exclude the now-hidden "root folder"
|
||||
if parent_folder.parent is None:
|
||||
path = os.path.join( parent_folder.library_root[0].name, path )
|
||||
break
|
||||
path = os.path.join( parent_folder.name, path )
|
||||
parent_folder = parent_folder.parent
|
||||
path += ldda.name
|
||||
while path in seen:
|
||||
path += '_'
|
||||
seen.append( path )
|
||||
zpath = os.path.split(path)[-1] # comes as base_name/fname
|
||||
outfname,zpathext = os.path.splitext(zpath)
|
||||
if is_composite:
|
||||
# need to add all the components from the extra_files_path to the zip
|
||||
if zpathext == '':
|
||||
zpath = '%s.html' % zpath # fake the real nature of the html file
|
||||
try:
|
||||
archive.add(ldda.dataset.file_name,zpath) # add the primary of a composite set
|
||||
except IOError:
|
||||
error = True
|
||||
log.exception( "Unable to add composite parent %s to temporary library download archive" % ldda.dataset.file_name)
|
||||
message = "Unable to create archive for download, please report this error"
|
||||
status = 'error'
|
||||
continue
|
||||
flist = glob.glob(os.path.join(ldda.dataset.extra_files_path,'*.*')) # glob returns full paths
|
||||
for fpath in flist:
|
||||
efp,fname = os.path.split(fpath)
|
||||
if fname > '':
|
||||
fname = fname.translate(trantab)
|
||||
try:
|
||||
archive.add( fpath,fname )
|
||||
except IOError:
|
||||
error = True
|
||||
log.exception( "Unable to add %s to temporary library download archive %s" % (fname,outfname))
|
||||
message = "Unable to create archive for download, please report this error"
|
||||
status = 'error'
|
||||
continue
|
||||
else: # simple case
|
||||
try:
|
||||
archive.add( ldda.dataset.file_name, path )
|
||||
except IOError:
|
||||
error = True
|
||||
log.exception( "Unable to write %s to temporary library download archive" % ldda.dataset.file_name)
|
||||
message = "Unable to create archive for download, please report this error"
|
||||
status = 'error'
|
||||
if not error:
|
||||
lname = trans.sa_session.query( trans.app.model.Library ).get( trans.security.decode_id( library_id ) ).name
|
||||
fname = lname.replace( ' ', '_' ) + '_files'
|
||||
if action == 'zip':
|
||||
archive.close()
|
||||
tmpfh = open( tmpf )
|
||||
# clean up now
|
||||
try:
|
||||
os.unlink( tmpf )
|
||||
os.rmdir( tmpd )
|
||||
except OSError:
|
||||
error = True
|
||||
log.exception( "Unable to remove temporary library download archive and directory" )
|
||||
message = "Unable to create archive for download, please report this error"
|
||||
status = 'error'
|
||||
if not error:
|
||||
trans.response.set_content_type( "application/x-zip-compressed" )
|
||||
trans.response.headers[ "Content-Disposition" ] = "attachment; filename=%s.%s" % (fname,outext)
|
||||
return tmpfh
|
||||
elif action == 'ngxzip':
|
||||
trans.response.set_content_type( "application/zip" )
|
||||
trans.response.headers[ "Content-Disposition" ] = "attachment; filename=%s.%s" % (fname,outext)
|
||||
trans.response.headers[ "X-Archive-Files" ] = "zip"
|
||||
return archive
|
||||
else:
|
||||
trans.response.set_content_type( "application/x-tar" )
|
||||
trans.response.headers[ "Content-Disposition" ] = "attachment; filename=%s.%s" % (fname,outext)
|
||||
archive.wsgi_status = trans.response.wsgi_status()
|
||||
archive.wsgi_headeritems = trans.response.wsgi_headeritems()
|
||||
return archive.stream
|
||||
status=status ) )
|
||||
else:
|
||||
status = 'error'
|
||||
message = 'Invalid action ( %s ) specified.' % action
|
||||
return trans.response.send_redirect( web.url_for( controller='library_common',
|
||||
action='browse_library',
|
||||
cntrller=cntrller,
|
||||
use_panels=use_panels,
|
||||
id=library_id,
|
||||
show_deleted=show_deleted,
|
||||
message=util.sanitize_text( message ),
|
||||
status=status ) )
|
||||
# We must have arrived here from the library_dataset_search_results page, so reddirect there.
|
||||
search_term = params.get( 'search_term', '' )
|
||||
comptypes = get_comptypes( trans )
|
||||
return trans.fill_template( '/library/common/library_dataset_search_results.mako',
|
||||
cntrller=cntrller,
|
||||
search_term=search_term,
|
||||
comptypes=comptypes,
|
||||
lddas=lddas,
|
||||
show_deleted=show_deleted,
|
||||
use_panels=use_panels,
|
||||
message=message,
|
||||
status=status )
|
||||
|
||||
@web.expose
|
||||
def import_datasets_to_histories( self, trans, cntrller, library_id='', folder_id='', ldda_ids='', target_history_ids='', new_history_name='', **kwd ):
|
||||
# This method is called from one of the following places:
|
||||
# - a menu option for a library dataset ( ldda_ids will be a singel dataset id )
|
||||
# - a menu option for a library folder ( folder_id will have a value )
|
||||
# - a menu option for a library dataset search result set ( ldda_ids will be a comma separated string of dataset ids )
|
||||
params = util.Params( kwd )
|
||||
message = util.restore_text( params.get( 'message', '' ) )
|
||||
status = params.get( 'status', 'done' )
|
||||
show_deleted = util.string_as_bool( params.get( 'show_deleted', False ) )
|
||||
use_panels = util.string_as_bool( params.get( 'use_panels', False ) )
|
||||
user = trans.get_user()
|
||||
current_history = trans.get_history()
|
||||
if library_id:
|
||||
library = trans.sa_session.query( trans.model.Library ).get( trans.security.decode_id( library_id ) )
|
||||
else:
|
||||
library = None
|
||||
if folder_id:
|
||||
folder = trans.sa_session.query( trans.model.LibraryFolder ).get( trans.security.decode_id( folder_id ) )
|
||||
else:
|
||||
folder = None
|
||||
ldda_ids = util.listify( ldda_ids )
|
||||
if ldda_ids:
|
||||
# Check boxes cause 2 copies of each id to be included in the request
|
||||
ldda_ids = map( trans.security.decode_id, ldda_ids )
|
||||
unique_ldda_ids = []
|
||||
for ldda_id in ldda_ids:
|
||||
if ldda_id not in unique_ldda_ids:
|
||||
unique_ldda_ids.append( ldda_id )
|
||||
ldda_ids = unique_ldda_ids
|
||||
target_history_ids = util.listify( target_history_ids )
|
||||
if target_history_ids:
|
||||
target_history_ids = [ trans.security.decode_id( target_history_id ) for target_history_id in target_history_ids if target_history_id ]
|
||||
if params.get( 'import_datasets_to_histories_button', False ):
|
||||
invalid_datasets = 0
|
||||
if not ldda_ids or not ( target_history_ids or new_history_name ):
|
||||
message = "You must provide one or more source library datasets and one or more target histories."
|
||||
status = 'error'
|
||||
else:
|
||||
if new_history_name:
|
||||
new_history = trans.app.model.History()
|
||||
new_history.name = new_history_name
|
||||
new_history.user = user
|
||||
trans.sa_session.add( new_history )
|
||||
trans.sa_session.flush()
|
||||
target_history_ids.append( new_history.id )
|
||||
if user:
|
||||
target_histories = [ hist for hist in map( trans.sa_session.query( trans.app.model.History ).get, target_history_ids ) if ( hist is not None and hist.user == user )]
|
||||
else:
|
||||
target_histories = [ current_history ]
|
||||
if len( target_histories ) != len( target_history_ids ):
|
||||
message += "You do not have permission to add datasets to %i requested histories. " % ( len( target_history_ids ) - len( target_histories ) )
|
||||
status = 'error'
|
||||
for ldda in map( trans.sa_session.query( trans.app.model.LibraryDatasetDatasetAssociation ).get, ldda_ids ):
|
||||
if ldda is None:
|
||||
message += "You tried to import a library dataset that does not exist. "
|
||||
status = 'error'
|
||||
invalid_datasets += 1
|
||||
elif ldda.dataset.state not in [ trans.model.Dataset.states.OK, trans.model.Dataset.states.ERROR ]:
|
||||
message += "Cannot import dataset '%s' since its state is '%s'. " % ( ldda.name, ldda.dataset.state )
|
||||
status = 'error'
|
||||
invalid_datasets += 1
|
||||
elif not ldda.has_data():
|
||||
message += "Cannot import empty dataset '%s'. " % ldda.name
|
||||
status = 'error'
|
||||
invalid_datasets += 1
|
||||
else:
|
||||
for target_history in target_histories:
|
||||
hda = ldda.to_history_dataset_association( target_history=target_history, add_to_history=True )
|
||||
trans.sa_session.flush()
|
||||
hist_names_str = ", ".join( [ target_history.name for target_history in target_histories ] )
|
||||
num_source = len( ldda_ids ) - invalid_datasets
|
||||
num_target = len( target_histories )
|
||||
message = "%i %s have been imported into %i %s: %s" % ( num_source,
|
||||
inflector.cond_plural( num_source, "dataset" ),
|
||||
num_target,
|
||||
inflector.cond_plural( num_target, "history" ),
|
||||
hist_names_str )
|
||||
trans.sa_session.refresh( current_history )
|
||||
current_user_roles = trans.get_current_user_roles()
|
||||
source_lddas = []
|
||||
if folder:
|
||||
for library_dataset in folder.datasets:
|
||||
ldda = library_dataset.library_dataset_dataset_association
|
||||
if not ldda.deleted and trans.app.security_agent.can_access_library_item( current_user_roles, ldda, trans.user ):
|
||||
source_lddas.append( ldda )
|
||||
elif ldda_ids:
|
||||
for ldda_id in ldda_ids:
|
||||
# Secuirty access permiision chcck is not needed here since the current user had access
|
||||
# to the lddas in order for the menu optin to be available.
|
||||
ldda = trans.sa_session.query( trans.model.LibraryDatasetDatasetAssociation ).get( ldda_id )
|
||||
source_lddas.append( ldda )
|
||||
target_histories = [ current_history ]
|
||||
if user:
|
||||
target_histories = user.active_histories
|
||||
return trans.fill_template( "/library/common/import_datasets_to_histories.mako",
|
||||
cntrller=cntrller,
|
||||
library=library,
|
||||
current_history=trans.get_history(),
|
||||
ldda_ids=ldda_ids,
|
||||
target_history_ids=target_history_ids,
|
||||
source_lddas=source_lddas,
|
||||
target_histories=target_histories,
|
||||
new_history_name=new_history_name,
|
||||
show_deleted=show_deleted,
|
||||
use_panels=use_panels,
|
||||
message=message,
|
||||
status=status )
|
||||
@web.expose
|
||||
def manage_template_inheritance( self, trans, cntrller, item_type, library_id, folder_id=None, ldda_id=None, **kwd ):
|
||||
params = util.Params( kwd )
|
||||
@@ -2064,6 +2170,31 @@ def get_containing_library_from_library_dataset( trans, library_dataset ):
|
||||
if library.root_folder == folder:
|
||||
return library
|
||||
return None
|
||||
def get_comptypes( trans ):
|
||||
comptypes_t = comptypes
|
||||
if trans.app.config.nginx_x_archive_files_base:
|
||||
comptypes_t = ['ngxzip']
|
||||
for comptype in trans.app.config.disable_library_comptypes:
|
||||
# TODO: do this once, not every time (we're gonna raise an
|
||||
# exception every time after the first time)
|
||||
try:
|
||||
comptypes_t.remove( comptype )
|
||||
except:
|
||||
pass
|
||||
return comptypes_t
|
||||
def get_sorted_accessible_library_items( trans, cntrller, items, sort_attr ):
|
||||
is_admin = trans.user_is_admin() and cntrller == 'library_admin'
|
||||
if is_admin:
|
||||
accessible_items = items
|
||||
else:
|
||||
# Enforce access permission settings
|
||||
current_user_roles = trans.get_current_user_roles()
|
||||
accessible_items = []
|
||||
for item in items:
|
||||
if trans.app.security_agent.can_access_library_item( current_user_roles, item, trans.user ):
|
||||
accessible_items.append( item )
|
||||
# Sort by name
|
||||
return sort_by_attr( [ item for item in accessible_items ], sort_attr )
|
||||
def sort_by_attr( seq, attr ):
|
||||
"""
|
||||
Sort the sequence of objects by object's attribute
|
||||
@@ -2079,25 +2210,12 @@ def sort_by_attr( seq, attr ):
|
||||
intermed = map( None, map( getattr, seq, ( attr, ) * len( seq ) ), xrange( len( seq ) ), seq )
|
||||
intermed.sort()
|
||||
return map( operator.getitem, intermed, ( -1, ) * len( intermed ) )
|
||||
def get_sorted_accessible_library_items( trans, cntrller, items, sort_attr ):
|
||||
is_admin = trans.user_is_admin() and cntrller == 'library_admin'
|
||||
if is_admin:
|
||||
accessible_items = items
|
||||
else:
|
||||
# Enforce access permission settings
|
||||
current_user_roles = trans.get_current_user_roles()
|
||||
accessible_items = []
|
||||
for item in items:
|
||||
if trans.app.security_agent.can_access_library_item( current_user_roles, item, trans.user ):
|
||||
accessible_items.append( item )
|
||||
# Sort by name
|
||||
return sort_by_attr( [ item for item in accessible_items ], sort_attr )
|
||||
def lucene_search( trans, cntrller, search_term, search_url, **kwd ):
|
||||
"""Return display of results from a full-text lucene search of data libraries."""
|
||||
params = util.Params( kwd )
|
||||
message = util.restore_text( params.get( 'message', '' ) )
|
||||
status = params.get( 'status', 'done' )
|
||||
full_url = "%s?%s" % ( search_url, urllib.urlencode( { "kwd" : search_term } ) )
|
||||
full_url = "%s/find?%s" % ( search_url, urllib.urlencode( { "kwd" : search_term } ) )
|
||||
response = urllib2.urlopen( full_url )
|
||||
ldda_ids = util.json.from_json_string( response.read() )[ "ids" ]
|
||||
response.close()
|
||||
@@ -2115,17 +2233,20 @@ def whoosh_search( trans, cntrller, search_term, **kwd ):
|
||||
if index_exists:
|
||||
index = whoosh.index.open_dir( whoosh_index_dir )
|
||||
# Set field boosts for searcher to place equal weight on all search fields.
|
||||
searcher = index.searcher( weighting=BM25F( field_B={ 'name_B' : 3.5,
|
||||
'info_B' : 2.3,
|
||||
'dbkey_B' : 3.1,
|
||||
'message_B' : 2.1,
|
||||
'state_B' : 1.2 } ) )
|
||||
searcher = index.searcher( weighting=BM25F( field_B={ 'name_B' : 3.4,
|
||||
'info_B' : 3.2,
|
||||
'dbkey_B' : 3.3,
|
||||
'message_B' : 3.5 } ) )
|
||||
# Perform search
|
||||
parser = MultifieldParser( [ 'name', 'info', 'dbkey', 'message', 'state' ], schema=schema )
|
||||
parser = MultifieldParser( [ 'name', 'info', 'dbkey', 'message' ], schema=schema )
|
||||
# Search term with wildcards may be slow...
|
||||
results = searcher.search( parser.parse( '*' + search_term + '*' ), minscore=1.0 )
|
||||
results = searcher.search( parser.parse( '*' + search_term + '*' ), minscore=0.1 )
|
||||
ldda_ids = [ result[ 'id' ] for result in results ]
|
||||
lddas = [ trans.app.model.LibraryDatasetDatasetAssociation.get( ldda_id ) for ldda_id in ldda_ids ]
|
||||
lddas = []
|
||||
for ldda_id in ldda_ids:
|
||||
ldda = trans.app.model.LibraryDatasetDatasetAssociation.get( ldda_id )
|
||||
if ldda:
|
||||
lddas.append( ldda )
|
||||
lddas = get_sorted_accessible_library_items( trans, cntrller, lddas, 'name' )
|
||||
else:
|
||||
message = "Tell your Galaxy administrator that the directory %s does not contain valid whoosh indexes" % str( whoosh_index_dir )
|
||||
|
||||
@@ -30,7 +30,7 @@ def main( ini_file ):
|
||||
sa_session, gconfig = get_sa_session( ini_file )
|
||||
max_size = float( gconfig.get( "fulltext_max_size", 100 ) ) * 1048576
|
||||
ignore_exts = gconfig.get( "fulltext_noindex_filetypes", "" ).split( "," )
|
||||
search_url = gconfig.get( "fulltext_index_url", None )
|
||||
search_url = gconfig.get( "fulltext_url", None )
|
||||
if not search_url:
|
||||
raise ValueError( "Need to specify search functionality in universe_wsgi.ini" )
|
||||
dataset_file = create_dataset_file( get_lddas( sa_session, max_size, ignore_exts ) )
|
||||
@@ -41,7 +41,7 @@ def main( ini_file ):
|
||||
os.remove( dataset_file )
|
||||
|
||||
def build_index( search_url, dataset_file ):
|
||||
url = "%s?%s" % ( search_url, urllib.urlencode( { "docfile" : dataset_file } ) )
|
||||
url = "%s/index?%s" % ( search_url, urllib.urlencode( { "docfile" : dataset_file } ) )
|
||||
request = urllib2.Request( url )
|
||||
request.get_method = lambda: "PUT"
|
||||
response = urllib2.urlopen( request )
|
||||
@@ -57,21 +57,35 @@ def create_dataset_file( dataset_iter ):
|
||||
|
||||
def get_lddas( sa_session, max_size, ignore_exts ):
|
||||
for ldda in sa_session.query( model.LibraryDatasetDatasetAssociation ).filter_by( deleted=False ):
|
||||
id = ldda.id
|
||||
name = ldda.name
|
||||
info = ldda.library_dataset.get_info()
|
||||
if info and not info.startswith( 'upload' ):
|
||||
info = info.replace( 'no info', '' )
|
||||
else:
|
||||
info = ''
|
||||
dbkey = ldda.metadata.dbkey
|
||||
state = ldda.state
|
||||
message = ldda.message
|
||||
if ( float( ldda.dataset.get_size() ) > max_size or ldda.extension in ignore_exts ):
|
||||
fname = ""
|
||||
else:
|
||||
fname = ldda.dataset.get_file_name()
|
||||
yield id, name, info, dbkey, state, message, fname
|
||||
yield ldda.id, fname, _get_dataset_metadata(ldda)
|
||||
|
||||
def _get_dataset_metadata(ldda):
|
||||
"""Retrieve descriptions and information associated with a dataset.
|
||||
"""
|
||||
lds = ldda.library_dataset
|
||||
folder_info = _get_folder_info(lds.folder)
|
||||
lds_info = lds.get_info()
|
||||
if lds_info and not lds_info.startswith("upload"):
|
||||
lds_info = lds_info.replace("no info", "")
|
||||
else:
|
||||
lds_info = ""
|
||||
return "%s %s %s %s %s" % (lds.name or "", lds_info, ldda.metadata.dbkey,
|
||||
ldda.message, folder_info)
|
||||
|
||||
def _get_folder_info(folder):
|
||||
"""Get names and descriptions for all parent folders except top level.
|
||||
"""
|
||||
folder_info = ""
|
||||
if folder and folder.parent:
|
||||
folder_info = _get_folder_info(folder.parent)
|
||||
folder_info += " %s %s" % (
|
||||
folder.name.replace("Unnamed folder", ""),
|
||||
folder.description or "")
|
||||
return folder_info
|
||||
|
||||
def get_sa_session( ini_file ):
|
||||
conf_parser = ConfigParser.ConfigParser( { 'here':os.getcwd() } )
|
||||
|
||||
@@ -24,7 +24,7 @@ try:
|
||||
from whoosh.fields import Schema, STORED, ID, KEYWORD, TEXT
|
||||
from whoosh.index import Index
|
||||
whoosh_search_enabled = True
|
||||
schema = Schema( id=STORED, name=TEXT, info=TEXT, dbkey=TEXT, message=TEXT, state=TEXT )
|
||||
schema = Schema( id=STORED, name=TEXT, info=TEXT, dbkey=TEXT, message=TEXT )
|
||||
import galaxy.model.mapping
|
||||
from galaxy import config, model
|
||||
import pkg_resources
|
||||
@@ -43,13 +43,12 @@ def build_index( sa_session, whoosh_index_dir ):
|
||||
else:
|
||||
return a_basestr
|
||||
lddas_indexed = 0
|
||||
for id, name, info, dbkey, state, message in get_lddas( sa_session ):
|
||||
for id, name, info, dbkey, message in get_lddas( sa_session ):
|
||||
writer.add_document( id=id,
|
||||
name=to_unicode( name ),
|
||||
info=to_unicode( info ),
|
||||
dbkey=to_unicode( dbkey ),
|
||||
message=to_unicode( message ),
|
||||
state=to_unicode( state ) )
|
||||
message=to_unicode( message ) )
|
||||
lddas_indexed += 1
|
||||
writer.commit()
|
||||
print "Number of active library datasets indexed: ", lddas_indexed
|
||||
@@ -64,9 +63,8 @@ def get_lddas( sa_session ):
|
||||
else:
|
||||
info = ''
|
||||
dbkey = ldda.metadata.dbkey
|
||||
state = ldda.state
|
||||
message = ldda.message
|
||||
yield id, name, info, dbkey, state, message
|
||||
yield id, name, info, dbkey, message
|
||||
|
||||
def get_sa_session_and_needed_config_settings( ini_file ):
|
||||
conf_parser = ConfigParser.ConfigParser( { 'here' : os.getcwd() } )
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
<%namespace file="/message.mako" import="render_msg" />
|
||||
<%namespace file="/library/common/library_item_info.mako" import="render_library_item_info" />
|
||||
<%namespace file="/library/common/common.mako" import="render_actions_on_multiple_items" />
|
||||
<%namespace file="/library/common/common.mako" import="common_javascripts" />
|
||||
|
||||
<%!
|
||||
def inherit(context):
|
||||
@@ -46,6 +47,7 @@
|
||||
<%def name="javascripts()">
|
||||
${parent.javascripts()}
|
||||
${h.js("class", "jquery.jstore")}
|
||||
${common_javascripts()}
|
||||
${self.grid_javascripts()}
|
||||
</%def>
|
||||
|
||||
@@ -152,15 +154,6 @@
|
||||
});
|
||||
});
|
||||
|
||||
function checkForm() {
|
||||
if ( $("select#action_on_datasets_select option:selected").text() == "delete" ) {
|
||||
if ( confirm( "Click OK to delete these datasets?" ) ) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Looks for changes in dataset state using an async request. Keeps
|
||||
// calling itself (via setTimeout) until all datasets are in a terminal
|
||||
// state.
|
||||
@@ -212,7 +205,7 @@
|
||||
</script>
|
||||
</%def>
|
||||
|
||||
<%def name="render_dataset( cntrller, ldda, library_dataset, selected, library, folder, pad, parent, row_counter, tracked_datasets, show_deleted=False, render_checkboxes=True )">
|
||||
<%def name="render_dataset( cntrller, ldda, library_dataset, selected, library, folder, pad, parent, row_counter, tracked_datasets, show_deleted=False )">
|
||||
<%
|
||||
## The received ldda must always be a LibraryDatasetDatasetAssociation object. The object id passed to methods
|
||||
## from the drop down menu should be the ldda id to prevent id collision ( which could happen when displaying
|
||||
@@ -248,13 +241,11 @@
|
||||
%endif
|
||||
id="libraryItem-${ldda.id}">
|
||||
<td style="padding-left: ${pad+20}px;">
|
||||
%if render_checkboxes:
|
||||
<input style="float: left;" type="checkbox" name="ldda_ids" value="${trans.security.encode_id( ldda.id )}"
|
||||
%if selected:
|
||||
checked="checked"
|
||||
%endif
|
||||
/>
|
||||
<input style="float: left;" type="checkbox" name="ldda_ids" value="${trans.security.encode_id( ldda.id )}"
|
||||
%if selected:
|
||||
checked="checked"
|
||||
%endif
|
||||
/>
|
||||
%if ldda.library_dataset.deleted:
|
||||
<span class="libraryItem-error">
|
||||
%endif
|
||||
@@ -288,7 +279,7 @@
|
||||
<a class="action-button" href="${h.url_for( controller='library_common', action='upload_library_dataset', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( folder.id ), replace_id=trans.security.encode_id( library_dataset.id ), show_deleted=show_deleted )}">Upload a new version of this dataset</a>
|
||||
%endif
|
||||
%if not branch_deleted( folder ) and not ldda.library_dataset.deleted and ldda.has_data:
|
||||
<a class="action-button" href="${h.url_for( controller='library_common', action='act_on_multiple_datasets', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), ldda_ids=trans.security.encode_id( ldda.id ), do_action='import_to_history', use_panels=use_panels, show_deleted=show_deleted )}">Import this dataset into your current history</a>
|
||||
<a class="action-button" href="${h.url_for( controller='library_common', action='import_datasets_to_histories', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), ldda_ids=trans.security.encode_id( ldda.id ), use_panels=use_panels, show_deleted=show_deleted )}">Import this dataset into selected histories</a>
|
||||
<a class="action-button" href="${h.url_for( controller='library_common', action='download_dataset_from_folder', cntrller=cntrller, id=trans.security.encode_id( ldda.id ), library_id=trans.security.encode_id( library.id ), use_panels=use_panels )}">Download this dataset</a>
|
||||
%endif
|
||||
%if can_modify:
|
||||
@@ -379,6 +370,7 @@
|
||||
<a class="action-button" href="${h.url_for( controller='library_common', action='create_folder', cntrller=cntrller, parent_id=trans.security.encode_id( folder.id ), library_id=trans.security.encode_id( library.id ), use_panels=use_panels, show_deleted=show_deleted )}">Add sub-folder</a>
|
||||
%endif
|
||||
%if not branch_deleted( folder ):
|
||||
<a class="action-button" href="${h.url_for( controller='library_common', action='import_datasets_to_histories', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( folder.id ), use_panels=use_panels, show_deleted=show_deleted )}">Select folder datasets for import into selected histories</a>
|
||||
%if can_modify:
|
||||
<a class="action-button" href="${h.url_for( controller='library_common', action='folder_info', cntrller=cntrller, id=trans.security.encode_id( folder.id ), library_id=trans.security.encode_id( library.id ), use_panels=use_panels, show_deleted=show_deleted )}">Edit information</a>
|
||||
%else:
|
||||
@@ -515,6 +507,7 @@
|
||||
%endif
|
||||
<a class="action-button" href="${h.url_for( controller='library_common', action='library_permissions', cntrller=cntrller, id=trans.security.encode_id( library.id ), use_panels=use_panels, show_deleted=show_deleted )}">Edit permissions</a>
|
||||
%endif
|
||||
<a class="action-button" href="${h.url_for( controller='library_common', action='import_datasets_to_histories', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( library.root_folder.id ), use_panels=use_panels, show_deleted=show_deleted )}">Select datasets for import into selected histories</a>
|
||||
%elif can_modify and not library.purged:
|
||||
<a class="action-button" href="${h.url_for( controller='library_common', action='undelete_library_item', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), item_id=trans.security.encode_id( library.id ), item_type='library', use_panels=use_panels )}">Undelete this data library</a>
|
||||
%elif library.purged:
|
||||
@@ -539,7 +532,10 @@
|
||||
<table cellspacing="0" cellpadding="0" border="0" width="100%" class="grid" id="library-grid">
|
||||
<thead>
|
||||
<tr class="libraryTitle">
|
||||
<th>Name</th>
|
||||
<th>
|
||||
<input type="checkbox" id="checkAll" name=select_all_datasets_checkbox value="true" onclick='checkAllFields(1);'/><input type="hidden" name=select_all_datasets_checkbox value="true"/>
|
||||
Name
|
||||
</th>
|
||||
<th>Message</th>
|
||||
<th>Uploaded By</th>
|
||||
<th>Date</th>
|
||||
|
||||
@@ -1,5 +1,48 @@
|
||||
<%namespace file="/common/template_common.mako" import="render_template_field" />
|
||||
|
||||
<%def name="common_javascripts()">
|
||||
<script type="text/javascript">
|
||||
function checkAllFields()
|
||||
{
|
||||
var chkAll = document.getElementById('checkAll');
|
||||
var checks = document.getElementsByTagName('input');
|
||||
var boxLength = checks.length;
|
||||
var allChecked = false;
|
||||
var totalChecked = 0;
|
||||
if ( chkAll.checked == true )
|
||||
{
|
||||
for ( i=0; i < boxLength; i++ )
|
||||
{
|
||||
if ( checks[i].name.indexOf( 'ldda_ids' ) != -1)
|
||||
{
|
||||
checks[i].checked = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( i=0; i < boxLength; i++ )
|
||||
{
|
||||
if ( checks[i].name.indexOf( 'ldda_ids' ) != -1)
|
||||
{
|
||||
checks[i].checked = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function checkForm() {
|
||||
if ( $("select#action_on_datasets_select option:selected").text() == "delete" ) {
|
||||
if ( confirm( "Click OK to delete these datasets?" ) ) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
</%def>
|
||||
|
||||
<%def name="render_upload_form( cntrller, upload_option, action, library_id, folder_id, replace_dataset, file_formats, dbkeys, space_to_tab, link_data_only, widgets, roles_select_list, history, show_deleted )">
|
||||
<%
|
||||
import os, os.path
|
||||
@@ -319,26 +362,34 @@
|
||||
%endif
|
||||
</%def>
|
||||
|
||||
<%def name="render_actions_on_multiple_items()">
|
||||
<%def name="render_actions_on_multiple_items( actions_to_exclude=[] )">
|
||||
<%
|
||||
is_admin = trans.user_is_admin() and cntrller=='library_admin'
|
||||
can_delete = 'delete' not in actions_to_exclude and is_admin
|
||||
can_download = 'download' not in actions_to_exclude
|
||||
can_import_to_histories = 'import_to_histories' not in actions_to_exclude
|
||||
can_manage_permissions = 'manage_permissions' not in actions_to_exclude
|
||||
%>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="5" style="padding-left: 42px;">
|
||||
For selected items:
|
||||
<select name="do_action" id="action_on_selected_items">
|
||||
%if ( trans.user_is_admin() and cntrller=='library_admin' ):
|
||||
<option value="manage_permissions">Edit permissions</option>
|
||||
<option value="delete">Delete</option>
|
||||
%elif cntrller in ['library', 'library_search']:
|
||||
%if default_action == 'add':
|
||||
<option value="add" selected>Import into your current history</option>
|
||||
%if can_import_to_histories:
|
||||
%if not is_admin and default_action == 'import_to_histories':
|
||||
<option value="import_to_histories" selected>Import selected datasets to histories</option>
|
||||
%else:
|
||||
<option value="add">Import into your current history</option>
|
||||
<option value="import_to_histories">Import selected datasets to histories</option>
|
||||
%endif
|
||||
%if default_action == 'manage_permissions':
|
||||
%endif
|
||||
%if can_manage_permissions:
|
||||
%if not is_admin and default_action == 'manage_permissions':
|
||||
<option value="manage_permissions" selected>Edit permissions</option>
|
||||
# This condition should not contain an else clause because the user is not authorized
|
||||
# to manage dataset permissions unless the default action is 'manage_permissions'
|
||||
%else:
|
||||
<option value="manage_permissions">Edit permissions</option>
|
||||
%endif
|
||||
%endif
|
||||
%if can_download:
|
||||
%if 'gz' in comptypes:
|
||||
<option value="tgz"
|
||||
%if default_action == 'download':
|
||||
@@ -361,6 +412,9 @@
|
||||
>Download as a .zip file</option>
|
||||
%endif
|
||||
%endif
|
||||
%if can_delete:
|
||||
<option value="delete">Delete</option>
|
||||
%endif
|
||||
</select>
|
||||
<input type="submit" class="primary-button" name="action_on_datasets_button" id="action_on_datasets_button" value="Go"/>
|
||||
</td>
|
||||
|
||||
@@ -0,0 +1,101 @@
|
||||
<%namespace file="/message.mako" import="render_msg" />
|
||||
<%inherit file="/base.mako"/>
|
||||
<%namespace file="/message.mako" import="javascripts" />
|
||||
<%def name="title()">Import library datasets to histories</%def>
|
||||
|
||||
<%def name="javascripts()">
|
||||
|
||||
${parent.javascripts()}
|
||||
${h.js( "jquery", "galaxy.base" )}
|
||||
<script type="text/javascript">
|
||||
$(function() {
|
||||
$("#select-multiple").click(function() {
|
||||
$("#single-dest-select").val("");
|
||||
$("#single-destination").hide();
|
||||
$("#multiple-destination").show();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
</%def>
|
||||
|
||||
%if message:
|
||||
${render_msg( message, status )}
|
||||
%endif
|
||||
|
||||
<p>
|
||||
<div class="infomessage">Import library datasets into histories.</div>
|
||||
<div style="clear: both"></div>
|
||||
</p>
|
||||
<p>
|
||||
<form method="post">
|
||||
<div class="toolForm" style="float: left; width: 45%; padding: 0px;">
|
||||
<div class="toolFormBody">
|
||||
<input type="hidden" name="cntrller" value="${cntrller}"/>
|
||||
%if source_lddas:
|
||||
%for source_ldda in source_lddas:
|
||||
<%
|
||||
checked = ""
|
||||
encoded_id = trans.security.encode_id( source_ldda.id )
|
||||
if source_ldda.id in ldda_ids:
|
||||
checked = " checked='checked'"
|
||||
%>
|
||||
<div class="form-row">
|
||||
<input type="checkbox" name="ldda_ids" id="dataset_${encoded_id}" value="${encoded_id}" ${checked}/>
|
||||
<label for="dataset_${encoded_id}" style="display: inline;font-weight:normal;">${source_ldda.name}</label>
|
||||
</div>
|
||||
%endfor
|
||||
%else:
|
||||
<div class="form-row">This folder has no accessible library datasets.</div>
|
||||
%endif
|
||||
</div>
|
||||
</div>
|
||||
<div style="float: left; padding-left: 10px; font-size: 36px;">→</div>
|
||||
<div class="toolForm" style="float: right; width: 45%; padding: 0px;">
|
||||
<div class="toolFormTitle">Destination Histories:</div>
|
||||
<div class="toolFormBody">
|
||||
<div class="form-row" id="single-destination">
|
||||
<select id="single-dest-select" name="target_history_ids">
|
||||
<option value=""></option>
|
||||
%for i, target_history in enumerate( target_histories ):
|
||||
<% encoded_id = trans.security.encode_id( target_history.id ) %>
|
||||
<option value="${encoded_id}">${i + 1}: ${h.truncate( target_history.name, 30 )}</option>
|
||||
%endfor
|
||||
</select>
|
||||
<br/><br/>
|
||||
<a style="margin-left: 10px;" href="javascript:void(0);" id="select-multiple">Choose multiple histories</a>
|
||||
</div>
|
||||
<div id="multiple-destination" style="display: none;">
|
||||
%for i, target_history in enumerate( target_histories ):
|
||||
<%
|
||||
cur_history_text = ""
|
||||
encoded_id = trans.security.encode_id( target_history.id )
|
||||
%>
|
||||
<div class="form-row">
|
||||
<input type="checkbox" name="target_history_ids" id="target_history_${encoded_id}" value="${encoded_id}"/>
|
||||
<label for="target_history_${encoded_id}" style="display: inline; font-weight:normal;">${i + 1}: ${target_history.name}${cur_history_text}</label>
|
||||
</div>
|
||||
%endfor
|
||||
</div>
|
||||
%if trans.get_user():
|
||||
<%
|
||||
checked = ""
|
||||
if "create_new_history" in target_history_ids:
|
||||
checked = " checked='checked'"
|
||||
%>
|
||||
<hr />
|
||||
<div style="text-align: center; color: #888;">— OR —</div>
|
||||
<div class="form-row">
|
||||
<label for="new_history_name" style="display: inline; font-weight:normal;">New history named:</label>
|
||||
<input type="textbox" name="new_history_name" />
|
||||
</div>
|
||||
%endif
|
||||
</div>
|
||||
</div>
|
||||
<div style="clear: both"></div>
|
||||
<div class="form-row" align="center">
|
||||
<input type="submit" class="primary-button" name="import_datasets_to_histories_button" value="Import library datasets"/>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</p>
|
||||
@@ -66,7 +66,7 @@
|
||||
<a class="action-button" href="${h.url_for( controller='library_common', action='upload_library_dataset', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), folder_id=trans.security.encode_id( ldda.library_dataset.folder.id ), replace_id=trans.security.encode_id( ldda.library_dataset.id ) )}">Upload a new version of this dataset</a>
|
||||
%endif
|
||||
%if cntrller=='library' and ldda.has_data():
|
||||
<a class="action-button" href="${h.url_for( controller='library_common', action='act_on_multiple_datasets', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), ldda_ids=trans.security.encode_id( ldda.id ), do_action='import_to_history', use_panels=use_panels, show_deleted=show_deleted )}">Import this dataset into your current history</a>
|
||||
<a class="action-button" href="${h.url_for( controller='library_common', action='import_datasets_to_histories', cntrller=cntrller, library_id=trans.security.encode_id( library.id ), ldda_ids=trans.security.encode_id( ldda.id ), use_panels=use_panels, show_deleted=show_deleted )}">Select histories to import this dataset</a>
|
||||
<a class="action-button" href="${h.url_for( controller='library_common', action='download_dataset_from_folder', cntrller=cntrller, id=trans.security.encode_id( ldda.id ), library_id=trans.security.encode_id( library.id ), use_panels=use_panels, show_deleted=show_deleted )}">Download this dataset</a>
|
||||
%endif
|
||||
%if show_associated_hdas_and_lddas:
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
<%namespace file="/message.mako" import="render_msg" />
|
||||
<%namespace file="/library/common/browse_library.mako" import="render_dataset" />
|
||||
<%namespace file="/library/common/common.mako" import="render_actions_on_multiple_items" />
|
||||
<%namespace file="/library/common/common.mako" import="common_javascripts" />
|
||||
|
||||
<%!
|
||||
def inherit(context):
|
||||
@@ -44,6 +46,7 @@
|
||||
<%def name="javascripts()">
|
||||
${parent.javascripts()}
|
||||
${h.js("class", "jquery.jstore")}
|
||||
${common_javascripts()}
|
||||
</%def>
|
||||
|
||||
<%def name="render_searched_components()">
|
||||
@@ -52,7 +55,6 @@
|
||||
<li>info</li>
|
||||
<li>dbkey (genome build)</li>
|
||||
<li>message</li>
|
||||
<li>state</li>
|
||||
%if trans.app.config.enable_lucene_library_search:
|
||||
<li>disk file content</li>
|
||||
%endif
|
||||
@@ -91,34 +93,69 @@
|
||||
%if lddas:
|
||||
<p>The string "${search_term}" was found in at least one of the following information components of the displayed library datasets.</p>
|
||||
${render_searched_components()}
|
||||
<table cellspacing="0" cellpadding="0" border="0" width="100%" class="grid" id="library-grid">
|
||||
<thead>
|
||||
<tr class="libraryTitle">
|
||||
<th>Name</th>
|
||||
<th>Message</th>
|
||||
<th>Uploaded By</th>
|
||||
<th>Date</th>
|
||||
<th>File Size</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<%
|
||||
tracked_datasets = {}
|
||||
row_counter = RowCounter()
|
||||
my_row = row_counter.count
|
||||
%>
|
||||
%for ldda in lddas:
|
||||
<%
|
||||
library_dataset = ldda.library_dataset
|
||||
folder = library_dataset.folder
|
||||
library = folder.parent_library
|
||||
%>
|
||||
${render_dataset( cntrller, ldda, library_dataset, False, library, folder, 0, my_row, row_counter, tracked_datasets, show_deleted=False, render_checkboxes=False )}
|
||||
<form name="act_on_multiple_datasets" action="${h.url_for( controller='library_common', action='act_on_multiple_datasets', cntrller=cntrller, use_panels=use_panels, show_deleted=show_deleted )}" onSubmit="javascript:return checkForm();" method="post">
|
||||
<table cellspacing="0" cellpadding="0" border="0" width="100%" class="grid" id="library-grid">
|
||||
<thead>
|
||||
<tr class="libraryTitle">
|
||||
<th>
|
||||
<input type="checkbox" id="checkAll" name=select_all_datasets_checkbox value="true" onclick='checkAllFields(1);'/><input type="hidden" name=select_all_datasets_checkbox value="true"/>
|
||||
Name
|
||||
</th>
|
||||
<th>Message</th>
|
||||
<th>Uploaded By</th>
|
||||
<th>Date</th>
|
||||
<th>File Size</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<%
|
||||
tracked_datasets = {}
|
||||
row_counter = RowCounter()
|
||||
my_row = row_counter.count
|
||||
row_counter.increment()
|
||||
%>
|
||||
%endfor
|
||||
</table>
|
||||
%for ldda in lddas:
|
||||
<%
|
||||
library_dataset = ldda.library_dataset
|
||||
folder = library_dataset.folder
|
||||
library = folder.parent_library
|
||||
%>
|
||||
${render_dataset( cntrller, ldda, library_dataset, False, library, folder, 0, my_row, row_counter, tracked_datasets, show_deleted=False )}
|
||||
<%
|
||||
my_row = row_counter.count
|
||||
row_counter.increment()
|
||||
%>
|
||||
%endfor
|
||||
${render_actions_on_multiple_items( actions_to_exclude=[ 'manage_permissions' ] )}
|
||||
</table>
|
||||
</form>
|
||||
## Help about compression types
|
||||
|
||||
<div class="libraryItemBody">
|
||||
<p class="infomark">
|
||||
TIP: You can download individual library files by selecting "Download this dataset" from the context menu (triangle) next to the dataset's name.
|
||||
</p>
|
||||
</div>
|
||||
%if len( comptypes ) > 1:
|
||||
<div class="libraryItemBody">
|
||||
<p class="infomark">
|
||||
TIP: Multiple compression options are available for downloading library datasets:
|
||||
</p>
|
||||
<ul style="padding-left: 1em; list-style-type: disc;">
|
||||
%if 'gz' in comptypes:
|
||||
<li>gzip: Recommended for fast network connections
|
||||
%if trans.app.config.upstream_gzip:
|
||||
NOTE: The file you receive will be an uncompressed .tar file - this is because the Galaxy server compresses it and your browser decompresses it on the fly.
|
||||
%endif
|
||||
</li>
|
||||
%endif
|
||||
%if 'bz2' in comptypes:
|
||||
<li>bzip2: Recommended for slower network connections (smaller size but takes longer to compress)</li>
|
||||
%endif
|
||||
%if 'zip' in comptypes:
|
||||
<li>zip: Not recommended but is provided as an option for those who cannot open the above formats</li>
|
||||
%endif
|
||||
</ul>
|
||||
</div>
|
||||
%endif
|
||||
%elif status != 'error':
|
||||
<p>The string "${search_term}" was not found in any of the following information components for any library datasets that you can access.</p>
|
||||
${render_searched_components()}
|
||||
|
||||
@@ -2106,6 +2106,13 @@ class TwillTestCase( unittest.TestCase ):
|
||||
% ( self.url, cntrller, library_id, ldda_ids, do_action ) )
|
||||
for check_str in strings_displayed:
|
||||
self.check_page_for_string( check_str )
|
||||
def import_datasets_to_histories( self, cntrller, library_id, ldda_ids='', new_history_name='Unnamed history', strings_displayed=[] ):
|
||||
# Can't use the ~/library_admin/libraries form as twill barfs on it so we'll simulate the form submission
|
||||
# by going directly to the form action
|
||||
self.visit_url( '%s/library_common/import_datasets_to_histories?cntrller=%s&library_id=%s&ldda_ids=%s&new_history_name=%s&import_datasets_to_histories_button=Import+library+datasets' \
|
||||
% ( self.url, cntrller, library_id, ldda_ids, new_history_name ) )
|
||||
for check_str in strings_displayed:
|
||||
self.check_page_for_string( check_str )
|
||||
def download_archive_of_library_files( self, cntrller, library_id, ldda_ids, format ):
|
||||
self.home()
|
||||
# Here it would be ideal to have twill set form values and submit the form, but
|
||||
|
||||
@@ -296,11 +296,11 @@ class TestLibrarySecurity( TwillTestCase ):
|
||||
strings_displayed=[ '2.bed',
|
||||
'This is the latest version of this library dataset',
|
||||
'Edit attributes of 2.bed' ] )
|
||||
self.act_on_multiple_datasets( 'library',
|
||||
self.security.encode_id( library1.id ),
|
||||
'import_to_history',
|
||||
ldda_ids=self.security.encode_id( ldda2.id ),
|
||||
strings_displayed=[ '1 dataset(s) have been imported into your history' ] )
|
||||
self.import_datasets_to_histories( cntrller='library',
|
||||
library_id=self.security.encode_id( library1.id ),
|
||||
ldda_ids=self.security.encode_id( ldda2.id ),
|
||||
new_history_name='goodbye',
|
||||
strings_displayed=[ '1 dataset have been imported into 1 history' ] )
|
||||
self.logout()
|
||||
# regular_user2 should not be able to see ldda2
|
||||
self.login( email=regular_user2.email )
|
||||
@@ -382,10 +382,10 @@ class TestLibrarySecurity( TwillTestCase ):
|
||||
def check_edit_page( lddas, strings_displayed=[], strings_not_displayed=[] ):
|
||||
for ldda in lddas:
|
||||
# Import each library dataset into our history
|
||||
self.act_on_multiple_datasets( 'library',
|
||||
self.security.encode_id( library1.id ),
|
||||
'import_to_history',
|
||||
ldda_ids=self.security.encode_id( ldda.id ) )
|
||||
self.import_datasets_to_histories( cntrller='library',
|
||||
library_id=self.security.encode_id( library1.id ),
|
||||
ldda_ids=self.security.encode_id( ldda.id ),
|
||||
new_history_name='hello' )
|
||||
# Determine the new HistoryDatasetAssociation id created when the library dataset was imported into our history
|
||||
last_hda_created = get_latest_hda()
|
||||
self.edit_hda_attribute_info( str( last_hda_created.id ),
|
||||
@@ -393,8 +393,8 @@ class TestLibrarySecurity( TwillTestCase ):
|
||||
# admin_user is associated with role1, so should have all permissions on imported datasets
|
||||
check_edit_page( latest_3_lddas,
|
||||
strings_displayed=[ 'Manage dataset permissions on',
|
||||
'can manage the roles associated with permissions on this dataset',
|
||||
'can import this dataset into their history for analysis' ] )
|
||||
'can manage the roles associated with permissions on this dataset',
|
||||
'can import this dataset into their history for analysis' ] )
|
||||
self.logout()
|
||||
# regular_user1 is associated with role1, so should have all permissions on imported datasets
|
||||
self.login( email=regular_user1.email )
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<tool name="Access Libraries" id="library_access1">
|
||||
<description>stored locally</description>
|
||||
<inputs action="/library/index" method="get" target="_parent">
|
||||
<param name="default_action" type="hidden" value="add" />
|
||||
<param name="default_action" type="hidden" value="import_to_histories" />
|
||||
</inputs>
|
||||
<uihints minwidth="800"/>
|
||||
</tool>
|
||||
|
||||
@@ -337,18 +337,17 @@ use_interactive = True
|
||||
#transfer_manager_port = 8163
|
||||
|
||||
# Search data libraries with whoosh
|
||||
enable_whoosh_library_search = True
|
||||
#enable_whoosh_library_search = True
|
||||
# Whoosh indexes are stored in this directory.
|
||||
whoosh_index_dir = database/whoosh_indexes
|
||||
#whoosh_index_dir = database/whoosh_indexes
|
||||
|
||||
# Search data libraries with lucene
|
||||
#enable_lucene_library_search = False
|
||||
# maxiumum file size to index for searching, in MB
|
||||
#fulltext_max_size = 500
|
||||
#fulltext_noindex_filetypes=bam,sam,wig,bigwig,fasta,fastq,fastqsolexa,fastqillumina,fastqsanger
|
||||
# base URL of server providing search functionality using whoosh.
|
||||
#fulltext_index_url = http://localhost:8081/index
|
||||
#fulltext_find_url = http://localhost:8081/find
|
||||
# base URL of server providing search functionality using lucene
|
||||
#fulltext_url = http://localhost:8081
|
||||
|
||||
# -- Users and Security
|
||||
|
||||
|
||||
Reference in New Issue
Block a user